Building a video player app in Android (Part 5 / 5)

With ExoPlayer, Playlists, MediaSession, Audio Focus, PIP

The goal of this series of articles is to get you started with using ExoPlayer to build a simple, but feature rich, video player app (that supports playlists, MediaSession, Audio Focus, and Picture in Picture).

This is the final part of a 5 part series that includes:

The previous article in the series covered the steps needed to add Audio Focus support to your app. This article gets into the details of adding support for picture in picture (PIP) to the app.

PIP

Picture in picture (PIP) was introduced in Android Oreo, which allows an activity to be minimized into a small window that’s visible on top of other activities. You can set the orientation of this window that floats on top of everything else on the screen. Here’s an example of what this looks like.

It is really easy to enable PIP mode for an activity in the AndroidManifest.xml. Here’s an example.

Note — You can also set another attribute android:resizeableActivity to true, and this will make this activity resizeable for multi-window mode.

Once you’ve marked that your activity supports picture PIP, then you have to make it enter PIP mode based on some user action. Typically, you can trigger this when the user hits the home button by overriding the onUserLeaveHint() method. When the user hits the home button, it moves the current activity to the background. Here’s an example.

Note that we set an aspect ratio of 16:9 when the activity is minimized. You can set whatever aspect ratio you want for this minimized window.

Once the activity that’s showing the video player enters PIP mode, we are notified of this, via the following method.

The onPictureInPictureChanged(…) method is called when the activity enters or exits PIP mode. In our case, we override this method and hide the player UI controls when the activity is minimized. The PlayerView has a useController field that can be set to false in order to hide these controls. When the activity is maximized, we allow these UI controls to be displayed again.

Audio Focus

Supporting PIP makes the integration with MediaSession, and supporting Audio Focus make sense from a UX perspective.

When the app can minimize itself into a small window and play media while other apps are running, audio focus becomes hugely important.

Consider this scenario, a user launches the video player app and starts playing a video. Then they minimize it into a PIP window, and then launch YouTube. At this point, both YouTube and the video player app are visible to the user.

  • When you choose to play a video in YouTube app, this should pause playback in the sample app.
  • When you choose to play a video in the sample app, this should pause playback in YouTube.

And this is exactly what happens when you use the AudioFocusWrapper class (that provides audio focus support to SimpleExoPlayer) in the previous article.

MediaSession

Because the app is using a MediaSession (that we added in the third article in the series), a UI to control playback is automatically provided by the system without writing any code whatsoever! 🙌 With this, the user can easily play / pause / skip, etc. right from the PIP window.

Source code on GitHub

By following these 5 articles, you should be able to create a video player app that is similar to this sample we have created (which you can get from Android Studio as well).

Resources for further learning

ExoPlayer

MediaSession, Audio Focus

DASH, HLS

Picture in Picture

Like what you read? Give Nazmul Idris (Naz) a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.