C# Winform 当音频播放完成后,播放下一个音频,怎么知道音频有没有播放完 ...

打印 上一主题 下一主题

主题 900|帖子 900|积分 2700

程序在预警时,会发出报警音,当报警音频播放时间,超过预警频率时,就会像我们打印文档一样,像打印机发送10次打印任务。当打出第1张纸的时候,这时候想取消打印。就不能在电脑端通过软件操作了。因此为了避免这种事情发生,就只有等打印机打完一张,再发下一个任务。这样的话,可以随时发起取消打印任务。
如果实现在报警音频竣事前,不再给任务
SoundPlayer

在C#中,SoundPlayer 类本身没有直接提供变乱或属性来检测音频是否播放完成。不过,你可以通过以下方法来实现这一功能:PlaySync 方法会壅闭当前线程,直到音频播放完成。你可以将播放操作放在一个单独的线程中,以避免壅闭主线程。
满意不了我想要的功能
  1. using System;
  2. using System.Media;
  3. using System.Threading;
  4. class Program
  5. {
  6.     static void Main()
  7.     {
  8.         string[] audioFiles = { "audio1.wav", "audio2.wav", "audio3.wav" };
  9.         SoundPlayer player = new SoundPlayer();
  10.         foreach (string file in audioFiles)
  11.         {
  12.             //TODO 如果任务取消,break 跳出循环
  13.             player.SoundLocation = file;
  14.             player.Load(); // 加载音频文件
  15.             player.PlaySync(); // 阻塞播放,直到当前音频播放完成
  16.             Console.WriteLine($"播放完成: {file}");
  17.         }
  18.         Console.WriteLine("所有音频播放完成");
  19.     }
  20. }
复制代码
优点:

  • 实现简单,代码直观。
  • 不必要额外的变乱处理。
缺点:

  • PlaySync会壅闭当前线程,可能导致UI线程卡住(如果是在UI线程中运行)。
NAudio

C# Winform 通过 NAudio 获取控制电脑操作系统音量
NAudio库提供了更强大的音频处理功能,可以通过PlaybackStopped变乱来实现连续播放
NAudio 中,WaveOutEvent 是一个用于播放音频的类,它封装了底层的音频设备资源。如果在使用完毕后没有调用 Dispose() 方法,垃圾回收器(GC)会在对象被回收时调用其析构函数(Finalize),但此时可能已经无法正确释放资源,从而导致错误。
如果 WaveOutEvent 使用了 AudioFileReader 或其他资源,确保这些资源也被释放:
  1. using System;
  2. using System.Collections.Generic;
  3. using NAudio.Wave;
  4. public class MyForm : Form
  5. {
  6.     private Label myLabel;
  7.     public MyForm()
  8.     {
  9.     }
  10.    
  11.     WaveOutEvent waveOut;
  12.     AudioFileReader audioFile; //要单独拿出来,进行释放
  13.        
  14.     List<string> audioFiles = new List<string> { "audio1.wav", "audio2.wav", "audio3.wav" };
  15.    
  16.     private void OnLineCustodyOrderFrm_Load(object sender, EventArgs e)
  17.     {
  18.         waveOut = new WaveOutEvent();
  19.         waveOut.PlaybackStopped += WaveOut_PlaybackStopped;
  20.         PlayNextAudio();
  21.     }
  22.     private void WaveOut_PlaybackStopped(object sender, StoppedEventArgs e)
  23.     {
  24.         if (waveOut != null && waveOut.PlaybackState == PlaybackState.Stopped)
  25.         {
  26.             waveOut.Dispose();
  27.         }
  28.         Console.WriteLine($"播放完成: {audioFiles[currentIndex - 1]}");
  29.         PlayNextAudio();
  30.     }
  31.     private void PlayNextAudio()
  32.     {
  33.         if (currentIndex < audioFiles.Count)
  34.         {
  35.             audioFile = new AudioFileReader(audioFiles[currentIndex]);
  36.             waveOut.Init(audioFile);
  37.             waveOut.Play();
  38.             Console.WriteLine($"开始播放: {audioFiles[currentIndex]}");
  39.             currentIndex++;
  40.         }
  41.         else
  42.         {
  43.             Console.WriteLine("所有音频播放完成");
  44.         }
  45.     }
  46.     private void MyForm_FormClosing(object sender, FormClosingEventArgs e)
  47.     {
  48.          CloseWaveOut();
  49.     }
  50.     private void CloseWaveOut()
  51.     {
  52.         if (waveOut != null)
  53.         {
  54.            waveOut.Stop();
  55.         }
  56.         if (AudioFile != null)
  57.         {
  58.             AudioFile.Dispose();
  59.             AudioFile = null;
  60.         }
  61.         //窗体关系,要释放资源
  62.         if (waveOut != null)
  63.         {
  64.             waveOut.Dispose(); // 确保控件被释放
  65.             waveOut = null;
  66.         }
  67.     }
  68. }
复制代码
关键点
显式释放资源:

  • 在每次音频播放完成后,调用 waveOut.Dispose() 释放当前的 WaveOutEvent 对象。
  • 在程序退出前,确保释放所有资源。
重新创建 WaveOutEvent:

  • 每次播放新的音频文件时,重新创建一个新的 WaveOutEvent 对象,而不是复用之前的对象。
释放 AudioFileReader:

  • 如果使用了 AudioFileReader,也必要确保在播放完成后释放它。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

数据人与超自然意识

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表