Skip to main content
Version: 7.2.0

How to track player states

A video player has states. As a developer, you should understand these states, as each state grants you access to different data, and might imply a re-render of your UI. For example, if your video player is in the "Paused" state, you want to show a play-button instead of a pause-button.

The objective of this guide is to define some video player states, and how to track the transition between states.

Although there's no official list of video player states, we'll define 11 states for learning purposes. These 11 states are visualized in the state diagram below.

Video Player States

The table below provides the definitions of these 11 states.

StateDescription
A: EmptyA state where the player is created, but has no information or data retained on the source which is to be played. The player is idle and not undertaking any interaction with the system.
B: InitializedA state where the player knows the source which is to be played, but no media data is loaded. The player is idle and not undertaking any interaction with the system.
C: Playing - HAVE_NOTHINGA state where the player wants to start playing a source, but has no media data available. The player is actively loading media data in order to initiate playback.
D: Paused - HAVE_NOTHINGA state where the player wants to fill its buffer without playing, but has no media data available. The player is actively loading media data in order to fill its buffer.
E: Playing - HAVE_METADATAA state where the player wants to start playing a source, but only metadata is available and the entire buffer is still empty. The player knows which tracks and qualities are available. The player is actively loading media data in order to initiate playback.
F: Paused - HAVE_METADATAA state where the player wants to fill its buffer without playing, but only metadata is available and the entire buffer is still empty. The player knows which tracks and qualities are available. The player is actively loading media data in order to fill its buffer.
G: Playing - HAVE_CURRENT_DATAA state where the player wants to start playing a source and has media data in its buffer for the current timestamp, but this data is insufficient to start playback and guarantee a smooth viewer experience. The player is actively loading media data in order to initiate playback.
H: Paused - HAVE_CURRENT_DATAA state where the player wants to fill its buffer without playing and has media data in the buffer for the current timestamp, but this data is insufficient to start playback and guarantee a smooth viewer experience. The player is actively loading media data in order to fill its buffer.
I: PlayingA state where the player is actively rendering out media data. The current timestamp is progressing at the speed of the current playback rate and media buffer data is being consumed and loaded in parallel. timeupdate events will be dispatched regularly during playback and progress events will be dispatched as additional data is loaded.
J: PausedA state where the player has sufficient media data in its buffer in order to guarantee a smooth viewer experience when playback is started, but it is in a paused state. The player is not consuming any media data, but might be loading additional media data to grow its buffer in the background.
K: ErrorA state where the player has observed a fatal, non recoverable error. The player cannot continue playback and needs to be initialized again in order to restart playback. A player can get into this state from any state other than the Empty-state.

The table below explains what triggers each of the 26 transitions between states, and what video player events are related.

TransitionTriggersEvents
1new THEOplayer.Player
2player.source = Xsourcechange, currentsourcechange
3player.play()play, loadstart
4player.load()loadstart
5player.pause()pause
6player.play()play
7The stream manifest being loadedreadystatechange, loadedmetadata, durationchange
8The stream manifest being loadedreadystatechange, loadedmetadata, durationchange
9player.pause()pause
10player.play()play
11Stream media data is loadedreadystatechange, loadeddata, progress, canplay
12Stream media data is loadedreadystatechange, loadeddata, progress, canplay
13player.pause()pause
14player.play()play
15Sufficient media data is loaded to start playback fluently.progress, canplaythrough, readystatechange, playing
A seeked event can be dispatched if the entrance of this state was caused by a seek.
16Sufficient media data is loaded to start playback fluently.canplaythrough, readystatechange
A seeked event can be dispatched if the entrance of this state was caused by a seek.
17player.pause()pause
18player.play()play, playing
19player.currentTime = X and there is some media data at the target time, but not enough to play fluently.seeking, readystatechange
20The player buffer is not being filled enough, causing a stall.waiting, readystatechange
21player.currentTime = X and there is no media data at the target time.seeking, readystatechange
22Playback has ended.ended, readystatechange
23player.currentTime = X and there is some media data at the target time, but not enough to play fluently.seeking, readystatechange
24player.currentTime = X and there is no media data at the target time.seeking, readystatechange
25An error occurred.error
26player.source = nullemptied

Implementation

The following code samples demonstrate how you track some of the 18 events related to the state transitions across different SDKs.

  • sourcechange
  • currentsourcechange
  • play
  • loadstart
  • pause
  • readystatechange
  • loadedmetadata
  • durationchange
  • loadeddata
  • progress
  • canplay
  • canplaythrough
  • playing
  • waiting
  • seeking
  • ended
  • error
  • emptied

All 18 events are dispatched by the Player interface.

Web SDK

The snippet below demonstrates how you can track some of the related events through the THEOplayer Web SDK. All other events can be tracked similarly. You can find the event names in the PlayerEventMap API reference. This approach is valid for all web-based platforms, including Tizen and webOS.

player.addEventListener("sourcechange", (event) => {
console.log(event);
});
// ...
player.addEventListener("ended", (event) => {
console.log(event);
});

Android SDK

The snippet below demonstrates how you can track some of the related events through the THEOplayer Android SDK. All other events can be tracked similarly. You can find the event names in the PlayerEventTypes API reference. This approach is valid for all Android-based platforms, including Android TV and Fire TV.

player.addEventListener(PlayerEventTypes.SOURCECHANGE, event -> {
System.out.println(event);
});
// ...
player.addEventListener(PlayerEventTypes.ENDED, event -> {
System.out.println(event);
});

iOS/tvOS SDK and Legacy iOS/tvOS SDK (4.12.x)

The snippet below demonstrates how you can track some of the related events through the THEOplayer iOS SDK. All other events can be tracked similarly. You can find the event names in the PlayerEventTypes API reference. This approach is valid for all iOS-based platforms, including iPadOS and tvOS.

player?.addEventListener(type: PlayerEventTypes.SOURCE_CHANGE, listener: { (event) in
print(event)
})
// ...
player?.addEventListener(type: PlayerEventTypes.ENDED, listener: { (event) in
print(event)
})

Roku SDK

This subsection is in maintenance. Reach out to our team if you require help.