如何仅在第一个结束时播放声音文件?
我有这样的代码:如何仅在第一个结束时播放声音文件?
MediaElement player = new MediaElement();
Windows.Storage.StorageFolder folder;
Windows.Storage.StorageFile file;
string FileName = "";
private async void Play(string Tno, string Cno)
{
folder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("Assets");
for (int i = 1; i <= 4; i++)
{
switch (i)
{
case 1:
FileName = "Sound\\mysound1.wav";
break;
case 2:
FileName = "Sound\\mysound2.wav";
break;
case 3:
FileName = "Sound\\mysound3.wav";
break;
case 4:
FileName = "Sound\\mysound4.wav";
break;
}
file = await folder.GetFileAsync(FileName);
player.SetSource(await file.OpenAsync(Windows.Storage.FileAccessMode.Read), file.ContentType);
player.Play();
}
}
它播放声音 “mysound4.wav”。 当我追踪代码时,它会过快地播放4个文件,而不会有任何延迟。 那么我怎样才能播放第二个文件,只有当第一个完成?
在WPF应用的解决方案可以使用这样的队列......
public partial class MainWindow : Window
{
private readonly Queue<string> _audioFilesQueue = new Queue<string>();
private readonly MediaElement _player;
public MainWindow()
{
InitializeComponent();
_player = new MediaElement();
_player.LoadedBehavior = MediaState.Manual;
_player.UnloadedBehavior = MediaState.Manual;
_player.MediaEnded += Player_MediaEnded;
}
private void Player_MediaEnded(object sender, RoutedEventArgs e)
{
OnProcessQueue();
}
private void Btn_OnClick(object sender, RoutedEventArgs e)
{
PlayCascade(new[]
{
"X:\\Library\\Sounds\\Other\\sound1.wav",
"X:\\Library\\Sounds\\Other\\sound2.wav",
"X:\\Library\\Sounds\\Other\\sound3.wav"
});
}
private void PlayCascade(string[] sequence)
{
foreach (var file in sequence)
{
_audioFilesQueue.Enqueue(file);
}
OnProcessQueue();
}
private void OnProcessQueue()
{
Dispatcher.Invoke(() =>
{
if (_audioFilesQueue.Any())
{
var toPlay = _audioFilesQueue.Dequeue();
_player.Source = new Uri(toPlay);
_player.Play();
}
});
}
队列是一个非常好的触摸,但是您应该更加重视回答问题(您的代码中_really_回答问题的部分是事件回调)。不要误解我的意思,队列是为此而设计的,但这只是质量改进,在这种情况下,它是真正的答案。也许增加2个片段:一个只是解释回调是如何工作的,另一个是队列。 – Kroltan
它是真的很好的代码,谢谢 ,但不幸的是VS 2017不包含MediaState.Manual 所以我评论这些代码,它没有工作 _player.LoadedBehavior = MediaState.Manual; _player.UnloadedBehavior = MediaState.Manual; 有什么建议吗? – Ammar
这不是VS的问题,我想你不是在WPF应用程序上工作,而是在UWP上工作。然而,我的代码是指一个WPF桌面应用程序,所以不介意删除行或适应您的需求 – Grappachu
如果是我我会包裹在描述符包装类持有文件,例如路径上的数据每个WAV ,持续时间等...将包装器排队到知道何时出队的特殊队列(您必须记住上次时间项目已过期并检查持续时间是否已结束)并播放一个项目 – ilansch
尝试使用Mediaelmement的CurrentState属性:https ://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.mediaelement#Windows_UI_Xaml_Controls_MediaElement_CurrentState –
如果在多线程环境中调用此方法会怎么样?你一次只需要一个媒体播放。 – ilansch