27 outubro 2021
Posted by Don Turner, Developer Relations Engineer
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.
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:
Media3 contains many libraries. The ones most relevant for simple media playback are shown below.
Library name |
Purpose |
Useful classes for playback |
media3-exoplayer |
Objects for playing video and audio, provided by ExoPlayer. |
An ExoPlayer can be used for many playback use cases. Create one using an ExoPlayer.Builder |
media3-ui |
Views for displaying media playback controls, content and metadata. |
StyledPlayerView displays audio and video content from a Player |
media3-session |
Objects for creating and interacting with a media session. |
MediaSession for advertising what you're playing MediaLibraryService for advertising your content library |
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 MediaController
and 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 ExoPlayer
and 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
Using this 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!
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 build.gradle
:
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.
For more information check out the “What's next for AndroidX Media and ExoPlayer” talk from Android Dev Summit 2021 and the Media3 release notes.