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:
- ExoPlayer introduction
- ExoPlayer playlists, UI customization, and events
- MediaSession Connector extension for ExoPlayer
- Supporting Audio Focus
- Supporting PIP (this article)
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.
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.
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.
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.
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).
Contribute to android-VideoPlayer development by creating an account on GitHub.github.com
Resources for further learning
- IO17 ExoPlayer codelab
- IO14 ExoPlayer Introduction Video
- IO17 ExoPlayer Session Video
- Why ExoPlayer?
- Latest changes for ExoPlayer v2.6.1
MediaSession, Audio Focus
Picture in Picture