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; } } }

浙公网安备 33010602011771号