Save the date! Android Dev Summit is coming to Sunnyvale, CA on Oct 23-24, 2019.

SessionPlayer

public abstract class SessionPlayer
extends Object implements AutoCloseable

java.lang.Object
   ↳ androidx.media2.SessionPlayer


Base interface for all media players that want media session.

APIs that return ListenableFuture should be the asynchronous calls and shouldn't block the calling thread. This guarantees the APIs are safe to be called on the main thread.

Topics covered here are:

  1. Best practices
  2. Player states
  3. Invalid method calls

Best practices

Here are best practices when implementing/using SessionPlayer:
  • When updating UI, you should respond to SessionPlayer.PlayerCallback invocations instead of SessionPlayer.PlayerResult objects since the player can be controlled by others.
  • When a SessionPlayer object is no longer being used, call AutoCloseable.close() as soon as possible to release the resources used by the internal player engine associated with the SessionPlayer. For example, if a player uses hardware decoder, other player instances may fallback to software decoders or fail to play. You cannot use SessionPlayer instance after you call AutoCloseable.close(). There is no way to reuse the instance.
  • The current playback position can be retrieved with a call to getCurrentPosition(), which is helpful for applications such as a music player that need to keep track of the playback progress.
  • The playback position can be adjusted with a call to seekTo(long). Although the asynchronous seekTo(long) call returns right away, the actual seek operation may take a while to finish, especially for audio/video being streamed.
  • You can call seekTo(long) from the PLAYER_STATE_PAUSED. In these cases, if you are playing a video stream and the requested position is valid, one video frame may be displayed.

Player states

The playback control of audio/video files is managed as a state machine. The SessionPlayer defines four states:
  1. PLAYER_STATE_IDLE: Initial state after the instantiation.

    While in this state, you should call setMediaItem(MediaItem) or setPlaylist(List, MediaMetadata). Check returned ListenableFuture for potential error.

    Calling prepare() transfers this object to PLAYER_STATE_PAUSED.

  2. PLAYER_STATE_PAUSED: State when the audio/video playback is paused.

    Call play() to resume or start playback from the position where it paused.

  3. PLAYER_STATE_PLAYING: State when the player plays the media item.

    In this state, SessionPlayer.PlayerCallback.onBufferingStateChanged(SessionPlayer, MediaItem, int) will be called regularly to tell the buffering status.

    Playback state would remain PLAYER_STATE_PLAYING when the currently playing media item is changed.

    When the playback reaches the end of stream, the behavior depends on repeat mode, set by setRepeatMode(int). If the repeat mode was set to REPEAT_MODE_NONE, the player will transfer to the PLAYER_STATE_PAUSED. Otherwise, the SessionPlayer object remains in the PLAYER_STATE_PLAYING and playback will be ongoing.

  4. PLAYER_STATE_ERROR: State when the playback failed and player cannot be recovered by itself.

    In general, playback might fail due to various reasons such as unsupported audio/video format, poorly interleaved audio/video, resolution too high, streaming timeout, and others. In addition, due to programming errors, a playback control operation might be performed from an invalid state. In these cases the player may transition to this state.

Invalid method calls

The only method you safely call from the PLAYER_STATE_ERROR is AutoCloseable.close(). Any other methods might throw an exception or return meaningless data.

Subclasses of the SessionPlayer may have extra methods that are safe to be called in the error state and/or provide a method to recover from the error state. Take a look at documentations of specific class that you're interested in.

Most methods can be called from any non-Error state. They will either perform their work or silently have no effect. The following table lists the methods that aren't guaranteed to successfully running if they're called from the associated invalid states.

Method Name Invalid States
setMediaItem {Paused, Playing}
setPlaylist {Paused, Playing}
prepare {Paused, Playing}
play {Idle}
pause {Idle}
seekTo {Idle}

Summary

Nested classes

class SessionPlayer.PlayerCallback

A callback class to receive notifications for events on the session player. 

class SessionPlayer.PlayerResult

Result class of the asynchronous APIs. 

Constants

int BUFFERING_STATE_BUFFERING_AND_PLAYABLE

Buffering state indicating the player is buffering but enough has been buffered for this player to be able to play the content.

int BUFFERING_STATE_BUFFERING_AND_STARVED

Buffering state indicating the player is buffering, but the player is currently starved for data, and cannot play.

int BUFFERING_STATE_COMPLETE

Buffering state indicating the player is done buffering, and the remainder of the content is available for playback.

int BUFFERING_STATE_UNKNOWN

Buffering state is unknown.

int PLAYER_STATE_ERROR

State when the player is in error state and cannot be recovered self.

int PLAYER_STATE_IDLE

State when the player is idle, and needs configuration to start playback.

int PLAYER_STATE_PAUSED

State when the player's playback is paused

int PLAYER_STATE_PLAYING

State when the player's playback is ongoing

int REPEAT_MODE_ALL

Playing media list will be repeated.

int REPEAT_MODE_GROUP

Playback of the playing media group will be repeated.

int REPEAT_MODE_NONE

Playback will be stopped at the end of the playing media list.

int REPEAT_MODE_ONE

Playback of the current playing media item will be repeated.

int SHUFFLE_MODE_ALL

Media list will be played in shuffled order.

int SHUFFLE_MODE_GROUP

Media group will be played in shuffled order.

int SHUFFLE_MODE_NONE

Media list will be played in order.

long UNKNOWN_TIME

Public constructors

SessionPlayer()

Public methods

abstract ListenableFuture<SessionPlayer.PlayerResult> addPlaylistItem(int index, MediaItem item)

Adds the media item to the playlist at position index.

abstract AudioAttributesCompat getAudioAttributes()

Gets the AudioAttributesCompat that media player has.

abstract long getBufferedPosition()

Gets the buffered position of current playback, or UNKNOWN_TIME if unknown.

abstract int getBufferingState()

Returns the current buffering state of the player.

abstract MediaItem getCurrentMediaItem()

Gets the current media item.

abstract int getCurrentMediaItemIndex()

Gets the index of current media item in playlist.

abstract long getCurrentPosition()

Gets the current playback head position.

abstract long getDuration()

Gets the duration of the current media item, or UNKNOWN_TIME if unknown.

abstract int getNextMediaItemIndex()

Gets the next item index in the playlist.

abstract float getPlaybackSpeed()

Gets the actual playback speed to be used by the player when playing.

abstract int getPlayerState()

Gets the current player state.

abstract List<MediaItem> getPlaylist()

Gets the playlist.

abstract MediaMetadata getPlaylistMetadata()

Gets the playlist metadata.

abstract int getPreviousMediaItemIndex()

Gets the previous item index in the playlist.

abstract int getRepeatMode()

Gets the repeat mode.

abstract int getShuffleMode()

Gets the shuffle mode.

abstract ListenableFuture<SessionPlayer.PlayerResult> pause()

Pauses playback.

abstract ListenableFuture<SessionPlayer.PlayerResult> play()

Plays the playback.

abstract ListenableFuture<SessionPlayer.PlayerResult> prepare()

Prepares the media items for playback.

final void registerPlayerCallback(Executor executor, SessionPlayer.PlayerCallback callback)

Register SessionPlayer.PlayerCallback to listen changes.

abstract ListenableFuture<SessionPlayer.PlayerResult> removePlaylistItem(int index)

Removes the media item from the playlist

The implementation may not change the currently playing media item even when it's removed.

abstract ListenableFuture<SessionPlayer.PlayerResult> replacePlaylistItem(int index, MediaItem item)

Replaces the media item at index in the playlist.

abstract ListenableFuture<SessionPlayer.PlayerResult> seekTo(long position)

Seeks to the specified position.

abstract ListenableFuture<SessionPlayer.PlayerResult> setAudioAttributes(AudioAttributesCompat attributes)

Sets the AudioAttributesCompat to be used during the playback of the media.

abstract ListenableFuture<SessionPlayer.PlayerResult> setMediaItem(MediaItem item)

Sets a MediaItem for playback.

abstract ListenableFuture<SessionPlayer.PlayerResult> setPlaybackSpeed(float playbackSpeed)

Sets the playback speed.

abstract ListenableFuture<SessionPlayer.PlayerResult> setPlaylist(List<MediaItem> list, MediaMetadata metadata)

Sets a list of MediaItem with metadata.

abstract ListenableFuture<SessionPlayer.PlayerResult> setRepeatMode(int repeatMode)

Sets the repeat mode.

abstract ListenableFuture<SessionPlayer.PlayerResult> setShuffleMode(int shuffleMode)

Sets the shuffle mode.

abstract ListenableFuture<SessionPlayer.PlayerResult> skipToNextPlaylistItem()

Skips to the next item in the playlist.

abstract ListenableFuture<SessionPlayer.PlayerResult> skipToPlaylistItem(int index)

Skips to the the media item.

abstract ListenableFuture<SessionPlayer.PlayerResult> skipToPreviousPlaylistItem()

Skips to the previous item in the playlist.

final void unregisterPlayerCallback(SessionPlayer.PlayerCallback callback)

Unregister the previously registered SessionPlayer.PlayerCallback.

abstract ListenableFuture<SessionPlayer.PlayerResult> updatePlaylistMetadata(MediaMetadata metadata)

Updates the playlist metadata while keeping the playlist as-is.

Protected methods

final List<Pair<SessionPlayer.PlayerCallback, Executor>> getCallbacks()

Gets the callbacks with executors for subclasses to notify player events.

Inherited methods

Constants

BUFFERING_STATE_BUFFERING_AND_PLAYABLE

public static final int BUFFERING_STATE_BUFFERING_AND_PLAYABLE

Buffering state indicating the player is buffering but enough has been buffered for this player to be able to play the content. See getBufferedPosition() for how far is buffered already.

Constant Value: 1 (0x00000001)

BUFFERING_STATE_BUFFERING_AND_STARVED

public static final int BUFFERING_STATE_BUFFERING_AND_STARVED

Buffering state indicating the player is buffering, but the player is currently starved for data, and cannot play.

Constant Value: 2 (0x00000002)

BUFFERING_STATE_COMPLETE

public static final int BUFFERING_STATE_COMPLETE

Buffering state indicating the player is done buffering, and the remainder of the content is available for playback.

Constant Value: 3 (0x00000003)

BUFFERING_STATE_UNKNOWN

public static final int BUFFERING_STATE_UNKNOWN

Buffering state is unknown.

Constant Value: 0 (0x00000000)

PLAYER_STATE_ERROR

public static final int PLAYER_STATE_ERROR

State when the player is in error state and cannot be recovered self.

Constant Value: 3 (0x00000003)

PLAYER_STATE_IDLE

public static final int PLAYER_STATE_IDLE

State when the player is idle, and needs configuration to start playback.

Constant Value: 0 (0x00000000)

PLAYER_STATE_PAUSED

public static final int PLAYER_STATE_PAUSED

State when the player's playback is paused

Constant Value: 1 (0x00000001)

PLAYER_STATE_PLAYING

public static final int PLAYER_STATE_PLAYING

State when the player's playback is ongoing

Constant Value: 2 (0x00000002)

REPEAT_MODE_ALL

public static final int REPEAT_MODE_ALL

Playing media list will be repeated.

Constant Value: 2 (0x00000002)

REPEAT_MODE_GROUP

public static final int REPEAT_MODE_GROUP

Playback of the playing media group will be repeated. A group is a logical block of media items which is specified in the section 5.7 of the Bluetooth AVRCP 1.6. An example of a group is the playlist.

Constant Value: 3 (0x00000003)

REPEAT_MODE_NONE

public static final int REPEAT_MODE_NONE

Playback will be stopped at the end of the playing media list.

Constant Value: 0 (0x00000000)

REPEAT_MODE_ONE

public static final int REPEAT_MODE_ONE

Playback of the current playing media item will be repeated.

Constant Value: 1 (0x00000001)

SHUFFLE_MODE_ALL

public static final int SHUFFLE_MODE_ALL

Media list will be played in shuffled order.

Constant Value: 1 (0x00000001)

SHUFFLE_MODE_GROUP

public static final int SHUFFLE_MODE_GROUP

Media group will be played in shuffled order. A group is a logical block of media items which is specified in the section 5.7 of the Bluetooth AVRCP 1.6. An example of a group is the playlist.

Constant Value: 2 (0x00000002)

SHUFFLE_MODE_NONE

public static final int SHUFFLE_MODE_NONE

Media list will be played in order.

Constant Value: 0 (0x00000000)

UNKNOWN_TIME

public static final long UNKNOWN_TIME

Constant Value: -1 (0xffffffffffffffff)

Public constructors

SessionPlayer

public SessionPlayer ()

Public methods

addPlaylistItem

public abstract ListenableFuture<SessionPlayer.PlayerResult> addPlaylistItem (int index, 
                MediaItem item)

Adds the media item to the playlist at position index. Index equals or greater than the current playlist size (e.g. Integer.MAX_VALUE) will add the item at the end of the playlist.

The implementation may not change the currently playing media item. If index is less than or equal to the current index of the playlist, the current index of the playlist will be increased correspondingly.

The implementation must notify registered callbacks with SessionPlayer.PlayerCallback.onPlaylistChanged(SessionPlayer, List, MediaMetadata) when it's completed.

Parameters
index int: the index of the item you want to add in the playlist

item MediaItem: the media item you want to add

Returns
ListenableFuture<SessionPlayer.PlayerResult>

getAudioAttributes

public abstract AudioAttributesCompat getAudioAttributes ()

Gets the AudioAttributesCompat that media player has.

Returns
AudioAttributesCompat

getBufferedPosition

public abstract long getBufferedPosition ()

Gets the buffered position of current playback, or UNKNOWN_TIME if unknown.

Returns
long the buffered position in ms, or UNKNOWN_TIME.

getBufferingState

public abstract int getBufferingState ()

Returns the current buffering state of the player. During the buffering, see getBufferedPosition() for the quantifying the amount already buffered.

Returns
int the buffering state.

getCurrentMediaItem

public abstract MediaItem getCurrentMediaItem ()

Gets the current media item.

Returns
MediaItem the current media item. Can be null only when media item or playlist hasn't been set.

getCurrentMediaItemIndex

public abstract int getCurrentMediaItemIndex ()

Gets the index of current media item in playlist. This value may be updated when SessionPlayer.PlayerCallback.onCurrentMediaItemChanged(SessionPlayer, MediaItem) or SessionPlayer.PlayerCallback.onPlaylistChanged(SessionPlayer, List, MediaMetadata) is called.

Returns
int the index of current media item. Can be -1 only when current media item is null or playlist hasn't been set.

getCurrentPosition

public abstract long getCurrentPosition ()

Gets the current playback head position.

Returns
long the current playback position in ms, or UNKNOWN_TIME if unknown.

getDuration

public abstract long getDuration ()

Gets the duration of the current media item, or UNKNOWN_TIME if unknown.

Returns
long the duration in ms, or UNKNOWN_TIME.

getNextMediaItemIndex

public abstract int getNextMediaItemIndex ()

Gets the next item index in the playlist. The returned value can be outdated after SessionPlayer.PlayerCallback.onCurrentMediaItemChanged(SessionPlayer, MediaItem) or SessionPlayer.PlayerCallback.onPlaylistChanged(SessionPlayer, List, MediaMetadata) is called.

Returns
int the index of next media item. Can be -1 only when next media item does not exist or playlist hasn't been set.

getPlaybackSpeed

public abstract float getPlaybackSpeed ()

Gets the actual playback speed to be used by the player when playing.

Note that it may differ from the speed set in setPlaybackSpeed(float).

Returns
float the actual playback speed

getPlayerState

public abstract int getPlayerState ()

Gets the current player state.

Returns
int the current player state

getPlaylist

public abstract List<MediaItem> getPlaylist ()

Gets the playlist.

Returns
List<MediaItem> playlist, or null if none is set.

getPlaylistMetadata

public abstract MediaMetadata getPlaylistMetadata ()

Gets the playlist metadata.

Returns
MediaMetadata metadata metadata of the playlist, or null if none is set

getPreviousMediaItemIndex

public abstract int getPreviousMediaItemIndex ()

Gets the previous item index in the playlist. The returned value can be outdated after SessionPlayer.PlayerCallback.onCurrentMediaItemChanged(SessionPlayer, MediaItem) or SessionPlayer.PlayerCallback.onPlaylistChanged(SessionPlayer, List, MediaMetadata) is called.

Returns
int the index of previous media item. Can be -1 only when previous media item does not exist or playlist hasn't been set.

getRepeatMode

public abstract int getRepeatMode ()

Gets the repeat mode.

Returns
int repeat mode

getShuffleMode

public abstract int getShuffleMode ()

Gets the shuffle mode.

Returns
int The shuffle mode

pause

public abstract ListenableFuture<SessionPlayer.PlayerResult> pause ()

Pauses playback.

Returns
ListenableFuture<SessionPlayer.PlayerResult>

play

public abstract ListenableFuture<SessionPlayer.PlayerResult> play ()

Plays the playback.

Returns
ListenableFuture<SessionPlayer.PlayerResult>

prepare

public abstract ListenableFuture<SessionPlayer.PlayerResult> prepare ()

Prepares the media items for playback. During this time, the player may allocate resources required to play, such as audio and video decoders.

Returns
ListenableFuture<SessionPlayer.PlayerResult>

registerPlayerCallback

public final void registerPlayerCallback (Executor executor, 
                SessionPlayer.PlayerCallback callback)

Register SessionPlayer.PlayerCallback to listen changes.

Parameters
executor Executor: a callback Executor

callback SessionPlayer.PlayerCallback: a PlayerCallback

Throws
IllegalArgumentException if executor or callback is null.

removePlaylistItem

public abstract ListenableFuture<SessionPlayer.PlayerResult> removePlaylistItem (int index)

Removes the media item from the playlist

The implementation may not change the currently playing media item even when it's removed.

The implementation must notify registered callbacks with SessionPlayer.PlayerCallback.onPlaylistChanged(SessionPlayer, List, MediaMetadata) when it's completed.

Parameters
index int: the index of the item you want to remove in the playlist

Returns
ListenableFuture<SessionPlayer.PlayerResult>

replacePlaylistItem

public abstract ListenableFuture<SessionPlayer.PlayerResult> replacePlaylistItem (int index, 
                MediaItem item)

Replaces the media item at index in the playlist. This can be also used to update metadata of an item.

The implementation must notify registered callbacks with SessionPlayer.PlayerCallback.onPlaylistChanged(SessionPlayer, List, MediaMetadata) when it's completed.

Parameters
index int: the index of the item to replace in the playlist

item MediaItem: the new item

Returns
ListenableFuture<SessionPlayer.PlayerResult>

seekTo

public abstract ListenableFuture<SessionPlayer.PlayerResult> seekTo (long position)

Seeks to the specified position. Moves the playback head to the specified position.

Parameters
position long: the new playback position in ms. The value should be in the range of start and end positions defined in MediaItem.

Returns
ListenableFuture<SessionPlayer.PlayerResult>

setAudioAttributes

public abstract ListenableFuture<SessionPlayer.PlayerResult> setAudioAttributes (AudioAttributesCompat attributes)

Sets the AudioAttributesCompat to be used during the playback of the media.

You must call this method in PLAYER_STATE_IDLE in order for the audio attributes to become effective thereafter.

Parameters
attributes AudioAttributesCompat: non-null AudioAttributes.

Returns
ListenableFuture<SessionPlayer.PlayerResult>

setMediaItem

public abstract ListenableFuture<SessionPlayer.PlayerResult> setMediaItem (MediaItem item)

Sets a MediaItem for playback.

It's recommended to fill MediaMetadata in each MediaItem especially for the duration information with the key MediaMetadata.METADATA_KEY_DURATION. Without the duration information in the metadata, session will do extra work to get the duration and send it to the controller.

The implementation must notify registered callbacks with SessionPlayer.PlayerCallback.onPlaylistChanged(SessionPlayer, List, MediaMetadata) when it's completed.

Parameters
item MediaItem: the descriptor of media item you want to play

Returns
ListenableFuture<SessionPlayer.PlayerResult> a ListenableFuture which represents the pending completion of the command.

Throws
IllegalArgumentException if the given item is null.

setPlaybackSpeed

public abstract ListenableFuture<SessionPlayer.PlayerResult> setPlaybackSpeed (float playbackSpeed)

Sets the playback speed. A value of 1.0f is the default playback value.

After changing the playback speed, it is recommended to query the actual speed supported by the player, see getPlaybackSpeed().

Parameters
playbackSpeed float: playback speed

Returns
ListenableFuture<SessionPlayer.PlayerResult>

setPlaylist

public abstract ListenableFuture<SessionPlayer.PlayerResult> setPlaylist (List<MediaItem> list, 
                MediaMetadata metadata)

Sets a list of MediaItem with metadata. Ensure uniqueness of each MediaItem in the playlist so the session can uniquely identity individual items. All MediaItems shouldn't be null as well.

It's recommended to fill MediaMetadata in each MediaItem especially for the duration information with the key MediaMetadata.METADATA_KEY_DURATION. Without the duration information in the metadata, session will do extra work to get the duration and send it to the controller.

The implementation must notify registered callbacks with SessionPlayer.PlayerCallback.onPlaylistChanged(SessionPlayer, List, MediaMetadata) when it's completed.

Parameters
list List: A list of MediaItem objects to set as a play list.

metadata MediaMetadata

Returns
ListenableFuture<SessionPlayer.PlayerResult> a ListenableFuture which represents the pending completion of the command.

Throws
IllegalArgumentException if the given list is null or empty, or has duplicated media items.

setRepeatMode

public abstract ListenableFuture<SessionPlayer.PlayerResult> setRepeatMode (int repeatMode)

Sets the repeat mode.

The implementation must notify registered callbacks with SessionPlayer.PlayerCallback.onRepeatModeChanged(SessionPlayer, int) when it's completed.

Parameters
repeatMode int: repeat mode

Returns
ListenableFuture<SessionPlayer.PlayerResult>

setShuffleMode

public abstract ListenableFuture<SessionPlayer.PlayerResult> setShuffleMode (int shuffleMode)

Sets the shuffle mode.

The implementation must notify registered callbacks with SessionPlayer.PlayerCallback.onShuffleModeChanged(SessionPlayer, int) when it's completed.

Parameters
shuffleMode int: The shuffle mode

Returns
ListenableFuture<SessionPlayer.PlayerResult>

skipToNextPlaylistItem

public abstract ListenableFuture<SessionPlayer.PlayerResult> skipToNextPlaylistItem ()

Skips to the next item in the playlist.

The implementation must notify registered callbacks with SessionPlayer.PlayerCallback.onCurrentMediaItemChanged(SessionPlayer, MediaItem) when it's completed.

Returns
ListenableFuture<SessionPlayer.PlayerResult>

skipToPlaylistItem

public abstract ListenableFuture<SessionPlayer.PlayerResult> skipToPlaylistItem (int index)

Skips to the the media item.

The implementation must notify registered callbacks with SessionPlayer.PlayerCallback.onCurrentMediaItemChanged(SessionPlayer, MediaItem) when it's completed.

Parameters
index int: The index of the item you want to play in the playlist

Returns
ListenableFuture<SessionPlayer.PlayerResult>

skipToPreviousPlaylistItem

public abstract ListenableFuture<SessionPlayer.PlayerResult> skipToPreviousPlaylistItem ()

Skips to the previous item in the playlist.

The implementation must notify registered callbacks with SessionPlayer.PlayerCallback.onCurrentMediaItemChanged(SessionPlayer, MediaItem) when it's completed.

Returns
ListenableFuture<SessionPlayer.PlayerResult>

unregisterPlayerCallback

public final void unregisterPlayerCallback (SessionPlayer.PlayerCallback callback)

Unregister the previously registered SessionPlayer.PlayerCallback.

Parameters
callback SessionPlayer.PlayerCallback: the callback to be removed

Throws
IllegalArgumentException if the callback is null.

updatePlaylistMetadata

public abstract ListenableFuture<SessionPlayer.PlayerResult> updatePlaylistMetadata (MediaMetadata metadata)

Updates the playlist metadata while keeping the playlist as-is.

The implementation must notify registered callbacks with SessionPlayer.PlayerCallback.onPlaylistMetadataChanged(SessionPlayer, MediaMetadata) when it's completed.

Parameters
metadata MediaMetadata: metadata of the playlist

Returns
ListenableFuture<SessionPlayer.PlayerResult>

Protected methods

getCallbacks

protected final List<Pair<SessionPlayer.PlayerCallback, Executor>> getCallbacks ()

Gets the callbacks with executors for subclasses to notify player events.

Returns
List<Pair<SessionPlayer.PlayerCallback, Executor>> map of callbacks and its executors