Posted by Nevin Mittal – Developer Relations Engineer, Android Media

Today, we are pleased to announce a full release Did jetpack media3 Library. After sharing the first look at the library Android Developer Summit 2021We’ve published several alpha and beta releases over the past several months to ensure a high-quality set of APIs that we now encourage everyone to adopt.

Media3 is the new home for the APIs that enable you to create rich audio and video experiences. If you have used libraries like exoplayer, MediaCompatOr media2, you will find Media3 familiar. However, instead of using these separate libraries, Media3 provides a unified API for playback use-cases and also extends to new use-cases such as video editing and transcoding. The APIs are easy to use yet powerful, customizable to meet your needs, and reliable and optimized so you can build for a diverse Android device ecosystem.

In this blog post, we’ll focus on the playback API in Media3, so please stay tuned for upcoming posts where we’ll dive deeper into the video editing and transcoding APIs. As a brief introduction, the following table describes the major components for playback in Media3:


An interface that defines high-level functionality traditional for audio or video players, such as playback controls.


default implementation of player Interface in Media3.


An API that advertises media playback and receives playback command requests from external clients.


a service that holds MediaSession To enable background playback.


A service that additionally allows you to expose a content library to external clients.

media controller

An API commonly used by external clients to obtain playback information and send playback command requests to your media app. a’s complement MediaSession, Examples of external clients include notification and lock screen media controls on mobile and large screen devices, Android Auto, WearOS and the Google Assistant.


An API that additionally enables external clients to navigate your media app’s content library. a’s complement MediaLibraryService,

Our Developer Documentation There is more detail on these components. Let’s take a look at what this new library has to offer and how you can start using it.

keep it simple

By consolidating the APIs for playback developer travel into a single library, Media3 is able to offer player Interface that is used by multiple components, such as MediaSession And media controller, This interface underlies the traditional high-level functionality for audio and video playback, such as playback controls and the ability to query the properties of the currently playing media.

Having a common interface for all “player-like” components means that creating new instances of these objects is straightforward:

val player = ExoPlayer.builder(context).build()
val session = MediaSession.Builder(context, player).build()
val controller = MediaController.Builder(context, session.token).build()

media3 MediaSession And media controller will automatically reflect the status of the components they are connected to. As a result, you can also simplify your app’s architecture by removing connectors like ExoPlayer MediaSessionConnector Follow the flow of logic through your app more easily. calling play() But media controller will forward the action to MediaSessionWhich will then forward it to the player.

Similarly, Media3 aims to make background playback Easy to handle cases. player notification manager ExoPlayer is no longer needed like Media3 MediaSessionService And MediaLibraryService Automatically manage publishing media information as needed. Library handles configuring, starting and stopping foreground service As you need, but please also note some known issues in brief this comment,

ExoPlayer is deprecated, long live ExoPlayer!

ExoPlayer has a new home and is the default implementation of the aforementioned player interface in Media3. standalone exoplayer project with package name, will be discontinued soon and future updates will be published in Media3. For the next few months, we will continue to publish equivalent releases for both Media3 and ExoPlayer to help you make the transition to Media3. For example, this means that ExoPlayer 2.18.5 and ExoPlayer in Media3 1.0.0 are identical except for their package names. However, this is only temporary and we will be removing the standalone ExoPlayer later this year, so we recommend migrating to Media3 as soon as possible. The “Migrating to Media3” section below describes the process in more detail, including a script that handles most of the work for you.

Note that Media3 is developed with the same philosophy as ExoPlayer (and in fact, developed by the same team!). In other words, Media3 retains ExoPlayer’s customizable components, open source development on GitHub, receptivity to pull requests, and the public issue tracker, to name a few similarities.

Migrating to Media3

As mentioned earlier, the standalone Exoplayer project, with the package name, will be discontinued soon, so to continue receiving updates, you’ll need to migrate to Media3 ExoPlayer. Other media APIs being migrated to Media3 include, but are not limited to, MediaSessionConnector, MediaBrowserServiceCompatAnd MediaBrowserCompat,

We’ve created two key resources to help you get through this migration as smoothly as possible:

  1. A migration guide to walk you through the process step-by-step
  2. A migration script To convert your standalone ExoPlayer project package to the corresponding new module and package under Media3

The good news is that if you’re currently using ExoPlayer, there’s no need for any code changes and no need to re-integrate or re-write any customizations. Standalone ExoPlayer and Media3 ExoPlayer are identical apart from the package name, and the conversion can be done automatically with the above migration script. Just make sure you have updated your project to use latest version of ExoPlayer before getting started. For full details and steps, please visit migration guide,

Furthermore, since Media3 is fully backwards compatible ex media api like MediaControllerCompat And MediaMetadataCompat, your existing integrations will continue to work as before after the migration. Note that new features such as per-controller customization of commands are only available to customers using Media3. That is to say, for example, all legacy controllers, such as MediaControllerCompat, will get the same set of commands available. You can identify a legacy controller by examining get controller version, returns 0 in MediaSession.ControllerInfo,

The power of Media3, in the palm of your hand

Media3 offers you several options to adjust its behavior to better fit your needs. The next few sections describe some such mechanisms.

play it your way

Although ExoPlayer is the recommended player implementation to use for audio and video streaming apps, Media3 also offers simplebaseplayer To reduce the number of methods you need to implement in order to integrate with a custom player. start by applying getState Method this is where you can declare Permission Set supported by your player and configure metadata such as currently playing media item index and current timestamp.

class CustomPlayer : SimpleBasePlayer(looper) {
override fun getState(): State {



simplebaseplayer The class will implement valid player state and notify listeners of state changes. In addition, any method related to a Permission you don’t declare that is ignored as available, so beyond getStateYou only need to implement the methods that will actually be used.

Better control over your orders

MediaSession And media controller The API has also been updated to give you more control. With Media3, you can advertise your app’s playback capabilities on a per-controller basis. Modify commands available in the client app onconnect your method MediaSession.Callback, For example, to prevent the client app from package name com.example.myClient By gaining access to “Look for the next media item” player.command,

var sessionCallback = object : MediaSession.Callback {
override fun onConnect(
session: MediaSession,
controller: MediaSession.ControllerInfo
: MediaSession.ConnectionResult {
val connectionResult = super.onConnect(session, controller)
if (controller.packageName == "com.example.myClient") {
val availablePlayerCommands = connectionResult.availablePlayerCommands.buildUpon()
return MediaSession.ConnectionResult.accept(
return connectionResult

var mediaSession = MediaSession.Builder(context, player)

create custom command

Of course, as with the previous Media API, you can add custom commands to suit your app. To implement a custom command, create a new op command, You can grant access to controllers by adding this custom command to the list of available session commands, as shown above. You can handle custom command behavior in onCustomCommand method of the same call back,

override fun onCustomCommand(
session: MediaSession,
controller: MediaSession.ControllerInfo,
customCommand: SessionCommand,
args: Bundle
: ListenableFuture<SessionResult> {
if (customCommand.customAction == MY_CUSTOM_COMMAND) {

return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))

return Futures.immediateFuture(SessionResult(SessionResult.RESULT_ERROR_BAD_VALUE))

You can tell client apps to display your custom commands by including set custom layout call into onPostConnect method of MediaSession.Callback,

next steps

We’d love to see you start using Media3 in your apps!

To start exploring the library, feel free to check out demo app To see an example of audio and video playback, including how to integrate with media sessions. stay with us developer guide More detailed guidance on the various components in Media3 Landing soon. Our sample app, the universal android music playerand our test tool, media controller test The app will also be updated to Media3 on their main branches in the coming weeks.

If you run into any issues, have a feature request, or want to share any other kind of feedback, please let us know using media3 issue tracker on GitHub. We look forward to hearing from you!

By admin

Leave a Reply

Your email address will not be published. Required fields are marked *