我只想依次播放 4 个声音(声音 1-> 声音 2-> 声音 3),但在每次播放期间都不会停止我的代码流,也不会等待每个声音结束。
我到处搜索这个,但我阅读的每个方向都陷入了其他问题。
到目前为止,我最好的选择是:使用我已经使用过的 System.Media 中的 SoundPlayer 并制作我自己的队列函数,但是 Soundplayer 没有“完成播放”事件,所以我不知道何时开始下一个声音。 (真的吗,微软?)
其他解决方案和问题: DirectSound 在 .NET (c#) 中工作似乎很复杂。 Win Playsound 并没有真正帮助,因为它也无法排队。
最佳答案
您可以尝试在 UI 外的线程上使用 PlaySync,例如:后台线程,正如某些人评论的那样。
这是一个示例(未经测试)对队列使用线程安全* BlockingCollection
* 你可以在线程内外使用
您可能想要创建自己的类或方法,在每次声音结束时触发一个事件。或者您可以在线程中循环队列,因为 PlaySync 将自行等待。
using System.Threading;
using System.Collections.Concurrent;
namespace PlaySound
{
public partial class Form1 : Form
{
private Thread soundPlayThread;
private BlockingCollection<string> speakQueue = new BlockingCollection<string>();
private CancellationTokenSource cancelSoundPlay;
private int soundPlayCount = 0;
public Form1()
{
InitializeComponent();
cancelSoundPlay = new CancellationTokenSource();
}
private void btnStartSoundPlay_Click(object sender, EventArgs e)
{
StartSoundPlay();
}
private void btnStopSoundPlay_Click(object sender, EventArgs e)
{
cancelSoundPlay.Cancel();
Console.WriteLine("Sound play cancelled.");
}
private void btnAddToQueue_Click(object sender, EventArgs e)
{
speakQueue.Add("MyFile.wav");
}
private void queueAndPlay(string loc)
{
if (!File.Exists(loc=loc+".wav"))
loc=configPath+"soundnotfound.wav";
speakQueue.Add(loc);
StartSoundPlay();
}
private void StartSoundPlay()
{
//Sound Player Loop Thread
if (this.soundPlayThread == null || !this.soundPlayThread.IsAlive)
{
this.soundPlayThread = new Thread(SoundPlayerLoop);
this.soundPlayThread.Name = "SoundPlayerLoop";
this.soundPlayThread.IsBackground = true;
this.soundPlayThread.Start();
Console.WriteLine("Sound play started");
}
}
//Method that the outside thread will use outside the thread of this class
private void SoundPlayerLoop()
{
var sound = new SoundPlayer();
foreach (String soundToPlay in this.speakQueue.GetConsumingEnumerable(cancelSoundPlay.Token))
{
//http://msdn.microsoft.com/en-us/library/system.media.soundplayer.playsync.aspx
speaker.SoundLocation=soundToPlay;
//Here the outside thread waits for the following play to end before continuing.
sound.PlaySync();
soundPlayCount++;
Console.WriteLine("Sound play end. Count: " + soundPlayCount);
}
}
}
}
关于c# - 如何异步播放声音,但自己在队列中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22208258/