C#使用NAudio同时录制扬声器与麦克风音频异常问题求助
问题原因分析
你的代码存在两个核心问题,导致录制出现空白片段且音频内容分割:
- 音频格式不统一:
WasapiCapture(麦克风)和WasapiLoopbackCapture(扬声器)的默认WaveFormat大概率不一致(比如麦克风是单声道、扬声器是立体声,采样率也可能不同),直接将不同格式的音频数据写入同一WAV文件,会破坏文件的帧结构,产生空白。 - 异步数据写入混乱:两个Capture的
DataAvailable事件是独立异步触发的,数据写入顺序完全随机,相当于把两个音频流的帧无规则拼接,随着录制时间增加,帧错位的累积会导致空白时长越来越长。
解决方案
需要先将两个音频流统一为相同格式,再通过混音器合并成单一流后写入文件,确保音频数据的连续性和同步性。
修改后的代码
using NAudio.Wave; using NAudio.Wave.SampleProviders; public class Program { static void Main(string[] args) { string outputFileName = "output.wav"; RecordMixedAudio(outputFileName); } static void RecordMixedAudio(string outputFileName) { // 初始化两个捕获设备 using var micCapture = new WasapiCapture(); using var speakerCapture = new WasapiLoopbackCapture(); // 定义统一的目标格式:立体声、44100Hz、16位 var targetFormat = new WaveFormat(44100, 16, 2); // 将麦克风音频转换为目标格式 var micProvider = new MediaFoundationResampler(micCapture, targetFormat); micProvider.ResamplerQuality = 60; // 设置重采样质量 // 将扬声器音频转换为目标格式 var speakerProvider = new MediaFoundationResampler(speakerCapture, targetFormat); speakerProvider.ResamplerQuality = 60; // 创建混音器,合并两个音频流 var mixer = new MixingSampleProvider(targetFormat); mixer.AddMixerInput(micProvider.ToSampleProvider()); mixer.AddMixerInput(speakerProvider.ToSampleProvider()); // 将混音后的采样转换回WaveProvider,用于写入文件 var mixedWaveProvider = mixer.ToWaveProvider16(); // 初始化文件写入器 using var writer = new WaveFileWriter(outputFileName, targetFormat); // 注册数据可用事件,写入混音后的数据 mixedWaveProvider.DataAvailable += (s, e) => { writer.Write(e.Buffer, 0, e.BytesRecorded); }; // 开始录制 micCapture.StartRecording(); speakerCapture.StartRecording(); Console.WriteLine("Recording... Press any key to stop."); Console.ReadLine(); // 停止录制并释放资源 micCapture.StopRecording(); speakerCapture.StopRecording(); micProvider.Dispose(); speakerProvider.Dispose(); } }
关键说明
- 格式统一:使用
MediaFoundationResampler将两个设备的音频流转换为相同的WaveFormat,确保后续混音和写入的兼容性。 - 混音处理:
MixingSampleProvider会自动同步两个音频流的时间轴,将它们的音频样本混合在一起,避免帧错位问题。 - 资源管理:确保所有Wave相关对象都正确释放,避免内存泄漏。
额外注意事项
- 如果系统不支持MediaFoundationResampler,可以改用
WaveFormatConversionStream,但前者的重采样质量更高。 - 可以根据需求调整目标格式(比如单声道、不同采样率),但两个流必须统一为同一格式。
- 若需要更精确的同步,可以调整
WasapiCapture的Latency属性,减少捕获延迟。
内容的提问来源于stack exchange,提问作者Shouri Kanduri
相关产品推荐
相关产品推荐

