34

Seems simple enough, but I cannot figure out any way to determine what the state of a MediaElement is. There are various properties for some states (such as IsBuffering) but I can't find any for states such as Play, Pause, etc. Silverlight seems to have a CurrentState property that shows all these.

Currently the way I'm determining whether a video is supposed to be playing is watching for various events and a timer that checks to see if any progress is being made.

I'm new to MediaElement and WPF (I'm actually only using MediaElement in a WinForms app). Is there something I am missing?

Brian
  • 37,399
  • 24
  • 94
  • 109

9 Answers9

32

You aren't missing anything. You pretty much have to manually keep track of whether or not the media is playing. It's a pity, since it is so easy in Silverlight, as you mention. Seems like a major oversight to me.

PeterL
  • 1,397
  • 11
  • 15
  • I have added a feature request about this on the WPF GitHub repository. Please go give it a thumbs up. [Add CurrentState property to MediaElement #3655](https://github.com/dotnet/wpf/issues/3655) – Jan Ivar Z. Carlsen Oct 16 '20 at 08:29
24

You can get at the _currentState member using reflection.

    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;
    }

This covers play/pause, but doesn't change from 'play' to 'stop' when it finishes.

You can get around this by adding an event handler to the MediaEnded event, and running the .Stop() method, this changes the status correctly (which can be picked up by the method above)

Woffy
  • 98
  • 6
Rich S
  • 3,248
  • 3
  • 28
  • 49
9

What I did to "work around" that was subclass MediaPlayer (this would work for MediaElement as well) and add my own methods to Play/Pause/Stop. In those methods, I maintain a field which represents the playback status. Also, you need to hook MediaEnded so that you can change the status from 'playing' to 'stopped.'

NoWar
  • 36,338
  • 80
  • 323
  • 498
4

For Universal Windows 10 Platform (UWP) :

if ( yourMediaElement.CurrentState.ToString() == "Playing" ) 
{
    //nou yourMediaElement is playng
}

or below if you wana use an enum instead:

if (yourMediaElement.CurrentState == MediaElementState.Playing)
{
    //nou yourMediaElement is playng
}
iam.Carrot
  • 4,976
  • 2
  • 24
  • 71
Choletski
  • 7,074
  • 6
  • 43
  • 64
2

For Silverlight use CurrentState to check whether the state is playing or pause

 if (YourMediaElementName.CurrentState == MediaElementState.Playing)
 {
     // TODO: when media is playing.
 }
iam.Carrot
  • 4,976
  • 2
  • 24
  • 71
user3714810
  • 127
  • 7
2

And based on Rich S an extension can be implement

//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;
        }
    }
0

For the WPF MediaElement, here is the solution/workaround I use:

bool IsPlaying()
{
    var pos1 = wpfMediaElement.Position;
    System.Threading.Thread.Sleep(1);
    var pos2 = wpfMediaElement.Position;

    return pos2 != pos1;
}
Alex Pigida
  • 117
  • 2
  • 5
  • 10
    That's horrible workaround. If you call this method in UI thread, the whole UI will be forzen. – TcKs Apr 03 '13 at 13:31
  • 1
    I agree, it is not the best methode. But I will bet no one on this world will recognize this one millisecond on small programs. Its an workaround from Alex wich I call quick 'n dirty and for that I will give upvote. Using a hidden HeperProperty by accessing hidden fields is really not a "nice solution" eigther. – Nasenbaer Apr 16 '14 at 07:56
  • nothing wrong with it.. media element not having status property is truly horrible solution... nobody asked you to call it in UI thread either. – Boppity Bop Aug 02 '16 at 16:58
0

if you use MediaElement.CanPause it will determine if your currently playing media can be paused. Allows you to implement a Play/Pause button

var media = (MediaElement)obj;
  if (media.CanPause)
  {
    media.Pause();
  }
  else
  {
    media.Play();
  }
-1

For WPF use this: var playing = player.Position < player.NaturalDuration;