You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NAudio中WaveOut仅在Windows默认输出设备播放音频的问题求助

解决NAudio WaveOut无法切换指定音频输出设备的问题

问题根源

  1. 设备编号设置时机错误
    WaveOut的DeviceNumber必须在Init()之前设置——Init()方法会根据当前的设备编号绑定音频输出通道,事后再修改不会生效。你原代码里先调用Init再改DeviceNumber,完全搞反了顺序。

  2. 设备枚举体系不匹配
    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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 06:54:58