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.
<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();
}
Note: |
---|
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.
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:
From the Stopped state, the MediaElement may transition back to Playing or Paused if the Play or Pause methods are called.
(not shown) From the Playing state, the MediaEnded event may be raised if the media is finished. When this happens, the state may transition to either Stopped or Paused.
Any state can transition to Closed. A MediaFailed event is raised when this happens.
Note: |
---|
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. |
Note: |
---|
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.
See Also