我在WPF中创建游戏。为了管理声音,我创建了一个AudioController,它将创建MediaPlayers并管理播放,停止,循环,暂停等。我有它的基础工作。如果我在控件中,我可以打电话
AudioController.Play("MySound");
它将决定它是否已经为该声音设置了MediaPlayer,如果没有,它将创建一个。
在以下情况下会出现问题:
Task.Run(() => { DoSomething(); AudioController.Play("MySound"); });
_timer_tick(object sender...) { AudioController.Play("MySound"); }
使用“任务”时,我的声音将正常播放,但MediaEnded事件永远不会被触发,导致我无法正确管理MediaPlayers。
使用计时器刻度,声音将第一次播放,但永远不会再播放,即使它使用一个新的MediaPlayer 也永远不会触发MediaEnded事件
我已经尝试过调度电话,但它似乎没有什么区别。 我只能想象问题在于Play()调用是从不同的线程发送的。
public static void Play(string sound)
{
Debug.WriteLine("Publish called on Thread Id {0}", Thread.CurrentThread.ManagedThreadId);
if (!Application.Current.CheckAccess())
{
Application.Current.Dispatcher.Invoke(() => Play(sound, TimeSpan.Zero), DispatcherPriority.Normal);
return;
}
Play(sound, TimeSpan.Zero);
}
private static void Play(string sound, TimeSpan position)
{
//...some preemptive code that's just searching a list
//reuse
if (ap == null)
{
ap = new AudioPlayer(entry);
_players.Add(ap);
}
ap.Play(position);
}
注意:AudioPlayer是一个围绕MediaPlayer的包装类,因此我可以添加一些其他属性,例如LastActive
,IsLooping
,并通过调用来处理重放声音: / p>
_player.Stop();
_player.Position = position;
_player.Play();
更新:
我刚刚决定在上面的场景中运行不同的声音,一切似乎都运行正常。音频的唯一区别是一个是40kb而另一个是67kb。可能是文件太小而MediaPlayer没有注册NaturalDuration,因此假定它的0会阻止事件被触发吗?