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

NAudio PlaybackState始终为Playing,播放无法终止问题排查

问题分析与解决

核心问题

你遇到的循环无法终止、PlaybackStopped回调不触发的原因是:BufferedWaveProvider没有被告知数据流已结束。当你把所有音频块添加到缓冲区后,它仍会持续等待新数据输入,导致WaveOut一直维持Playing状态,不会主动停止播放。

解决方法

在遍历完所有recordedChunks并完成样本添加后,调用BufferedWaveProvider.SetEndOfStream()方法,明确标记音频数据流结束。这样WaveOut在播放完缓冲区剩余数据后,会自动切换到Stopped状态,并触发PlaybackStopped事件。

修改后的代码

static void Play(int outputDeviceIndex, byte[][] recordedChunks)
{
    using (var waveOut = new WaveOutEvent())
    {
        waveOut.DeviceNumber = outputDeviceIndex;
        waveOut.PlaybackStopped += (sender, args) => 
        {
            Console.WriteLine("Playback stopped: " + (args.Exception?.Message ?? "No error"));
        };

        var bufferedWaveProvider = new BufferedWaveProvider(new WaveFormat(44100, 1));
        waveOut.Init(bufferedWaveProvider);
        waveOut.Play();
        
        foreach (var chunk in recordedChunks)
        {
            bufferedWaveProvider.AddSamples(chunk, 0, chunk.Length);
        }

        // 标记数据流结束,通知WaveOut播放完现有数据后停止
        bufferedWaveProvider.SetEndOfStream();

        while (waveOut.PlaybackState == PlaybackState.Playing)
        {
            Thread.Sleep(100);
        }
    }
}

补充说明

  • SetEndOfStream()会让BufferedWaveProvider在读取完缓冲区剩余数据后返回0字节,触发WaveOut的停止逻辑。
  • 如果你不需要同步等待播放结束,可以移除while循环,在PlaybackStopped回调中处理后续操作(不过当前代码中的using块需要等待播放完成,否则会提前释放WaveOut实例)。

内容的提问来源于stack exchange,提问作者Vandermyer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 00:39:54