Share via


MediaElement States

Microsoft Silverlight will reach end of support after October 2021. Learn more.

You can detect MediaElement states by using the CurrentState property and detect state changes by using the CurrentStateChanged event. This overview covers the use of these APIs and provides information about the transitions between the different MediaElement states.

This topic contains the following sections.

  • MediaElement States
  • Using CurrentState and CurrentStateChanged
  • State Transition Table
  • Related Topics

MediaElement States

The current state of a MediaElement (Buffering, Closed, Error, Opening, Paused, Playing, or Stopped) can have an impact on users who consume your media. For example, if a user is attempting to view a large video, the MediaElement will likely remain in a state of Buffering for a significant amount of time. In this case, you would want to provide some clue in your user interface (UI) that the media cannot be played yet. When buffering is over, you would want to indicate that the media can now be played.

Using CurrentState and CurrentStateChanged

The following example demonstrates one way to display the CurrentState of a MediaElement. It creates a MediaElement and several buttons for controlling media playback. To display the current state of the MediaElement, the example registers for the CurrentStateChanged event and uses an event handler to update a TextBlock.

Run this sample

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <MediaElement CurrentStateChanged="Media_State_Changed"
        x:Name="media" Source="xbox.wmv" Width="300" Height="300" 
                  Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3" />

    <!-- Stops media playback.-->
    <Button Click="StopMedia" 
     Grid.Column="0" Grid.Row="1" Content="Stop" />

    <!-- Pauses media playback. -->
    <Button Click="PauseMedia" 
     Grid.Column="1" Grid.Row="1" Content="Pause" />

    <!-- Begins media playback. -->
    <Button Click="PlayMedia" 
     Grid.Column="2" Grid.Row="1" Content="Play" />

    <TextBlock
Grid.Column="0" Grid.Row="2" Margin="10" 
FontSize="12">CurrentState:</TextBlock>

    <TextBlock 
x:Name="mediaStateTextBlock"
Grid.Column="1" Grid.Row="2" Margin="0,10,0,0"
FontSize="12"></TextBlock>

</Grid>
Private Sub StopMedia(ByVal sender As Object, ByVal e As RoutedEventArgs)
    media.Stop()
End Sub

Private Sub PauseMedia(ByVal sender As Object, ByVal e As RoutedEventArgs)
    media.Pause()
End Sub

Private Sub PlayMedia(ByVal sender As Object, ByVal e As RoutedEventArgs)
    media.Play()
End Sub
Private Sub Media_State_Changed(ByVal sender As Object, ByVal e As EventArgs)
    mediaStateTextBlock.Text = media.CurrentState.ToString
End Sub
private void StopMedia(object sender, RoutedEventArgs e)
{
    media.Stop();
}
private void PauseMedia(object sender, RoutedEventArgs e)
{
    media.Pause();
}
private void PlayMedia(object sender, RoutedEventArgs e)
{
    media.Play();
}
private void Media_State_Changed(object sender, EventArgs e)
{
    mediaStateTextBlock.Text = media.CurrentState.ToString();
}
NoteNote:

The CurrentStateChanged event may not behave as expected. When state changes rapidly, events might be coalesced into a single raising of the event. For example, the CurrentState property might have switched from Playing to Buffering and back to Playing so rapidly that only a single CurrentStateChanged event was raised, in which case the property will not appear to have changed values. Also, your application should not assume an order in which the events occur, particularly for the transient states such as Buffering. One of the transient states may have been skipped over in event reporting because it happened so rapidly.

State Transition Table

The following table summarizes the different states the MediaElement can be in. These states correspond to the enumeration values of the MediaElementState enumeration.

Value

Description

AcquiringLicense

Only applicable when serving DRM-protected content: The MediaElement is acquiring a license required to play DRM-protected content. After OnAcquireLicense has been called, the MediaElement remains in this state until SetLicenseResponse has been called.

Buffering

The MediaElement is loading the media for playback. Its Position does not advance during this state. If the MediaElement was already playing video, it continues to display the last displayed frame.

Closed

The MediaElement contains no media. The MediaElement displays a transparent frame.

Individualizing

Only applicable when serving DRM-protected content: The MediaElement is in the process of ensuring that proper individualization components (only applicable when playing DRM-protected content) are installed on the user's computer. For more information, see Digital Rights Management (DRM).

Opening

The MediaElement is validating and attempting to open the Uniform Resource Identifier (URI) specified by its Source property.

Paused

The MediaElement does not advance its Position. If the MediaElement was playing video, it continues to display the current frame.

Playing

The MediaElement is playing the media specified by its source property. Its Position advances forward.

Stopped

The MediaElement contains media, but it is not playing or paused. Its Position is 0 and does not advance. If the loaded media is video, the MediaElement displays the first frame.

The following table summarizes these MediaElement states versus the actions taken on the MediaElement (for example, Play method called, Pause method called, and so on).

State

Source set

Play()

Pause()

Stop()

Seek()

Default exit condition

Closed (default)

Opening

No-op

No-op

No-op

No-op

Opening

Opening (new source)

Not specified

Not specified

Not specified

Not specified

If source is valid: Buffering (if AutoPlay == true) or Stopped (if AutoPlay == false) (MediaOpened)

If source is invalid: Opening (MediaFailed)

Buffering

Opening

Playing

Paused

Stopped

Buffering (new position)

BufferingTime is reached: Playing

Playing

Opening

No-op

Paused

Stopped

Buffering (new position)

End of stream: Paused

End of buffer: Buffering

Paused

Opening

Buffering

No-op

Stopped

Paused (new position)

Stopped

Opening

Buffering

Paused

No-op

Paused (new position)

As you can see in the preceding table, the state that is available to the MediaElement depends on its current state. For example, for a MediaElement that is currently in the state of Playing, if the source of the MediaElement is changed, the state changes to Opening; if the Play method is called, nothing happens (no-op); if the Pause method is called, the state changes to Paused, and so on.

The following diagram shows the transitions that can occur on a MediaElement.

MediaElement State Diagram

At stage (1) in the diagram, either the Source property is set, or SetSource is called. The MediaElement then opens the content and, if needed, acquires a license for it. Once those steps are finished, the MediaOpened event is raised. What happens next depends on the properties of the MediaElement:

  • Path (2) is taken if the AutoPlay property is true.

  • Path (3) is taken if the AutoPlay property is false and the CanPause property is true.

  • Path (4) is taken if both those properties are false.

The state may temporarily transition in and out of Buffering (5) if more bytes need to be downloaded for playback to proceed.

Other transitions of interest:

NoteNote:

The CurrentStateChanged event may not behave as expected. When state changes rapidly, events might be coalesced into a single raising of the event. For example, the CurrentState property might have switched from Playing to Buffering and back to Playing so rapidly that only a single CurrentStateChanged event was raised, in which case the property will not appear to have changed values. Also, your application should not assume an order in which the events occur, particularly for the transient states such as Buffering. One of the transient states may have been skipped over in event reporting because it happened so rapidly.

NoteNote:

Avoid "Not specified" states. For example, you should not call the Play method while the media is in the Opening state. To avoid this, you could check the CurrentState of the MediaElement before allowing Play to be called.

The following notes pertain to scenarios from the previous table. Note that the scenario Buffering/Play corresponds to the MediaElement being in a state of Buffering, and then the Play method is called.

  • Buffering/Play: This scenario results in MediaElement going into the Playing state so that the user can leave the Buffering state sooner than the BufferingTime specifies.

  • Playing/Seek: This scenario results in Buffering to ensure that enough of the video stream has been downloaded.

  • [Paused or Stopped]/Play: This scenario results in Buffering to ensure that enough of the media file has been downloaded.