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

C#实现音频无缝切换遇问题:播放存在间隙求解决方案

解决音频无缝播放间隙问题

问题根源

你当前使用的System.Media.SoundPlayer依赖Windows的PlaySound API,这个API在每次播放结束后会自动释放音频资源,切换下一段音频时需要重新初始化资源,这中间的延迟就是导致音轨间隙的原因。这个类的设计定位是简单播放音频,并不支持无缝衔接的场景。

解决方案:使用NAudio实现无缝播放

NAudio是.NET生态中专业的音频处理库,能很好地支持无缝播放需求。以下是具体实现步骤:

1. 安装NAudio包

通过NuGet包管理器安装:

Install-Package NAudio

2. 重写AudioPlayer类

using NAudio.Wave;
using System.Collections.Generic;
using System.Threading;

public static class AudioPlayer
{
    private static Thread _playbackThread;
    private static WaveOutEvent _waveOut;
    private static Queue<IWaveProvider> _playbackQueue = new Queue<IWaveProvider>();
    private static bool _stopRequested;

    public static void Initialize()
    {
        // 初始化播放设备,绑定播放完成事件
        _waveOut = new WaveOutEvent();
        _waveOut.PlaybackStopped += OnPlaybackStopped;

        // 预加载所有音频文件
        _playbackQueue.Enqueue(new AudioFileReader(@"../../../snippets/intro.wav"));
        _playbackQueue.Enqueue(new AudioFileReader(@"../../../snippets/0.wav"));
        _playbackQueue.Enqueue(new AudioFileReader(@"../../../snippets/1.wav"));
        _playbackQueue.Enqueue(new AudioFileReader(@"../../../snippets/2.wav"));
    }

    public static void Play()
    {
        _playbackThread = new Thread(RunPlaybackLoop);
        _playbackThread.Start();
    }

    public static void Stop()
    {
        _stopRequested = true;
    }

    private static void RunPlaybackLoop()
    {
        // 启动第一个音频播放
        PlayNextInQueue();

        // 循环补充队列直到收到停止请求
        while (!_stopRequested)
        {
            Thread.Sleep(50);
            // 重新添加循环片段到队列,实现无限循环
            _playbackQueue.Enqueue(new AudioFileReader(@"../../../snippets/0.wav"));
            _playbackQueue.Enqueue(new AudioFileReader(@"../../../snippets/1.wav"));
            _playbackQueue.Enqueue(new AudioFileReader(@"../../../snippets/2.wav"));
        }

        // 播放 outro 收尾
        _playbackQueue.Enqueue(new AudioFileReader(@"../../../snippets/outro.wav"));
        PlayNextInQueue();
    }

    private static void PlayNextInQueue()
    {
        if (_playbackQueue.Count > 0)
        {
            var nextStream = _playbackQueue.Dequeue();
            _waveOut.Init(nextStream);
            _waveOut.Play();
        }
    }

    private static void OnPlaybackStopped(object sender, StoppedEventArgs e)
    {
        // 当前音频播放完成后自动启动下一段
        if (!_stopRequested || _playbackQueue.Count > 0)
        {
            PlayNextInQueue();
        }
        else
        {
            // 清理资源
            _waveOut.Dispose();
        }
    }
}

关键优化点

  • 使用WaveOutEvent作为播放设备,支持播放完成触发事件,实现无延迟切换
  • 预加载音频为AudioFileReader,避免重复加载带来的延迟
  • 通过队列管理播放顺序,当前音频结束后立即启动下一段,实现无缝衔接

备选方案:拼接音频流(固定循环次数场景)

如果循环次数固定,可以将所有音频片段拼接成一个完整流后一次性播放,完全消除间隙:

using NAudio.Wave;

public static class AudioPlayer
{
    private static WaveOutEvent _waveOut;

    public static void Initialize()
    {
        _waveOut = new WaveOutEvent();
    }

    public static void Play()
    {
        // 加载所有音频片段
        var intro = new AudioFileReader(@"../../../snippets/intro.wav");
        var snippet0 = new AudioFileReader(@"../../../snippets/0.wav");
        var snippet1 = new AudioFileReader(@"../../../snippets/1.wav");
        var snippet2 = new AudioFileReader(@"../../../snippets/2.wav");
        var outro = new AudioFileReader(@"../../../snippets/outro.wav");

        // 拼接成连续流(示例循环3次)
        var concatenatedStream = new ConcatenatingWaveStream();
        concatenatedStream.AddWaveStream(intro);
        for (int i = 0; i < 3; i++)
        {
            concatenatedStream.AddWaveStream(snippet0);
            concatenatedStream.AddWaveStream(snippet1);
            concatenatedStream.AddWaveStream(snippet2);
        }
        concatenatedStream.AddWaveStream(outro);

        // 播放完整流
        _waveOut.Init(concatenatedStream);
        _waveOut.Play();
    }

    public static void Stop()
    {
        _waveOut.Stop();
        _waveOut.Dispose();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 07:37:38