NAudio WasapiLoopbackCapture断断续续的声音
NAudio WasapiLoopbackCapture intermittent sound
第 1 部分
我有一些 NAudio 相关代码
private void InitAudioOut(DateTime dtNow)
{
_pathOut = string.Format(BaseDirectory + @"\({0:HH-mm-ss dd-MM-yyyy} OUT).wav", dtNow);
_waveOut = new WasapiLoopbackCapture();
_waveOut.DataAvailable += WaveOutDataAvailable;
_waveOut.RecordingStopped += WaveOutRecordStopped;
_waveOutFileStream = new WaveFileWriter(_pathOut, _waveOut.WaveFormat);
_waveOut.StartRecording();
}
通过录音过程的初始化,我有以下 WaveOutDataAvailable 方法:
private void WaveOutDataAvailable(object sender, WaveInEventArgs e)
{
var buf= e.Buffer;
_waveOutFileStream.Write(buf, 0, buf.Length);
_waveOutFileStream.Flush();
}
生成的文件中的声音断断续续且缓慢,就像在声音块之间有 "blank" 个部分,任何想法都会受到赞赏。
第 1 部分结束
第 2 部分
此代码还有另一个版本,我试图将 WAV 流转换为 mp3 流,然后将其写入文件,它看起来像这样:
private void InitAudioIn(DateTime dtNow)
{
_pathIn = string.Format(BaseDirectory + @"\({0:HH-mm-ss dd-MM-yyyy} IN).mp3", dtNow);
_waveIn = new WaveInEvent();
_waveIn.WaveFormat = new WaveFormat(44100, 2);
_waveIn.DataAvailable += WaveInDataAvailable;
_waveIn.RecordingStopped += WaveInRecordStopped;
_waveInFileStream = File.Create(_pathIn);
_waveIn.StartRecording();
}
使用WaveInDataAvailable方法如下:
private void WaveInDataAvailable(object sender, WaveInEventArgs e)
{
var wavToMp3Buffer = ConvertWavToMp3(e.Buffer, _waveIn.WaveFormat);
_waveInFileStream.Write(wavToMp3Buffer, 0, wavToMp3Buffer.Length);
_waveInFileStream.Flush();
}
ConvertWavToMp3 方法:
public byte[] ConvertWavToMp3(byte[] wavContent, WaveFormat waveFormat)
{
using (var baseMemoryStream = new MemoryStream())
using (var wavToMp3Writer = new LameMP3FileWriter(baseMemoryStream, waveFormat, 64))
{
wavToMp3Writer.Write(wavContent, 0, wavContent.Length);
wavToMp3Writer.Flush();
return baseMemoryStream.ToArray();
}
}
如果我不尝试将其转换为 MP3,而只是将其写入 WAV 文件,那绝对没问题,但如果我尝试通过 ConvertWavToMp3 方法进行 MP3 转换,那么声音会变得缓慢且断断续续,这是怎么回事这个实现有问题吗?
第一部分,您对缓冲区长度与缓冲区中有效字节数相同的假设无效。尝试:
private void WaveOutDataAvailable(object sender, WaveInEventArgs e)
{
_waveOutFileStream.Write(e.Buffer, 0, e.BytesRecorded);
}
让输出流自动处理刷新。像这样尝试将数据强制写入磁盘要么行不通,要么在某些情况下会导致意外结果,例如可能会干扰数据的部分块写入。在录制结束时刷新,而不是在录制期间刷新。
关于第二部分...
您的代码正在创建一个文件,该文件是一系列 MP3 文件的串联,一个用于传递给您的 WaveInDataAvailable
方法的每个缓冲区,并包括结尾处的所有空白 space那些缓冲区。当然不能正常播放了。
想写MP3就直接写吧。让你的 _waveInFileStream
成为 LameMP3FileWriter
的一个实例,让它自己处理工作。这不仅会产生更有用的输出,而且您可以为收到的每个数据块设置和拆除编码器,从而省去很多低效的麻烦。
第 1 部分
我有一些 NAudio 相关代码
private void InitAudioOut(DateTime dtNow)
{
_pathOut = string.Format(BaseDirectory + @"\({0:HH-mm-ss dd-MM-yyyy} OUT).wav", dtNow);
_waveOut = new WasapiLoopbackCapture();
_waveOut.DataAvailable += WaveOutDataAvailable;
_waveOut.RecordingStopped += WaveOutRecordStopped;
_waveOutFileStream = new WaveFileWriter(_pathOut, _waveOut.WaveFormat);
_waveOut.StartRecording();
}
通过录音过程的初始化,我有以下 WaveOutDataAvailable 方法:
private void WaveOutDataAvailable(object sender, WaveInEventArgs e)
{
var buf= e.Buffer;
_waveOutFileStream.Write(buf, 0, buf.Length);
_waveOutFileStream.Flush();
}
生成的文件中的声音断断续续且缓慢,就像在声音块之间有 "blank" 个部分,任何想法都会受到赞赏。
第 1 部分结束
第 2 部分
此代码还有另一个版本,我试图将 WAV 流转换为 mp3 流,然后将其写入文件,它看起来像这样:
private void InitAudioIn(DateTime dtNow)
{
_pathIn = string.Format(BaseDirectory + @"\({0:HH-mm-ss dd-MM-yyyy} IN).mp3", dtNow);
_waveIn = new WaveInEvent();
_waveIn.WaveFormat = new WaveFormat(44100, 2);
_waveIn.DataAvailable += WaveInDataAvailable;
_waveIn.RecordingStopped += WaveInRecordStopped;
_waveInFileStream = File.Create(_pathIn);
_waveIn.StartRecording();
}
使用WaveInDataAvailable方法如下:
private void WaveInDataAvailable(object sender, WaveInEventArgs e)
{
var wavToMp3Buffer = ConvertWavToMp3(e.Buffer, _waveIn.WaveFormat);
_waveInFileStream.Write(wavToMp3Buffer, 0, wavToMp3Buffer.Length);
_waveInFileStream.Flush();
}
ConvertWavToMp3 方法:
public byte[] ConvertWavToMp3(byte[] wavContent, WaveFormat waveFormat)
{
using (var baseMemoryStream = new MemoryStream())
using (var wavToMp3Writer = new LameMP3FileWriter(baseMemoryStream, waveFormat, 64))
{
wavToMp3Writer.Write(wavContent, 0, wavContent.Length);
wavToMp3Writer.Flush();
return baseMemoryStream.ToArray();
}
}
如果我不尝试将其转换为 MP3,而只是将其写入 WAV 文件,那绝对没问题,但如果我尝试通过 ConvertWavToMp3 方法进行 MP3 转换,那么声音会变得缓慢且断断续续,这是怎么回事这个实现有问题吗?
第一部分,您对缓冲区长度与缓冲区中有效字节数相同的假设无效。尝试:
private void WaveOutDataAvailable(object sender, WaveInEventArgs e)
{
_waveOutFileStream.Write(e.Buffer, 0, e.BytesRecorded);
}
让输出流自动处理刷新。像这样尝试将数据强制写入磁盘要么行不通,要么在某些情况下会导致意外结果,例如可能会干扰数据的部分块写入。在录制结束时刷新,而不是在录制期间刷新。
关于第二部分...
您的代码正在创建一个文件,该文件是一系列 MP3 文件的串联,一个用于传递给您的 WaveInDataAvailable
方法的每个缓冲区,并包括结尾处的所有空白 space那些缓冲区。当然不能正常播放了。
想写MP3就直接写吧。让你的 _waveInFileStream
成为 LameMP3FileWriter
的一个实例,让它自己处理工作。这不仅会产生更有用的输出,而且您可以为收到的每个数据块设置和拆除编码器,从而省去很多低效的麻烦。