赞
踩
使用delegate委托:音频加载完成进行回调
namespace Epitome
{
public delegate void AudioClipLoadFinish(AudioClip clip);
public static class AudioLoad
{
public static IEnumerator Load(string url, AudioClipLoadFinish finish)
{
WWW www = new WWW("file://" + url);
yield return www;
finish(www.GetAudioClip());
}
}
}
使用案列:
public AudioSource accompany;
private void Start()
{
// 加载音频
StartCoroutine(AudioLoad.Load("filepath", AudioClipLoadFinish));
}
public void AudioClipLoadFinish(AudioClip clip)
{
accompany.clip = clip;
accompany.Paly();
}
NAudio是Mark Heath编写的开源.NET音频库
GitHub:NAudio项目
NAudio是个相对成熟、开源的C#音频开发工具,它包含录音、播放录音、格式转换、混音调整等功能。
namespace Epitome { public static class AudioConverter { /// <summary> /// MP3文件转WAV文件 /// </summary> /// <param name="filePath">MP3文件读取路径</param> /// <param name="savePath">WAV文件保存路径</param> public static void MP3TurnWAV(string filePath, string savePath) { using (FileStream stream = File.Open(filePath, FileMode.Open)) { Mp3FileReader reader = new Mp3FileReader(stream); WaveFileWriter.CreateWaveFile(savePath, reader); } } public static void MP3TurnWAV(string filePath, string savePath, List<string> fileNames) { List<string> strs = Project.DirectoryAllFileNames(filePath, new List<string>() { "mp3" }); if (strs != null) { string targetFilePath, saveFilePath; for (int j = 0; j < strs.Count; j++) { targetFilePath = filePath + "/" + strs[j]; saveFilePath = savePath + "/" + strs[j].Substring(0, strs[j].Length - 3) + "wav"; MP3TurnWAV(targetFilePath, saveFilePath); } #if UNITY_EDITOR AssetDatabase.Refresh(); #endif } } } }
使用案列:
EditorExtension.GetSelectionPath:获取编辑器选择的目标路径,获取该路径下的MP3音频文件
通过拼接音频文件路径,调用MP3TurnWAV生成WAV音频文件
/// <summary> /// MP3文件转WAV文件 /// </summary> [MenuItem("Epitome/Audio/MP3TurnWAV")] [MenuItem("Assets/Epitome/Audio/MP3TurnWAV")] private static void MP3TurnWAV() { List<string> paths = EditorExtension.GetSelectionPath(); for (int i = 0; i < paths.Count; i++) { if (Directory.Exists(paths[i])) { string rootPath = ProjectPath.GetDataPath.Substring(0, ProjectPath.GetDataPath.Length - 6); DirectoryInfo info = new DirectoryInfo(rootPath + paths[i]); string savePath = info.FullName + "_WAV"; Project.CreateDirectory(savePath); List<string> strs = Project.DirectoryAllFileNames(info.FullName, new List<string>() { "mp3" }); AudioConverter.MP3TurnWAV(info.FullName, savePath, strs); } } }
/// <summary> /// 剪切空白部分 /// </summary> public static AudioClip CutBlankSection(AudioClip audioClip, int time, int samplingRate) { float[] samples_one = new float[audioClip.samples]; audioClip.GetData(samples_one, 0); float[] samples_two = new float[time * samplingRate]; Array.Copy(samples_one, 0, samples_two, 0, time * samplingRate); AudioClip newAudioClip = AudioClip.Create(audioClip.name, samplingRate * time, 1, samplingRate, false); newAudioClip.SetData(samples_two, 0); return newAudioClip; } audioLength//秒单位 frequency = 44100; AudioClip audioClip = AudioClips.CutBlankSection(recording.clip, audioLength, frequency);
/// <summary> /// 修剪Wav文件 /// </summary> /// <param name="filePath">修剪文件路径</param> /// <param name="savePath">保存文件路径</param> /// <param name="cutFromStart">开始间隔</param> /// <param name="cutFromEnd">结束间隔</param> public static void TrimWavFile(string filePath, string savePath, TimeSpan cutFromStart, TimeSpan cutFromEnd) { using (WaveFileReader reader = new WaveFileReader(filePath)) { using (WaveFileWriter writer = new WaveFileWriter(savePath, reader.WaveFormat)) { int bytesPerMillisecond = reader.WaveFormat.AverageBytesPerSecond / 1000; int startPos = (int)cutFromStart.TotalMilliseconds * bytesPerMillisecond; startPos = startPos - startPos % reader.WaveFormat.BlockAlign; int endBytes = (int)cutFromEnd.TotalMilliseconds * bytesPerMillisecond; endBytes = endBytes - endBytes % reader.WaveFormat.BlockAlign; int endPos = (int)reader.Length - endBytes; TrimWavFile(reader, writer, startPos, endPos); } } } /// <summary> /// 修剪Wav文件 /// </summary> private static void TrimWavFile(WaveFileReader reader, WaveFileWriter writer, int startPos, int endPos) { reader.Position = startPos; byte[] buffer = new byte[1024]; while (reader.Position < endPos) { int bytesRequired = (int)(endPos - reader.Position); if (bytesRequired > 0) { int bytesToRead = Math.Min(bytesRequired, buffer.Length); int bytesRead = reader.Read(buffer, 0, bytesToRead); if (bytesRead > 0) { writer.Write(buffer, 0, bytesRead); } } } }
namespace Epitome { public static class AudioMixer { /// <summary> /// 音频混合(混音) /// </summary> /// <param name="filePath1">音频文件路径</param> /// <param name="filePath2">音频文件路径</param> /// <param name="mixedPath">混合音频文件路径</param> public static void AudioMixing(string filePath1, string filePath2,string mixedPath) { using (var reader1 = new AudioFileReader(filePath1)) using (var reader2 = new AudioFileReader(filePath2)) { var mixer = new MixingSampleProvider(new[] { reader1, reader2 }); WaveFileWriter.CreateWaveFile16(mixedPath, mixer); } } } }
使用案列:
// 伴奏混合原声
AudioMixer.AudioMixing(accompanyClipPath, originalPath, finalPath);
/// <summary> /// 合并音频 /// </summary> public static AudioClip MergeAudio(int interval, params AudioClip[] clips) { if (clips == null || clips.Length == 0) return null; int channels = clips[0].channels; int frequency = clips[0].frequency; using (MemoryStream memoryStream = new MemoryStream()) { for (int i = 0; i < clips.Length; i++) { if (clips[i] == null) continue; clips[i].LoadAudioData(); var buffer = clips[i].GetData(); memoryStream.Write(buffer, 0, buffer.Length); if (clips.Length - 1 == i) continue; byte[] byteClips = new byte[clips[i].frequency * clips[i].channels * 4 * interval];//合并音频间的间隔 memoryStream.Write(byteClips, 0, byteClips.Length); } var bytes = memoryStream.ToArray(); var result = AudioClip.Create("Merge", bytes.Length / 4 / channels, channels, 44100, false); result.SetData(bytes); return result; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。