NAudio中WaveOut仅在Windows默认输出设备播放音频的问题求助
解决NAudio WaveOut无法切换指定音频输出设备的问题
问题根源
设备编号设置时机错误
WaveOut的DeviceNumber必须在Init()之前设置——Init()方法会根据当前的设备编号绑定音频输出通道,事后再修改不会生效。你原代码里先调用Init再改DeviceNumber,完全搞反了顺序。设备枚举体系不匹配
WaveOut用的是传统Windows波形音频设备的编号,而MMDeviceEnumerator枚举的是Core Audio设备,两者的编号顺序不一定对应。如果想精准指定枚举到的设备,推荐用WasapiOut替代WaveOut,它直接支持绑定MMDevice实例。
修正方案
方案1:调整WaveOut的设置顺序(仅解决时机问题,注意设备编号对应)
static void Main(string[] args) { int waveOutDeviceCount = WaveOut.DeviceCount; var testFile = new WaveFileReader("./test.wav"); for (int i = 0; i < waveOutDeviceCount; i++) { var deviceInfo = WaveOut.GetCapabilities(i); Console.WriteLine("使用WaveOut设备: " + deviceInfo.ProductName); var waveout = new WaveOut(); waveout.DeviceNumber = i; // 先选设备 waveout.Init(testFile); // 再初始化 waveout.Play(); Thread.Sleep(4000); waveout.Stop(); waveout.Dispose(); testFile.Position = 0; // 重置音频文件指针,方便下次播放 } testFile.Dispose(); }
方案2:使用WasapiOut绑定MMDevice(推荐,精准匹配Core Audio设备)
static void Main(string[] args) { MMDeviceEnumerator enumerator = new MMDeviceEnumerator(); MMDeviceCollection devices = enumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active); var allDevices = devices.ToList(); var testFile = new WaveFileReader("./test.wav"); for (int i = 0; i < allDevices.Count; i++) { var device = allDevices[i]; Console.WriteLine("使用设备: " + device.DeviceFriendlyName + ", " + device.FriendlyName); var wasapiOut = new WasapiOut(device, AudioClientShareMode.Shared, false, 100); wasapiOut.Init(testFile); wasapiOut.Play(); Thread.Sleep(4000); wasapiOut.Stop(); wasapiOut.Dispose(); testFile.Position = 0; // 重置音频指针 } testFile.Dispose(); }
额外注意事项
- 每次播放后必须重置
WaveFileReader的Position为0,否则后续播放会从文件末尾开始,听不到声音。 - WasapiOut支持Windows 10及以上系统的现代音频特性,比如独占模式、低延迟,更适合当前系统环境。
- 若坚持用WaveOut,不要混用MMDeviceEnumerator的设备列表,直接通过
WaveOut.DeviceCount和WaveOut.GetCapabilities()获取WaveOut自身的设备信息。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

