Join us on the livestream at Android Dev Summit on 7-8 November 2018, starting at 10AM PDT!

MediaSession2

public class MediaSession2
extends Object implements AutoCloseable

java.lang.Object
   ↳ androidx.media2.MediaSession2


Allows a media app to expose its transport controls and playback information in a process to other processes including the Android framework and other apps. Common use cases are as follows.

  • Bluetooth/wired headset key events support
  • Android Auto/Wearable support
  • Separating UI process and playback process

A MediaSession2 should be created when an app wants to publish media playback information or handle media keys. In general an app only needs one session for all playback, though multiple sessions can be created to provide finer grain controls of media.

If you want to support background playback, MediaSessionService2 is preferred instead. With it, your playback can be revived even after playback is finished. See MediaSessionService2 for details.

Topic covered here:

  1. Session Lifecycle
  2. Audio focus and noisy intent
  3. Thread
  4. Media key events mapping

Session Lifecycle

A session can be obtained by MediaSession2.Builder. The owner of the session may pass its session token to other processes to allow them to create a MediaController2 to interact with the session.

When a session receive transport control commands, the session sends the commands directly to the the underlying media player set by MediaSession2.Builder or updatePlayerConnector(MediaPlayerConnector, MediaPlaylistAgent).

When an app is finished performing playback it must call close() to clean up the session and notify any controllers.

Audio focus and noisy intent

MediaSession2 handles audio focus and noisy intent with AudioAttributesCompat set to the underlying MediaPlayerConnector by default. You need to set the audio attribute before the session is created, and playback started with the session.

Here's the table of automatic audio focus behavior with audio attributes.

Audio AttributesAudio Focus Gain TypeMisc
AudioAttributesCompat.USAGE_VOICE_COMMUNICATION_SIGNALLING AudioManager.AUDIOFOCUS_NONE
AudioManager.AUDIOFOCUS_GAIN Developers should specific a proper usage instead of AudioAttributesCompat.USAGE_UNKNOWN
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE
AudioAttributesCompat.USAGE_ASSISTANCE_ACCESSIBILITY AudioManager.AUDIOFOCUS_GAIN_TRANSIENT if AudioAttributesCompat.CONTENT_TYPE_SPEECH, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK otherwise
null No audio focus handling, and sets the player volume to 0 Only valid if your media contents don't have audio
Any other AudioAttributes No audio focus handling, and sets the player volume to 0 This is to handle error

For more information about the audio focus, take a look at Managing audio focus

Thread

MediaSession2 objects are thread safe, but should be used on the thread on the looper.

Media key events mapping

Here's the table of per key event.

Key codeMediaSession2 API
KeyEvent.KEYCODE_MEDIA_PLAY play()
KeyEvent.KEYCODE_MEDIA_PAUSE pause()
KeyEvent.KEYCODE_MEDIA_NEXT skipToNextItem()
KeyEvent.KEYCODE_MEDIA_PREVIOUS skipToPreviousItem()
KeyEvent.KEYCODE_MEDIA_STOP pause() and then seekTo(long) with 0
KeyEvent.KEYCODE_MEDIA_FAST_FORWARD MediaSession2.SessionCallback.onFastForward(MediaSession2, MediaSession2.ControllerInfo)
KeyEvent.KEYCODE_MEDIA_REWIND MediaSession2.SessionCallback.onRewind(MediaSession2, MediaSession2.ControllerInfo)

Summary

Nested classes

class MediaSession2.Builder

Builder for MediaSession2

class MediaSession2.CommandButton

Button for a SessionCommand2 that will be shown by the controller. 

class MediaSession2.ControllerInfo

Information of a controller. 

interface MediaSession2.OnDataSourceMissingHelper

Interface definition of a callback to be invoked when a MediaItem2 in the playlist didn't have a DataSourceDesc2 but it's needed now for preparing or playing it. 

class MediaSession2.SessionCallback

Callback to be called for all incoming commands from MediaController2s. 

Constants

int ERROR_CODE_ACTION_ABORTED

Error code when the action is interrupted due to some external event.

int ERROR_CODE_APP_ERROR

Error code when the application state is invalid to fulfill the request.

int ERROR_CODE_AUTHENTICATION_EXPIRED

Error code when the request cannot be performed because authentication has expired.

int ERROR_CODE_CONCURRENT_STREAM_LIMIT

Error code when too many concurrent streams are detected.

int ERROR_CODE_CONTENT_ALREADY_PLAYING

Error code when the requested content is already playing.

int ERROR_CODE_END_OF_QUEUE

Error code when the playback navigation (previous, next) is not possible because the queue was exhausted.

int ERROR_CODE_NOT_AVAILABLE_IN_REGION

Error code when the content is blocked due to being regionally unavailable.

int ERROR_CODE_NOT_SUPPORTED

Error code when the request is not supported by the application.

int ERROR_CODE_PARENTAL_CONTROL_RESTRICTED

Error code when the content is blocked due to parental controls.

int ERROR_CODE_PREMIUM_ACCOUNT_REQUIRED

Error code when a premium account is required for the request to succeed.

int ERROR_CODE_SETUP_REQUIRED

Error code when the session needs user's manual intervention.

int ERROR_CODE_SKIP_LIMIT_REACHED

Error code when the application cannot skip any more songs because skip limit is reached.

int ERROR_CODE_UNKNOWN_ERROR

This is the default error code and indicates that none of the other error codes applies.

Public methods

void addPlaylistItem(int index, MediaItem2 item)

Adds the media item to the playlist at position index.

void clearOnDataSourceMissingHelper()

Clears the data source missing helper.

void close()
long getBufferedPosition()

Gets the buffered position, or MediaPlayerConnector.UNKNOWN_TIME if unknown.

int getBufferingState()

Gets the current buffering state of the player.

List<MediaSession2.ControllerInfo> getConnectedControllers()

Returns the list of connected controller.

MediaItem2 getCurrentMediaItem()

Return currently playing media item.

long getCurrentPosition()

Gets the current position.

long getDuration()

Gets the duration of the currently playing media item.

float getPlaybackSpeed()

Get the playback speed.

MediaPlayerConnector getPlayerConnector()
int getPlayerState()

Gets the current player state.

List<MediaItem2> getPlaylist()

Returns the playlist from the MediaPlaylistAgent.

MediaPlaylistAgent getPlaylistAgent()
MediaMetadata2 getPlaylistMetadata()

Gets the playlist metadata from the MediaPlaylistAgent.

int getRepeatMode()

Gets the repeat mode from the MediaPlaylistAgent.

int getShuffleMode()

Gets the shuffle mode from the MediaPlaylistAgent.

SessionToken2 getToken()

Returns the SessionToken2 for creating MediaController2.

void notifyError(int errorCode, Bundle extras)

Notify errors to the connected controllers

void notifyRoutesInfoChanged(MediaSession2.ControllerInfo controller, List<Bundle> routes)

Notify routes information to a connected controller

void pause()

Pause playback.

void play()

Play playback.

void prepare()

Request that the player prepare its playback.

void removePlaylistItem(MediaItem2 item)

Removes the media item in the playlist.

void replacePlaylistItem(int index, MediaItem2 item)

Replaces the media item at index in the playlist.

void reset()

Stop playback, and reset the player to the initial state.

void seekTo(long pos)

Move to a new location in the media stream.

void sendCustomCommand(SessionCommand2 command, Bundle args)

Send custom command to all connected controllers.

void sendCustomCommand(MediaSession2.ControllerInfo controller, SessionCommand2 command, Bundle args, ResultReceiver receiver)

Send custom command to a specific controller.

void setAllowedCommands(MediaSession2.ControllerInfo controller, SessionCommandGroup2 commands)

Set the new allowed command group for the controller

void setCustomLayout(MediaSession2.ControllerInfo controller, List<MediaSession2.CommandButton> layout)

Sets ordered list of MediaSession2.CommandButton for controllers to build UI with it.

void setOnDataSourceMissingHelper(MediaSession2.OnDataSourceMissingHelper helper)

Sets the data source missing helper.

void setPlaybackSpeed(float speed)

Set the playback speed.

void setPlaylist(List<MediaItem2> list, MediaMetadata2 metadata)

Sets a list of MediaItem2 to the MediaPlaylistAgent.

void setRepeatMode(int repeatMode)

Sets the repeat mode to the MediaPlaylistAgent.

void setShuffleMode(int shuffleMode)

Sets the shuffle mode to the MediaPlaylistAgent.

void skipToNextItem()

Skips to the next item.

void skipToPlaylistItem(MediaItem2 item)

Skips to the item in the playlist.

void skipToPreviousItem()

Skips to the previous item.

void updatePlayerConnector(MediaPlayerConnector player, MediaPlaylistAgent playlistAgent)

Sets the underlying MediaPlayerConnector and MediaPlaylistAgent for this session to dispatch incoming event to.

void updatePlaylistMetadata(MediaMetadata2 metadata)

Updates the playlist metadata to the MediaPlaylistAgent.

Inherited methods

Constants

ERROR_CODE_ACTION_ABORTED

public static final int ERROR_CODE_ACTION_ABORTED

Error code when the action is interrupted due to some external event.

Constant Value: 10 (0x0000000a)

ERROR_CODE_APP_ERROR

public static final int ERROR_CODE_APP_ERROR

Error code when the application state is invalid to fulfill the request.

Constant Value: 1 (0x00000001)

ERROR_CODE_AUTHENTICATION_EXPIRED

public static final int ERROR_CODE_AUTHENTICATION_EXPIRED

Error code when the request cannot be performed because authentication has expired.

Constant Value: 3 (0x00000003)

ERROR_CODE_CONCURRENT_STREAM_LIMIT

public static final int ERROR_CODE_CONCURRENT_STREAM_LIMIT

Error code when too many concurrent streams are detected.

Constant Value: 5 (0x00000005)

ERROR_CODE_CONTENT_ALREADY_PLAYING

public static final int ERROR_CODE_CONTENT_ALREADY_PLAYING

Error code when the requested content is already playing.

Constant Value: 8 (0x00000008)

ERROR_CODE_END_OF_QUEUE

public static final int ERROR_CODE_END_OF_QUEUE

Error code when the playback navigation (previous, next) is not possible because the queue was exhausted.

Constant Value: 11 (0x0000000b)

ERROR_CODE_NOT_AVAILABLE_IN_REGION

public static final int ERROR_CODE_NOT_AVAILABLE_IN_REGION

Error code when the content is blocked due to being regionally unavailable.

Constant Value: 7 (0x00000007)

ERROR_CODE_NOT_SUPPORTED

public static final int ERROR_CODE_NOT_SUPPORTED

Error code when the request is not supported by the application.

Constant Value: 2 (0x00000002)

ERROR_CODE_PARENTAL_CONTROL_RESTRICTED

public static final int ERROR_CODE_PARENTAL_CONTROL_RESTRICTED

Error code when the content is blocked due to parental controls.

Constant Value: 6 (0x00000006)

ERROR_CODE_PREMIUM_ACCOUNT_REQUIRED

public static final int ERROR_CODE_PREMIUM_ACCOUNT_REQUIRED

Error code when a premium account is required for the request to succeed.

Constant Value: 4 (0x00000004)

ERROR_CODE_SETUP_REQUIRED

public static final int ERROR_CODE_SETUP_REQUIRED

Error code when the session needs user's manual intervention.

Constant Value: 12 (0x0000000c)

ERROR_CODE_SKIP_LIMIT_REACHED

public static final int ERROR_CODE_SKIP_LIMIT_REACHED

Error code when the application cannot skip any more songs because skip limit is reached.

Constant Value: 9 (0x00000009)

ERROR_CODE_UNKNOWN_ERROR

public static final int ERROR_CODE_UNKNOWN_ERROR

This is the default error code and indicates that none of the other error codes applies.

Constant Value: 0 (0x00000000)

Public methods

addPlaylistItem

public void addPlaylistItem (int index, 
                MediaItem2 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.

This will not change the currently playing media item. If index is less than or equal to the current index of the play list, the current index of the play list will be incremented correspondingly.

Parameters
index int: the index you want to add

item MediaItem2: the media item you want to add

clearOnDataSourceMissingHelper

public void clearOnDataSourceMissingHelper ()

Clears the data source missing helper.

close

public void close ()

getBufferedPosition

public long getBufferedPosition ()

Gets the buffered position, or MediaPlayerConnector.UNKNOWN_TIME if unknown.

Returns
long the buffered position in ms, or MediaPlayerConnector.UNKNOWN_TIME.

getBufferingState

public int getBufferingState ()

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

Returns
int the buffering state.

getConnectedControllers

public List<MediaSession2.ControllerInfo> getConnectedControllers ()

Returns the list of connected controller.

Returns
List<MediaSession2.ControllerInfo> list of MediaSession2.ControllerInfo

getCurrentMediaItem

public MediaItem2 getCurrentMediaItem ()

Return currently playing media item.

Returns
MediaItem2 currently playing media item

getCurrentPosition

public long getCurrentPosition ()

Gets the current position.

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

getDuration

public long getDuration ()

Gets the duration of the currently playing media item.

Returns
long the duration of the current item from MediaPlayerConnector.getDuration().

getPlaybackSpeed

public float getPlaybackSpeed ()

Get the playback speed.

Returns
float speed

getPlayerConnector

public MediaPlayerConnector getPlayerConnector ()

Returns
MediaPlayerConnector player. Can be null if and only if the session is released.

getPlayerState

public int getPlayerState ()

Gets the current player state.

Returns
int the current player state

getPlaylist

public List<MediaItem2> getPlaylist ()

Returns the playlist from the MediaPlaylistAgent.

This list may differ with the list that was specified with setPlaylist(List, MediaMetadata2) depending on the MediaPlaylistAgent implementation. Use media items returned here for other playlist agent APIs such as MediaPlaylistAgent.skipToPlaylistItem(MediaItem2).

Returns
List<MediaItem2> playlist

getPlaylistAgent

public MediaPlaylistAgent getPlaylistAgent ()

Returns
MediaPlaylistAgent playlist agent

getPlaylistMetadata

public MediaMetadata2 getPlaylistMetadata ()

Gets the playlist metadata from the MediaPlaylistAgent.

Returns
MediaMetadata2 the playlist metadata

getRepeatMode

public int getRepeatMode ()

Gets the repeat mode from the MediaPlaylistAgent.

Returns
int repeat mode

getShuffleMode

public int getShuffleMode ()

Gets the shuffle mode from the MediaPlaylistAgent.

Returns
int The shuffle mode

getToken

public SessionToken2 getToken ()

Returns the SessionToken2 for creating MediaController2.

Returns
SessionToken2

notifyError

public void notifyError (int errorCode, 
                Bundle extras)

Notify errors to the connected controllers

Parameters
errorCode int: error code

extras Bundle: extras

notifyRoutesInfoChanged

public void notifyRoutesInfoChanged (MediaSession2.ControllerInfo controller, 
                List<Bundle> routes)

Notify routes information to a connected controller

Parameters
controller MediaSession2.ControllerInfo: controller information

routes List: The routes information

pause

public void pause ()

Pause playback.

This calls MediaPlayerConnector.pause().

play

public void play ()

Play playback.

This calls MediaPlayerConnector.play().

prepare

public void prepare ()

Request that the player prepare its playback. In other words, other sessions can continue to play during the preparation of this session. This method can be used to speed up the start of the playback. Once the preparation is done, the session will change its playback state to MediaPlayerConnector.PLAYER_STATE_PAUSED. Afterwards, play() can be called to start playback.

This calls MediaPlayerConnector.reset().

removePlaylistItem

public void removePlaylistItem (MediaItem2 item)

Removes the media item in the playlist.

If the item is the currently playing item of the playlist, current playback will be stopped and playback moves to next source in the list.

Parameters
item MediaItem2: the media item you want to add

replacePlaylistItem

public void replacePlaylistItem (int index, 
                MediaItem2 item)

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

Parameters
index int: the index of the item to replace

item MediaItem2: the new item

reset

public void reset ()

Stop playback, and reset the player to the initial state.

This calls MediaPlayerConnector.reset().

seekTo

public void seekTo (long pos)

Move to a new location in the media stream.

Parameters
pos long: Position to move to, in milliseconds.

sendCustomCommand

public void sendCustomCommand (SessionCommand2 command, 
                Bundle args)

Send custom command to all connected controllers.

Parameters
command SessionCommand2: a command

args Bundle: optional argument

sendCustomCommand

public void sendCustomCommand (MediaSession2.ControllerInfo controller, 
                SessionCommand2 command, 
                Bundle args, 
                ResultReceiver receiver)

Send custom command to a specific controller.

Parameters
controller MediaSession2.ControllerInfo

command SessionCommand2: a command

args Bundle: optional argument

receiver ResultReceiver: result receiver for the session

setAllowedCommands

public void setAllowedCommands (MediaSession2.ControllerInfo controller, 
                SessionCommandGroup2 commands)

Set the new allowed command group for the controller

Parameters
controller MediaSession2.ControllerInfo: controller to change allowed commands

commands SessionCommandGroup2: new allowed commands

setCustomLayout

public void setCustomLayout (MediaSession2.ControllerInfo controller, 
                List<MediaSession2.CommandButton> layout)

Sets ordered list of MediaSession2.CommandButton for controllers to build UI with it.

It's up to controller's decision how to represent the layout in its own UI. Here's the same way (layout[i] means a CommandButton at index i in the given list) For 5 icons row layout[3] layout[1] layout[0] layout[2] layout[4] For 3 icons row layout[1] layout[0] layout[2] For 5 icons row with overflow icon (can show +5 extra buttons with overflow button) expanded row: layout[5] layout[6] layout[7] layout[8] layout[9] main row: layout[3] layout[1] layout[0] layout[2] layout[4]

This API can be called in the MediaSession2.SessionCallback.onConnect(MediaSession2, ControllerInfo).

Parameters
controller MediaSession2.ControllerInfo: controller to specify layout.

layout List: ordered list of layout.

setOnDataSourceMissingHelper

public void setOnDataSourceMissingHelper (MediaSession2.OnDataSourceMissingHelper helper)

Sets the data source missing helper. Helper will be used to provide default implementation of MediaPlaylistAgent when it isn't set by developer.

Default implementation of the MediaPlaylistAgent will call helper when a MediaItem2 in the playlist doesn't have a DataSourceDesc2. This may happen when

If it's not set, playback wouldn't happen for the item without data source descriptor.

The helper will be run on the executor that was specified by MediaSession2.Builder.setSessionCallback(Executor, SessionCallback).

Parameters
helper MediaSession2.OnDataSourceMissingHelper: a data source missing helper.

Throws
IllegalStateException when the helper is set when the playlist agent is set

setPlaybackSpeed

public void setPlaybackSpeed (float speed)

Set the playback speed.

Parameters
speed float

setPlaylist

public void setPlaylist (List<MediaItem2> list, 
                MediaMetadata2 metadata)

Sets a list of MediaItem2 to the MediaPlaylistAgent. Ensure uniqueness of each MediaItem2 in the playlist so the session can uniquely identity individual items.

This may be an asynchronous call, and MediaPlaylistAgent may keep the copy of the list. Wait for MediaSession2.SessionCallback.onPlaylistChanged(MediaSession2, MediaPlaylistAgent, List, MediaMetadata2) to know the operation finishes.

You may specify a MediaItem2 without DataSourceDesc2. In that case, MediaPlaylistAgent has responsibility to dynamically query {link DataSourceDesc2} when such media item is ready for preparation or play. Default implementation needs MediaSession2.OnDataSourceMissingHelper for such case.

It's recommended to fill MediaMetadata2 in each MediaItem2 especially for the duration information with the key MediaMetadata2.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.

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

metadata MediaMetadata2

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

setRepeatMode

public void setRepeatMode (int repeatMode)

Sets the repeat mode to the MediaPlaylistAgent.

Parameters
repeatMode int: repeat mode

setShuffleMode

public void setShuffleMode (int shuffleMode)

Sets the shuffle mode to the MediaPlaylistAgent.

Parameters
shuffleMode int: The shuffle mode

skipToNextItem

public void skipToNextItem ()

Skips to the next item.

This calls MediaPlaylistAgent.skipToNextItem() and the behavior depends on the playlist agent implementation, especially with the shuffle/repeat mode.

skipToPlaylistItem

public void skipToPlaylistItem (MediaItem2 item)

Skips to the item in the playlist.

This calls MediaPlaylistAgent.skipToPlaylistItem(MediaItem2) and the behavior depends on the playlist agent implementation, especially with the shuffle/repeat mode.

Parameters
item MediaItem2: The item in the playlist you want to play

skipToPreviousItem

public void skipToPreviousItem ()

Skips to the previous item.

This calls MediaPlaylistAgent.skipToPreviousItem() and the behavior depends on the playlist agent implementation, especially with the shuffle/repeat mode.

updatePlayerConnector

public void updatePlayerConnector (MediaPlayerConnector player, 
                MediaPlaylistAgent playlistAgent)

Sets the underlying MediaPlayerConnector and MediaPlaylistAgent for this session to dispatch incoming event to.

When a MediaPlaylistAgent is specified here, the playlist agent should manage MediaPlayerConnector for calling MediaPlayerConnector.setNextDataSources(List).

If the MediaPlaylistAgent isn't set, session will recreate the default playlist agent.

Parameters
player MediaPlayerConnector: a MediaPlayerConnector that handles actual media playback in your app

playlistAgent MediaPlaylistAgent: a MediaPlaylistAgent that manages playlist of the player

updatePlaylistMetadata

public void updatePlaylistMetadata (MediaMetadata2 metadata)

Updates the playlist metadata to the MediaPlaylistAgent.

Parameters
metadata MediaMetadata2: metadata of the playlist