来自 NAudio 的原始音频
Raw Audio from NAudio
我想通过 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 header 添加到内存流,然后以 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");
确保将正确的 waveformat 参数传递给 FFMpeg。您将检查 FFmpeg documentation 以了解详细信息。 WASAPI 捕获将是立体声 IEEE 浮点数(32 位),可能是 44.1kHz 或 48kHz。你也应该使用 e.BytesRecorded
而不是 e.Buffer.Length
.
FFmpeg 原始 PCM 音频解复用器需要提供适当数量的通道(-channels
,默认值为 1)和采样率(-sample_rate
,默认值为 44100)。
选项的顺序很重要:紧接在输入之前的选项应用到输入,紧接在输出之前的选项应用到输出。
ffmpeg
cli 示例:
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");
使用 WasapiLoopbackCapture
,这是对我有用的完整命令,没有失真或减速:
string command = $"-f f32le -channels {wasapiLoopbackCapture.WaveFormat.Channels} -sample_rate {wasapiLoopbackCapture.WaveFormat.SampleRate} -i {pipePrefix}{pipeName} ffmpegtest.wav";
我想通过 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 header 添加到内存流,然后以 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");
确保将正确的 waveformat 参数传递给 FFMpeg。您将检查 FFmpeg documentation 以了解详细信息。 WASAPI 捕获将是立体声 IEEE 浮点数(32 位),可能是 44.1kHz 或 48kHz。你也应该使用 e.BytesRecorded
而不是 e.Buffer.Length
.
FFmpeg 原始 PCM 音频解复用器需要提供适当数量的通道(-channels
,默认值为 1)和采样率(-sample_rate
,默认值为 44100)。
选项的顺序很重要:紧接在输入之前的选项应用到输入,紧接在输出之前的选项应用到输出。
ffmpeg
cli 示例:
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");
使用 WasapiLoopbackCapture
,这是对我有用的完整命令,没有失真或减速:
string command = $"-f f32le -channels {wasapiLoopbackCapture.WaveFormat.Channels} -sample_rate {wasapiLoopbackCapture.WaveFormat.SampleRate} -i {pipePrefix}{pipeName} ffmpegtest.wav";