【问题标题】:How do I determine if MediaElement is playing?如何确定 MediaElement 是否正在播放?
【发布时间】:2011-05-19 08:17:38
【问题描述】:

看起来很简单,但我想不出任何方法来确定 MediaElement 的状态。某些状态(例如 IsBuffering)有各种属性,但我找不到播放、暂停等状态的任何属性。Silverlight 似乎有一个 CurrentState 属性可以显示所有这些。

目前,我确定是否应该播放视频的方式是观看各种事件和一个计时器,以检查是否正在取得任何进展。

我是 MediaElement 和 WPF 的新手(我实际上只在 WinForms 应用程序中使用 MediaElement)。有什么我遗漏的吗?

【问题讨论】:

    标签: wpf mediaelement


    【解决方案1】:

    你没有错过任何东西。您几乎必须手动跟踪媒体是否正在播放。很遗憾,正如您所提到的,因为在 Silverlight 中这很容易。对我来说似乎是一个重大疏忽。

    【讨论】:

    【解决方案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;

        【讨论】:

          猜你喜欢
          • 2012-01-05
          • 1970-01-01
          • 2023-03-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多