UWP MediaElement停止后无法重新播放的问题咨询
问题现象与解决方法
问题现象
- 首次播放
MyMediaElement时,状态变化为:opening -> paused -> playing,播放正常 - 执行
MyMediaElement.Source = null停止播放后,CurrentState变为closed,未触发MediaEnded事件,显示黑屏(符合预期) - 再次尝试播放时,状态变为
opening -> closed,仍显示黑屏,未触发MediaOpened事件,但触发MyediaElement_MediaFailed事件,报错:MF_MEDIA_ENGINE_ERR_SRC_NOT_SUPPORTED : HRESULT - 0xC00D3E85(媒体资源不受支持)
疑问
如何让第三次播放像第一次一样正常?_mediaStreamSource仍为有效值,为何第一次正常第三次失败?
原因分析
当调用MyMediaElement.Source = null时,MediaElement会内部释放绑定的MediaStreamSource实例,即便你保留了_mediaStreamSource的引用,该实例已处于不可用状态,无法再次被MediaElement调用,这就是第三次播放报错的核心原因。
解决方案
方案1:避免设置Source = null(推荐)
若仅需停止播放并显示黑屏,无需将MediaElement重置为closed状态,可修改停止按钮逻辑,仅调用Stop(),重新播放时直接调用Play()即可:
private void btn_stop(object sender, RoutedEventArgs e) { MyMediaElement.Stop(); // 移除Source = null的操作 } private void btn_play(object sender, RoutedEventArgs e) { if (MyMediaElement.CurrentState == MediaElementState.Stopped || MyMediaElement.CurrentState == MediaElementState.Paused) { MyMediaElement.Play(); } else if (MyMediaElement.CurrentState == MediaElementState.Closed) { MyMediaElement.SetMediaStreamSource(_mediaStreamSource); } }
方案2:重新创建MediaStreamSource实例
若必须通过Source = null让MediaElement回到closed状态,每次重新播放时需创建新的MediaStreamSource实例,而非复用旧实例:
private void btn_stop(object sender, RoutedEventArgs e) { MyMediaElement.Stop(); MyMediaElement.Source = null; // 释放旧的MediaStreamSource _mediaStreamSource?.Dispose(); _mediaStreamSource = null; } private void btn_play(object sender, RoutedEventArgs e) { if (MyMediaElement.CurrentState == MediaElementState.Closed) { // 替换成你实际创建MediaStreamSource的逻辑 _mediaStreamSource = CreateNewMediaStreamSource(); MyMediaElement.SetMediaStreamSource(_mediaStreamSource); } }
另外,在MediaOpened事件中,需先清理旧定时器再创建新实例,避免内存泄漏:
private void MyMediaElement_MediaOpened(object sender, RoutedEventArgs e) { MediaElement player = sender as MediaElement; if (player.NaturalDuration.HasTimeSpan) { // 先清理旧定时器 _mediaPlayerTimer?.Stop(); _mediaPlayerTimer?.Tick -= MediaPlayerTimer_Tick; _mediaPlayerTimer = new DispatcherTimer(); _mediaPlayerTimer.Interval = TimeSpan.FromMilliseconds(100); _mediaPlayerTimer.Tick += MediaPlayerTimer_Tick; _mediaPlayerTimer.Start(); } }
内容的提问来源于stack exchange,提问作者ricky rocky
相关产品推荐
相关产品推荐

