GitHub项目:Epitome.Audio音频模块

WWW类外部加载音乐文件

使用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介绍

NAudio是Mark Heath编写的开源.NET音频库
GitHub:NAudio项目
NAudio是个相对成熟、开源的C#音频开发工具,它包含录音、播放录音、格式转换、混音调整等功能。

基于NAudio音频文件格式转换

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_EDITORAssetDatabase.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);

基于NAudio音频剪切

/// <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);}}}
}

基于NAudio音频混合(混音)

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;}
}

【Audio】Unity音频模块:加载、转换、剪切、混音、合并相关推荐

  1. Unity之动态加载播放外部mp3音频

    准备工作   由于Unity支持的外部加载的音频格式有限(wav.ogg等),因此本文使用支持.Net的NAudio库来完成MP3音频的加载与播放.   NAudio   下载NAudio动态库,然后 ...

  2. OBS视频数据输出流程(模块加载,编码,推流)详细说明

    声明:本文章内容仅代表个人观点,不能保证完全的正确性,仅供参考! 先上个自己画的图,结合流程图和文字解释,理解起来会更快些 1.视频输出初始化程序运行时,初始化OBS,视频相关的初始化是再mainWi ...

  3. nodejs学习巩固笔记-nodejs基础,Node.js 高级编程(核心模块、模块加载机制)

    目录 Nodejs 基础 大前端开发过程中的必备技能 nodejs 的架构 为什么是 Nodejs Nodejs 异步 IO Nodejs 事件驱动架构 全局对象 全局变量之 process 核心模块 ...

  4. OpenCvSharp (C# OpenCV) DNN模块加载自己训练的TensorFlow模型做目标检测(含手势识别、骰子识别、菜品识别)(附源码)

    本文作者Color Space,文章未经作者允许禁止转载! 本文将介绍OpenCVSharp DNN模块加载自己训练的TensorFlow模型做目标检测(含手势识别.骰子识别.菜品识别)! 前言: 下 ...

  5. 大前端 - nodejs 基础(核心模块、模块加载机制)

    node基础 一 nodejs 核心模块.模块加载机制 nodejs异步io和事件循环 nodejs单线程 nodejs实现api服务 nodejs核心模块和api使用 提供应用程序可直接调用库,例如 ...

  6. Node.js(一、Node.js基础、模块加载机制、包等)

    Node.js(一.Node.js基础.模块加载机制.包等) 1.Node.js基础 1.1.Node是什么 1.2.Node环境安装失败解决方法 1.2.1.Node环境搭建 1.2.2.错误代码2 ...

  7. javascript模块化、模块加载器初探

    最常见网站的javascript架构可能是这样的: 一个底层框架文件,如jQuery 一个网站业务框架文件,包含整站公用业务模块类(如弹框.ajax封装等) 多个业务文件,包含每个具体页面有关系的业务 ...

  8. FreeSwitch 的初始化及其模块加载过程

    FS 主函数main() Freeswitch的主函数是在文件switch.c中定义的,该文件的260行是整个程序的入口,主函数主要完成的功能是包括,命令行解析,初始化apr库,构建全局内存池,模块加 ...

  9. javascript 异步模块加载 简易实现

    在javascript是没有类似java或其他语言的模块概念的,因此也不可能通过import或using等关键字来引用模块,这样造成了复杂项目中前端代码混乱,变量互相影响等. 因此在复杂项目中引入AM ...

最新文章

  1. YumRepo Error: All mirror URLs are not using问题解决
  2. linux脚本登录启动失败,linux-从bash脚本启动进程失败
  3. 【tool】将虚拟机从 VMware workstation 转到 vsphere
  4. 人才第一!英伟达大幅扩大深度学习学院(DLI)规模
  5. Shadow Map在DirectX9.0 SDK Sample 的实现方法
  6. linux mesa 教程,Ubuntu 13.04使用Mesa
  7. C# ZPL打印标签
  8. 新版三证合一营业执照组织机构代码是哪9位及统一社会信用代码怎么获取9位全国企业组织机构代码查询入口
  9. 友善mini2440裸机开发原理+源码
  10. 3ds Max Taper、Twist和Bend的运用——衣架的制作
  11. MathType的配置问题;将word中的公式转换为mathtype格式失败,缺少OMML2MML.XSL
  12. Oracle 12C Sharding分片数据库
  13. Android 小贴士播报
  14. 一个软件测试员如何选择mac妙控板或妙控鼠标
  15. 【操作系统----Linux】Linux作为服务器系统安装过程
  16. 火山安卓RSA加解密操作
  17. 谷歌Zxing Utils
  18. 一道很水的题(南工校赛决赛第一题)
  19. php 调用格式工厂,格式工厂能转换kux吗?
  20. 出门问问引入AI,其虚拟个人助理首亮相

热门文章

  1. 《 最新中国高校毕业生薪资报告 》
  2. Linux汇编代码中加打印,汇编语言中调用C函数打印“hello world”
  3. HashMap的实际应用
  4. color demura原理_一种消除液晶屏高温MURA的工艺研究
  5. 晶振(crystal)与谐振荡器(oscillator)
  6. 超市结算系统|Springboot+Vue通用超市结算收银系统
  7. 概率论复习笔记——条件概率、全概率、贝叶斯公式及其应用
  8. kaggle数据集的下载
  9. 最大化使用51的RAM空间
  10. 常见的鼠标事件以及onmouseover与onmousemove的区别