如何确定 MediaElement 是不是正在播放?
Posted
技术标签:
【中文标题】如何确定 MediaElement 是不是正在播放?【英文标题】:How do I determine if MediaElement is playing?如何确定 MediaElement 是否正在播放? 【发布时间】:2011-05-19 08:17:38 【问题描述】:看起来很简单,但我想不出任何方法来确定 MediaElement 的状态。某些状态(例如 IsBuffering)有各种属性,但我找不到播放、暂停等状态的任何属性。Silverlight 似乎有一个 CurrentState 属性可以显示所有这些。
目前,我确定是否应该播放视频的方式是观看各种事件和一个计时器,以检查是否正在取得任何进展。
我是 MediaElement 和 WPF 的新手(我实际上只在 WinForms 应用程序中使用 MediaElement)。有什么我遗漏的吗?
【问题讨论】:
【参考方案1】:你没有错过任何东西。您几乎必须手动跟踪媒体是否正在播放。很遗憾,正如您所提到的,因为在 Silverlight 中这很容易。对我来说似乎是一个重大疏忽。
【讨论】:
我在 WPF GitHub 存储库中添加了一个关于此的功能请求。请去给它竖起大拇指。 Add CurrentState property to MediaElement #3655【参考方案2】:您可以使用反射获取_currentState
成员。
private MediaState GetMediaState(MediaElement myMedia)
FieldInfo hlp = typeof(MediaElement).GetField("_helper", BindingFlags.NonPublic | BindingFlags.Instance);
object helperObject = hlp.GetValue(myMedia);
FieldInfo stateField = helperObject.GetType().GetField("_currentState", BindingFlags.NonPublic | BindingFlags.Instance);
MediaState state = (MediaState)stateField.GetValue(helperObject);
return state;
这包括播放/暂停,但完成后不会从“播放”变为“停止”。
您可以通过向MediaEnded
事件添加事件处理程序并运行.Stop()
方法来解决此问题,这会正确更改状态(可以通过上述方法获取)
【讨论】:
优秀的解决方案!这就是这样做的方法。 除非 Microsoft 将来某个时候重命名该字段 这对我来说非常有效。谢谢。我看到了重命名的潜在危险,但我们还有什么其他解决方案?下面引用的CurrentState
在现代完整 WPF 中不存在。【参考方案3】:
我做了什么来“解决”子类 MediaPlayer(这也适用于 MediaElement)并将我自己的方法添加到播放/暂停/停止。在这些方法中,我维护了一个表示播放状态的字段。此外,您需要挂钩 MediaEnded 以便您可以将状态从“正在播放”更改为“已停止”。
【讨论】:
把它放在 CodePlex 上。如果你没有时间,我打算,只是不想踩到任何脚趾。【参考方案4】:对于Universal Windows 10 Platform (UWP)
:
if ( yourMediaElement.CurrentState.ToString() == "Playing" )
//nou yourMediaElement is playng
如果您想改用enum
,则以下:
if (yourMediaElement.CurrentState == MediaElementState.Playing)
//nou yourMediaElement is playng
【讨论】:
【参考方案5】:并且可以基于 Rich S 实现扩展
//don't forget
using System.Windows.Controls;
using System.Reflection;
public static class Util
public static MediaState GetMediaState(this MediaElement myMedia)
FieldInfo hlp = typeof(MediaElement).GetField("_helper", BindingFlags.NonPublic | BindingFlags.Instance);
object helperObject = hlp.GetValue(myMedia);
FieldInfo stateField = helperObject.GetType().GetField("_currentState", BindingFlags.NonPublic | BindingFlags.Instance);
MediaState state = (MediaState)stateField.GetValue(helperObject);
return state;
【讨论】:
【参考方案6】:对于Silverlight
,使用 CurrentState 检查状态是播放还是暂停
if (YourMediaElementName.CurrentState == MediaElementState.Playing)
// TODO: when media is playing.
【讨论】:
需要注意的是CurrentState
只是Silverlight。【参考方案7】:
对于 WPF MediaElement,这是我使用的解决方案/解决方法:
bool IsPlaying()
var pos1 = wpfMediaElement.Position;
System.Threading.Thread.Sleep(1);
var pos2 = wpfMediaElement.Position;
return pos2 != pos1;
【讨论】:
那是可怕的解决方法。如果在 UI 线程中调用此方法,整个 UI 将被冻结。 我同意,这不是最好的方法。但我敢打赌,这个世界上没有人会在小程序上认出这一毫秒。这是亚历克斯的一种解决方法,我称之为快速'n脏,为此我将放弃投票。通过访问隐藏字段来使用隐藏的 HeperProperty 也确实不是一个“好的解决方案”。 没什么问题。没有状态属性的媒体元素是真正可怕的解决方案...也没有人要求你在 UI 线程中调用它。【参考方案8】:对于 WPF 使用这个:
var playing = player.Position < player.NaturalDuration;
【讨论】:
以上是关于如何确定 MediaElement 是不是正在播放?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Dropbox 中的视频播放到我的 win phone 8 应用程序的 mediaelement 中?