【问题标题】:Raw Audio from NAudio来自 NAudio 的原始音频
【发布时间】:2017-07-08 19:52:53
【问题描述】:

我想通过 NAudio 记录来自 WASAPI 环回的原始音频,并通过管道传输到 FFmpeg 以通过内存流进行流式传输。从document 开始,FFmpeg 可以将输入作为 Raw 但是,我的结果速度为 8~10 倍! 这是我的代码:

waveInput = new WasapiLoopbackCapture();
waveInput.DataAvailable += new EventHandler<WaveInEventArgs>((object sender, WaveInEventArgs e) => 
{
    lock (e.Buffer)
    {
        if (waveInput == null)
            return;
        try
        {
            using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream())
            {
                memoryStream.Write(e.Buffer, 0, e.Buffer.Length);
                memoryStream.WriteTo(ffmpeg.StandardInput.BaseStream);
            }
        }
        catch (Exception)
        {
            throw;
        }
    }
});
waveInput.StartRecording();

FFmpeg 参数:

ffmpegProcess.StartInfo.Arguments = String.Format("-f s16le -i pipe:0 -y output.wav");

1。有人可以解释一下这种情况并给我一个解决方案吗?
2. 我是否应该将 Wav 标头添加到 Memory Stream 中,然后以 Wav 格式通过管道传输到 FFmpeg?

可行的解决方案

waveInput = new WasapiLoopbackCapture();
waveInput.DataAvailable += new EventHandler<WaveInEventArgs>((object sender, WaveInEventArgs e) => 
{
    lock (e.Buffer)
    {
        if (waveInput == null)
            return;
        try
        {
            using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream())
            {
                memoryStream.Write(e.Buffer, 0, e.BytesRecorded);
                memoryStream.WriteTo(ffmpeg.StandardInput.BaseStream);
            }
        }
        catch (Exception)
        {
            throw;
        }
    }
});
waveInput.StartRecording();

FFMpeg 参数:

ffmpegProcess.StartInfo.Arguments = string.Format("-f f32le -ac 2 -ar 44.1k -i pipe:0 -c:a copy -y output.wav");

【问题讨论】:

    标签: c# ffmpeg naudio


    【解决方案1】:

    确保将正确的波形参数传递给 FFMpeg。详情请查看FFmpeg documentation。 WASAPI 捕获将是立体声 IEEE 浮点(32 位),可能是 44.1kHz 或 48kHz。你也应该使用e.BytesRecorded 而不是e.Buffer.Length

    【讨论】:

    • 我用过这个-f s32le -i pipe:0 -ar 44100 -ac 2 -sample_fmt s32 -c:a copy -y output.wav。但速度提高了 2 倍。 FFMpeg 说:输入流#0.0 的猜测通道布局:单声道。流 #0:0:音频:pcm_s32le,44100 Hz,单声道,s32,1411 kb/s
    • 我将上面的内容更改为:-f s32le -ac 2 -ar 44100 -i pipe:0 -sample_fmt s32 -c:a copy -y output.wav,得到的结果是:立体声和速度在前 4 分钟内从 3x 降低到 1x,并且不断地向前 1x。它在整个音频中带来了干扰和噪音,但我可以识别声音。我该怎么做才能解决这个问题?你的信息对我帮助很大。谢谢。
    • 我不认为 s32 是正确的。您想指定浮点数(不确定标志是什么)。无法解释我正在降低的速度增加 - 这很奇怪
    • 虽然我已经尝试了所有格式,但 s32le 是最接近的一种。但是我错了,正确的格式是f32le。生成的音频在前 2.3 分钟内稍微快了一点,很难注意到有什么不同。我从昨天开始就卡在这里了。你救了我的命,马克。你太棒了!
    • 我参加聚会迟到了,但是将您的示例格式更改为 48000 可以正常记录速度。
    【解决方案2】:

    FFmpeg 原始 PCM 音频解复用器需要提供适当数量的通道(-channels,默认值为 1)和采样率(-sample_rate,默认值为 44100)。

    选项的顺序很重要:紧接在输入之前的选项应用于输入,紧接在输出之前的选项应用于输出。

    ffmpegcli 示例:

    ffmpeg -f s32le -channels 2 -sample_rate 44100 -i pipe:0 -c copy output.wav
    

    您的代码示例:

    ffmpegProcess.StartInfo.Arguments = String.Format("-y -f s32le -channels 2 -sample_rate 44100 -i pipe:0 -c copy output.wav");
    

    【讨论】:

    • 我在您回答前大约 30 分钟这样做了,感谢您的帮助。但我的下一个问题是输出音频不清楚。它有很多干扰和噪音。
    【解决方案3】:

    使用WasapiLoopbackCapture,这是对我有用的完整命令,没有失真或减速:

    string command = $"-f f32le -channels {wasapiLoopbackCapture.WaveFormat.Channels} -sample_rate {wasapiLoopbackCapture.WaveFormat.SampleRate} -i {pipePrefix}{pipeName} ffmpegtest.wav";
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-16
      • 1970-01-01
      • 2015-05-01
      • 1970-01-01
      • 2014-11-20
      • 1970-01-01
      • 2013-06-05
      相关资源
      最近更新 更多