New features of AndroidX Media and ExoPlayer

Creating applications with multimedia playback features comes with a number of challenges that make development difficult. However, this year it became possible to use Jetpack Media3, a solution that completely changes the way you interact with multimedia. An Android developer will tell about this library and its capabilities CleverPumpkin Sergei Smirnov.

To play a multimedia file, two components are needed: the media player itself, which plays audio and video, and a user interface that displays some metadata (for example, the title, the duration of the audio track or video, and the current playback status).

In addition, the user interface allows you to interact with the player through buttons – the application receives the Play, Pause, Time Navigation commands and displays notifications when the state changes.

The problem is that in this architecture, the Android system and other applications do not receive information about media playback. As a result, users are deprived of convenient ways to view and control the player outside of our application.

In order to solve this problem, you need to connect the player to a multimedia session – then the system will receive information that the file is currently playing and provide control. In this case, you do not need to enter the application itself.

This makes many useful integrations available. For example, you can control the playback of a file through a smart watch or use the buttons on the headphones. In the future, it is planned to implement control from other applications, as well as through a voice assistant.

Thus, such an architecture allows you to more fully use the capabilities of both the player itself and the entire system as a whole.

Libraries

The main issue faced by developers in this area is the choice of an appropriate library to implement the function of playback and media management.

The solution to this issue is Jetpack Media3. But to better understand its benefits, first let’s review some of the libraries that have been used before.

Androidx.media2. It implements playback modules, interface components, media session control, and general data structures and functions.

ExoPlayer. This is a library for media playback operations. It is used in hundreds of thousands of applications, including our own Kassir.ru – here, with its help, stories and videos in banners are played.

There are modules in these APIs that almost duplicate each other and perform basically the same functions.
Other libraries also exist, including the original androidx.media compat library.

Many similar libraries, their capabilities and disadvantages, various compatibility conditions – all this makes it difficult to choose a library to use.

For the convenience of developers, Jetpack Media3 decided to combine these libraries.

  1. One common module has been created.

  2. ExoPlayer has been standardized while retaining its extensive set of support modules.

  3. One module with user interface and player view components and another module with API for working with system media sessions were implemented.

The result is androidx.media3 which provides a related set of libraries for various media use cases.

Foreground playback

Let’s describe the main use cases and highlight the advantages of Jetpack Media3 compared to previous versions.
Let’s consider the option of playing content, in which the application is located in the foreground. Here you can use the architecture when the UI, the player and the media session are in the same activity. In this case, the media session allows you to support media key events and picture-in-picture display controls.

In the past, this approach was difficult because with previous APIs, the media session could not directly interact with the player. A connector object was required that would translate commands and callbacks between these components. It took a lot of code to implement the full set of commands that a media session could receive, and to handle the various states of the player. Because of this, additional difficulties appeared, and the risk of errors increased.

To resolve this issue, Media3 abandoned the connector. Media3 provides ExoPlayer as its standard player – and it is in it that the Player interface is implemented.

Therefore, Google updated the MediaSession and UI widgets to accept the same Player interface by linking them directly to each other.

background playback

In the case of background playback, things are a little more complicated. The architecture is split between a service containing the player and an activity for the user interface.

The service starts a media session that is used to announce playback and issue commands to the player. And inside the activity, we create a media controller that serves to communicate with the media session.

As mentioned earlier, the player cannot interact directly with the session – a connector is required. It is also required for the media controller and our UI. The result is the same problem as playing in the foreground — connectors complicate the code, leading to crashes.

To address this issue, the generic Player interface has been implemented. The ExoPlayer is now directly compatible with the media session and the media controller is directly compatible with the UI. These changes result in code that is easier to maintain and less prone to errors.

PlayerService

Now let’s look at how to create an application that plays audio and video content in the background.

First of all, we create an instance of ExoPlayer. Then we start the media session and pass our player implementation to it.

Media3 will automatically update the media session based on the state of the player. In this case, connecting layers are not required.

Let’s move on to the Activity where we are going to display the user interface.

We set a link to the playback session in the OnStart() method of the Activity lifecycle.

  1. We generate a token for the session to which we want to connect.

  2. We create a MediaController that connects to the media session asynchronously.

  3. You can also connect the Listener to establish a connection.

  4. Since the MediaController is just an implementation of the Player interface, we can pass it directly to the playerView.

Once set up, the UI updates in the same way as when playing in the foreground when the UI and the player are in the same Activity. This works even if your service and player are running in a separate process.

Working with other apps

In conclusion, let’s touch on the question of how our application can work with other applications on the Android system.

There are two main options.

In the first case, we open access to the media session so that other applications and devices can control our media player and playback. For the user, this option may be the most convenient.

In the second case, we pass the playback content – other applications can use their own user interface. This is important, for example, for Android Auto, which provides its own, driver-friendly UI for our content.

Similar Posts

Leave a Reply

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