winform播放声音文件,播完成后自动播放下一个文件

1、nuget安装NAudio

2、代码实现

using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SoundWin.Common
{
    public static class AudioPlayer
    {
        /// <summary>
        /// 按顺序播放多个音频文件,每个文件播放完后自动播放下一个。
        /// </summary>
        /// <param name="audioFiles">音频文件路径列表</param>
        /// <returns>Task,当所有文件播放完毕时完成</returns>
        public static async Task PlayAllSequentiallyAsync(IEnumerable<string> audioFiles)
        {
            if (audioFiles == null)
                throw new ArgumentNullException(nameof(audioFiles));

            var files = new List<string>(audioFiles);
            if (files.Count == 0)
                return;

            // 使用 TaskCompletionSource 来等待播放完成
            var tcs = new TaskCompletionSource<bool>();

            // 在 UI 线程(如 WinForms)中,我们需要确保事件回调能正确同步
            // 这里使用 SynchronizationContext 捕获当前上下文(如果是 UI 线程)
            var syncContext = SynchronizationContext.Current;

            WaveOutEvent outputDevice = null;
            AudioFileReader audioFileReader = null;

            void PlayNext(int index)
            {
                try
                {
                    // 释放上一个资源
                    audioFileReader?.Dispose();
                    outputDevice?.Dispose();

                    if (index >= files.Count)
                    {
                        // 全部播放完毕
                        tcs.TrySetResult(true);
                        return;
                    }

                    string currentFile = files[index];
                    audioFileReader = new AudioFileReader(currentFile);
                    outputDevice = new WaveOutEvent();

                    // 订阅播放结束事件
                    outputDevice.PlaybackStopped += (s, e) =>
                    {
                        // 在原始上下文(如 UI 线程)中调用 PlayNext
                        if (syncContext != null)
                        {
                            syncContext.Post(_ => PlayNext(index + 1), null);
                        }
                        else
                        {
                            PlayNext(index + 1);
                        }
                    };

                    outputDevice.Init(audioFileReader);
                    outputDevice.Play();
                }
                catch (Exception ex)
                {
                    // 可选:记录日志或跳过错误文件
                    System.Diagnostics.Debug.WriteLine($"播放失败: {ex.Message}");
                    // 跳过当前文件,继续下一个
                    if (syncContext != null)
                        syncContext.Post(_ => PlayNext(index + 1), null);
                    else
                        PlayNext(index + 1);
                }
            }

            // 开始播放第一个文件
            PlayNext(0);

            // 等待全部播放完成
            await tcs.Task;
        }
    }
}
View Code

 

posted @ 2025-11-12 11:00  ziff123  阅读(5)  评论(0)    收藏  举报