C# Winform 當音頻播放完成后,播放下一個音頻,怎么知道音頻有沒有播放完成
程序在預警時,會發出報警音,當報警音頻播放時間,超過預警頻率時,就會像我們打印文檔一樣,像打印機發送10次打印任務。當打出第1張紙的時候,這時候想取消打印。就不能在電腦端通過軟件操作了。因此為了避免這種事情發生,就只有等打印機打完一張,再發下一個任務。這樣的話,可以隨時發起取消打印任務。
如果實現在報警音頻結束前,不再給任務
SoundPlayer
在C#中,SoundPlayer 類本身沒有直接提供事件或屬性來檢測音頻是否播放完成。不過,你可以通過以下方法來實現這一功能:PlaySync 方法會阻塞當前線程,直到音頻播放完成。你可以將播放操作放在一個單獨的線程中,以避免阻塞主線程。
滿足不了我想要的功能
using System;
using System.Media;
using System.Threading;
class Program
{
static void Main()
{
string[] audioFiles = { "audio1.wav", "audio2.wav", "audio3.wav" };
SoundPlayer player = new SoundPlayer();
foreach (string file in audioFiles)
{
//TODO 如果任務取消,break 跳出循環
player.SoundLocation = file;
player.Load(); // 加載音頻文件
player.PlaySync(); // 阻塞播放,直到當前音頻播放完成
Console.WriteLine($"播放完成: {file}");
}
Console.WriteLine("所有音頻播放完成");
}
}
優點:
- 實現簡單,代碼直觀。
- 不需要額外的事件處理。
缺點:
- PlaySync會阻塞當前線程,可能導致UI線程卡住(如果是在UI線程中運行)。
NAudio
C# Winform 通過 NAudio 獲取控制電腦操作系統音量
NAudio庫提供了更強大的音頻處理功能,可以通過PlaybackStopped事件來實現連續播放
NAudio 中,WaveOutEvent 是一個用于播放音頻的類,它封裝了底層的音頻設備資源。如果在使用完畢后沒有調用 Dispose() 方法,垃圾回收器(GC)會在對象被回收時調用其析構函數(Finalize),但此時可能已經無法正確釋放資源,從而導致錯誤。
如果 WaveOutEvent 使用了 AudioFileReader 或其他資源,確保這些資源也被釋放:
using System;
using System.Collections.Generic;
using NAudio.Wave;
public class MyForm : Form
{
private Label myLabel;
public MyForm()
{
}
WaveOutEvent waveOut;
AudioFileReader audioFile; //要單獨拿出來,進行釋放
List<string> audioFiles = new List<string> { "audio1.wav", "audio2.wav", "audio3.wav" };
private void OnLineCustodyOrderFrm_Load(object sender, EventArgs e)
{
waveOut = new WaveOutEvent();
waveOut.PlaybackStopped += WaveOut_PlaybackStopped;
PlayNextAudio();
}
private void WaveOut_PlaybackStopped(object sender, StoppedEventArgs e)
{
if (waveOut != null && waveOut.PlaybackState == PlaybackState.Stopped)
{
waveOut.Dispose();
}
Console.WriteLine($"播放完成: {audioFiles[currentIndex - 1]}");
PlayNextAudio();
}
private void PlayNextAudio()
{
if (currentIndex < audioFiles.Count)
{
audioFile = new AudioFileReader(audioFiles[currentIndex]);
waveOut.Init(audioFile);
waveOut.Play();
Console.WriteLine($"開始播放: {audioFiles[currentIndex]}");
currentIndex++;
}
else
{
Console.WriteLine("所有音頻播放完成");
}
}
private void MyForm_FormClosing(object sender, FormClosingEventArgs e)
{
CloseWaveOut();
}
private void CloseWaveOut()
{
if (waveOut != null)
{
waveOut.Stop();
}
if (AudioFile != null)
{
AudioFile.Dispose();
AudioFile = null;
}
//窗體關系,要釋放資源
if (waveOut != null)
{
waveOut.Dispose(); // 確保控件被釋放
waveOut = null;
}
}
}
關鍵點
顯式釋放資源:
- 在每次音頻播放完成后,調用 waveOut.Dispose() 釋放當前的 WaveOutEvent 對象。
- 在程序退出前,確保釋放所有資源。
重新創建 WaveOutEvent:
- 每次播放新的音頻文件時,重新創建一個新的 WaveOutEvent 對象,而不是復用之前的對象。
釋放 AudioFileReader:
- 如果使用了 AudioFileReader,也需要確保在播放完成后釋放它。
本文來自博客園,作者:VipSoft 轉載請注明原文鏈接:http://www.rzrgm.cn/vipsoft/p/18711375
浙公網安備 33010602011771號