C# 使用NAudio合并mp3、wav音频文件
1.什么是wav格式
WAV为 微软公司(Microsoft)开发的一种声音文件格式,它符合RIFF(Resource Interchange File Format)文件规范,用于保存Windows平台的音频信息资源。 通常使用三个参数来表示声音,量化位数,取样频率和采样点振幅。量化位数分为8位,16位,24位三种,声道有单声道和立体声之分,单声道振幅数据为n1矩阵点,立体声为n2矩阵点,取样频率一般有11025Hz(11kHz) ,22050Hz(22kHz)和44100Hz(44kHz) 三种。
标准格式化的WAV文件和CD格式一样,也是44.1K的取样频率,16位量化数字,因此在声音文件质量和CD相差无几。
2. WAV文件的组成
偏移地址 | 大小字节 | 数据块类型 | 内容 |
---|---|---|---|
00H~03H | 4 | 4字符 | 资源交换文件标志(RIFF) |
04H~07H | 4 | 长整数 | 从下个地址开始到文件尾的总字节数 |
08H~0BH | 4 | 4字符 | WAV文件标志(WAVE) |
0CH~0FH | 4 | 4字符 | 波形格式标志(fmt ),最后一位空格。 |
10H~13H | 4 | 整数 | 过滤字节(一般为00000010H),若为00000012H则说明数据头携带附加信息(见“附加信息”)。 |
14H~15H | 2 | 整数 | 格式种类(值为1时,表示数据为线性PCM编码) |
16H~17H | 2 | 整数 | 通道数,单声道为1,双声道为2 |
18H~1BH | 4 | 长整数 | 采样频率 |
1CH~1FH | 4 | 长整数 | 波形数据传输速率(每秒平均字节数) |
20H~21H | 2 | 整数 | DATA数据块长度,字节。 |
22H~23H | 2 | 整数 | PCM位宽 |
随后2字节 | 2 | 整数 | 附加信息(可选,由上方过滤字节确定) |
以上为对wav格式的基本了解,最近碰到一个需要合并音频文件的需求,奈何对此文件了解过少,最后借助于 NAudio
git地址: https://github.com/naudio/NAudio,结合文件流进行处理。
3.话不多说上代码。首先是安装Naudio的包。
3.1.上传音频文件并调用合并方法【伪代码】
public void UploadOrCombineAudioFile()
{
HttpFileCollection files = HttpContext.Current.Request.Files;
if (files == null || files.Count < )
return;
string upfileType = HttpContext.Current.Request.Form["upfileType"];//文件格式类型
/*...省略符...*/
int maxSize = * * ;//单文件上传最大限制
List<string> dirDic = new List<string> { ".mp3", ".mp4", ".pcm", ".wav" };//文件格式限制
string uploadPath = HttpContext.Current.Server.MapPath("~/AudioFile/TempFile/");//临时路径
if (!Directory.Exists(uploadPath))
Directory.CreateDirectory(uploadPath);
string fileType = string.Empty;
for (var i = ; i < files.Count; i++)
{
var postedfile = files[i];
var inputStream = postedfile.InputStream;
if (inputStream.Length > )
{
string thisfileName = files[i].FileName;
fileType = Path.GetExtension(thisfileName);
if (postedfile.InputStream == null
|| postedfile.InputStream.Length > maxSize
|| !dirDic.Contains(fileType.ToLower())){
return;
}
/*...我是省略符...*/
int ReadLen = ;
string uploadFileName = uploadPath + thisfileName;
byte[] bytes = new byte[];
using (FileStream stream = new FileStream(
uploadFileName, FileMode.OpenOrCreate))//保存文件到指定待合并文件路径下
{
while ((ReadLen = inputStream.Read(bytes, , bytes.Length)) > )
{
stream.Write(bytes, , ReadLen);
}
}
}
}
List<string> filepaths = new List<string>(Directory.GetFiles(uploadPath));//获取待合并文件路径
//文件合并后路径
string savePath = HttpContext.Current.Server.MapPath("~/AudioFile/ComBineFile/" + DateTime.Now.ToString("yyyyMMdd") + "/");
if (!Directory.Exists(savePath)){
Directory.CreateDirectory(savePath);
}
/*...我是省略符...*/
byte[] buffer = new byte[];
string savefullName = savePath + DateTime.Now.ToString("yyyyMMddHHmmssff") + upfileType;
if (upfileType.ToLower().Equals(".mp3"))
CombineMp3(filepaths, savefullName);//mp3合并
else if ((upfileType.ToLower().Equals(".wav")))
CombineWav(filepaths, savefullName);//wav合并
/*...我是省略符...*/
return;
}
3.2 .mp3格式合并
//命名空间
using System.IO;
using NAudio;
using NAudio.Wave;
/// <summary>
/// Mp3格式合并
/// </summary>
/// <param name="inputFiles">待合并文件路径</param>
/// <param name="outputfullName">输出文件名</param>
private void CombineMp3(List<string> inputFiles, string outputfullName)
{
using (FileStream outputStream = new FileStream(outputfullName, FileMode.OpenOrCreate))
{
foreach (string file in inputFiles)
{
Mp3FileReader reader = new Mp3FileReader(file);
if ((outputStream.Position == ) && (reader.Id3v2Tag != null))
{
outputStream.Write(reader.Id3v2Tag.RawData, , reader.Id3v2Tag.RawData.Length);
}
Mp3Frame frame;
while ((frame = reader.ReadNextFrame()) != null)
{
outputStream.Write(frame.RawData, , frame.RawData.Length);
}
}
}
}
3.3.wav格式合并
/// <summary>
/// wav格式合并
/// </summary>
/// <param name="inputFiles">待合并文件</param>
/// <param name="outputfullName">输出文件名</param>
private void CombineWav(List<string> inputFiles, string outputfullName)
{
WaveStream waveStream = WaveFormatConversionStream.CreatePcmStream(new WaveFileReader(inputFiles[]));
using (WaveFileWriter waveFileWriter = new WaveFileWriter(outputfullName, waveStream.WaveFormat))
{
foreach (string file in inputFiles)
{
waveStream = WaveFormatConversionStream.CreatePcmStream(new WaveFileReader(file));
byte[] bytes = new byte[waveStream.Length];
waveStream.Position = ;
waveStream.Read(bytes, , (int)waveStream.Length);
waveFileWriter.Write(bytes, , bytes.Length);
}
}
}
本文由 创作,采用 知识共享署名4.0 国际许可协议进行许可。本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。最后编辑时间为: 2021/05/11 11:26