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 的一个实例,让它自己处理工作。这不仅会产生更有用的输出,而且您可以为收到的每个数据块设置和拆除编码器,从而省去很多低效的麻烦。