求助:基于C#与NAudio实现音频输入设备实时监听播放功能
C# 使用NAudio实现麦克风实时监听及多通道扩展方案
1. 先解决NAudio引用问题
- 右键项目 → 选择「管理NuGet程序包」,搜索
NAudio安装最新稳定版 - 或者打开Package Manager控制台,执行命令:
Install-Package NAudio
2. 基础版:单麦克风实时监听播放
创建Windows Forms项目,拖入一个按钮(命名为btnStartStop),编写以下代码:
窗体类全局变量声明
using NAudio.Wave; using System.Windows.Forms; public partial class MainForm : Form { private WaveInEvent _micInput; private WaveOutEvent _speakerOutput; private bool _isListening = false; public MainForm() { InitializeComponent(); } }
按钮点击事件逻辑
private void btnStartStop_Click(object sender, EventArgs e) { if (!_isListening) { // 初始化输入输出设备 _micInput = new WaveInEvent(); _speakerOutput = new WaveOutEvent(); // 设置统一音频格式(输入输出必须匹配) var audioFormat = new WaveFormat(44100, 16, 2); // 44.1kHz、16位、立体声 _micInput.WaveFormat = audioFormat; _speakerOutput.Init(_micInput); // 麦克风数据实时传递给扬声器播放 _micInput.DataAvailable += (s, args) => { _speakerOutput.Write(args.Buffer, 0, args.BytesRecorded); }; // 启动监听 _micInput.StartRecording(); _speakerOutput.Play(); _isListening = true; btnStartStop.Text = "停止监听"; } else { // 停止并释放资源,避免内存泄漏 _micInput.StopRecording(); _speakerOutput.Stop(); _micInput.Dispose(); _speakerOutput.Dispose(); _isListening = false; btnStartStop.Text = "开始监听"; } }
窗体关闭时的资源清理
private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { if (_isListening) { _micInput.StopRecording(); _speakerOutput.Stop(); } _micInput?.Dispose(); _speakerOutput?.Dispose(); }
可选:让用户预选输入设备
如果需要让用户选择特定麦克风,在窗体加载时获取设备列表:
private void MainForm_Load(object sender, EventArgs e) { var deviceSelector = new ComboBox(); // 拖一个ComboBox到窗体 for (int i = 0; i < WaveIn.DeviceCount; i++) { var deviceInfo = WaveIn.GetCapabilities(i); deviceSelector.Items.Add($"{i}: {deviceInfo.ProductName}"); } deviceSelector.SelectedIndex = 0; // 默认选中第一个设备 } // 初始化WaveIn时设置设备编号: // _micInput.DeviceNumber = deviceSelector.SelectedIndex;
3. 后续扩展:多通道输入混合播放
要实现多个麦克风同时输出到扬声器,使用NAudio的MixingSampleProvider完成音频流混合:
核心代码示例
private List<WaveInEvent> _multiMicList = new List<WaveInEvent>(); private WaveOutEvent _multiSpeakerOutput; private MixingSampleProvider _audioMixer; // 启动多麦克风监听 private void StartMultiListening() { var targetFormat = new WaveFormat(44100, 16, 2); _audioMixer = new MixingSampleProvider(targetFormat.ToSampleProvider().WaveFormat); _audioMixer.ReadFully = true; // 确保读取所有输入数据完成混合 // 假设有两个麦克风设备,编号为0和1 foreach (int deviceNum in new[] {0, 1}) { var micInput = new WaveInEvent(); micInput.DeviceNumber = deviceNum; micInput.WaveFormat = targetFormat; // 将麦克风输入转换为SampleProvider,添加到混音器 var sampleProvider = micInput.ToSampleProvider(); _audioMixer.AddMixerInput(sampleProvider); micInput.StartRecording(); _multiMicList.Add(micInput); } // 将混音后的流转换为WaveProvider,供扬声器播放 var mixedWaveProvider = _audioMixer.ToWaveProvider(); _multiSpeakerOutput = new WaveOutEvent(); _multiSpeakerOutput.Init(mixedWaveProvider); _multiSpeakerOutput.Play(); } // 停止多麦克风监听 private void StopMultiListening() { foreach (var mic in _multiMicList) { mic.StopRecording(); mic.Dispose(); } _multiSpeakerOutput.Stop(); _multiSpeakerOutput.Dispose(); _multiMicList.Clear(); }
扩展注意事项
- 所有输入设备的音频格式必须和混音器目标格式一致,格式不匹配时可使用
ResamplerDmoSampleProvider进行转换 - 多输入叠加可能导致音量失真,可给每个
SampleProvider添加VolumeSampleProvider单独调节音量
内容的提问来源于stack exchange,提问作者TTACsniper1234
相关产品推荐
相关产品推荐

