Posted by Don Turner, Developer Relations Engineer
Introducing Jetpack Media3
Today, we’re launching the first alpha of Jetpack Media3. It’s a collection of support libraries for media playback, including ExoPlayer. This article will explain why we created Media3, what it contains, and how it can simplify your app architecture.
Why another media API?
We have several existing media APIs: Jetpack Media also known as MediaCompat, Jetpack Media2, and ExoPlayer. These libraries were developed with different goals, and have several areas of overlapping functionality.
For example, ExoPlayer and Media2 both contain UI components, and MediaCompat and Media2 contain classes for handling media sessions.
It can be challenging to decide which library to use for a given use case, and objects from different libraries are often not compatible, requiring adapters or connecting code. Media3 removes these challenges by providing a single set of libraries which work well together.
To create Media3 we:
- Identified the common areas of functionality in our existing media libraries, including UI, playback and media session handling.
- Refined and merged the best parts.
- Created a common Player interface for all “player-like” objects (more on this later).
What’s in the box
Media3 contains many libraries. The ones most relevant for simple media playback are shown below.
A common Player
Our existing media APIs have a lot of objects which accept playback commands, like “play,” “pause,” and “skip”. Identifying these “player-like” objects and ensuring that they implement a common Player interface was one of the biggest undertakings in the development of Media3.
We’ve updated, enhanced, and streamlined the Player interface from ExoPlayer to act as the common
Player interface for Media3.
Classes such as
MediaSession that previously contained references to other “player-like” objects have been updated to reference the new player.
This is useful when communicating with UI components. Both
MediaController now implement
Player, so either one of them can be used to communicate with
StyledPlayerView or other UI components.
Diagram showing how MediaController and ExoPlayer implement the Player interface and can be used to communicate with UI components, like StyledPlayerView
Player interface avoids the need for connecting components, allowing for less code and a simpler app architecture.
In particular, this makes working with media sessions easier. Instead of using the
MediaSessionConnector extension, or writing your own “player to media session” connector, you can create a
MediaSession using a
Player, like this:
player = ExoPlayer.Builder(context).build() session = MediaSession.Builder(context, player).build()
Now your media session will automatically reflect the state of your player, and any commands sent to your media session will be automatically forwarded to your player. All that in just two lines of code!
Providing a content library
If your app needs to expose its content library to other apps, like Android Auto, use
MediaLibraryService, rather than a
MediaBrowserService from MediaCompat.
You’ll then create a
MediaLibrarySession and implement a
MediaLibrarySessionCallback whose methods will be called by the browsing app to obtain your content tree.
Diagram showing how MediaLibraryService can be used to expose a content library
One of the key benefits of using Jetpack libraries is API stability. If you use symbols that are part of the stable API, you generally don’t need to update your code to use a new release of that library within the same major version.
In Media3, some of the most commonly used objects are marked as stable, including the Player API and media session classes.
Most of ExoPlayer’s API surface is marked as unstable.
Diagram showing stable and unstable areas of the Media3 API
To use an unstable method or class you’ll need to add the
OptIn annotation before using it.
@androidx.annotation.OptIn(UnstableApi::class) private fun initializeExoPlayer() // ...
If your project uses a lot of unstable methods it may be more convenient to add this suppression to your project-wide lint.xml.
<issue id="UnsafeOptInUsageError"> <ignore regexp='(markerClass = androidx.media3.common.util.UnstableApi.class)' /> </issue>
Just because part of an API is marked as unstable doesn’t mean that the API is unreliable or that you shouldn’t use it – it’s just a way of informing you that it might change in the future.
Media3 is released today in alpha and we’d love you to try it out.
One of the best ways to do this is to check out the demo app, which shows how to play video and audio, and integrate with a media session.
You can add the Media3 dependencies to your app by adding the following artifacts to your
implementation 'androidx.media3:media3-ui:1.0.0-alpha01' implementation 'androidx.media3:media3-exoplayer:1.0.0-alpha01' implementation 'androidx.media3:media3-session:1.0.0-alpha01'
If you have feedback or run into problems, please file an issue. We’d really love to hear from you.