Android Picture In Picture (PiP) Mode - ExoPlayer

Android Picture-in-Picture (PIP) Mode allows multitasking by allowing users to continue watching video (or any other content) while interacting with other apps. Introduced in Android 8.0 (API level 26), PIP mode minimizes video playback into a small, movable window that stays visible on the screen as users navigate their device. This feature is particularly useful for apps that play video, such as media players or video conferencing apps, providing a seamless viewing experience even when switching tasks.

In this article, we’ll explore the basics of PIP and how to implement it for a video playing in ExoPlayer.
android pip mode exoplayer

1. The Basics

Before getting into full example, let's cover the basics of PiP. All the pointers discussed below are necessary to have smoother PiP experience.

1.1 Declare picture-in-picture Support

By default, the picture-in-picture is not enabled for any app. To enabled PiP in your app, the following changes needs to be done in AndroidManifest.xml
  • To add PiP support to an activity, add android:supportsPictureInPicture to true.
  • Add android:configChanges property to avoid activity restarts when layout configuration changes.
  • If necessary, add android:launchMode="singleTask" as well to avoid launching the multiple instances of same activity.

<activity
            android:name=".PlayerActivity"
            android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
            android:launchMode="singleTask"
            android:supportsPictureInPicture="true" />
    

1.2 Enter into picture-in-picture

To enter into PiP mode, simply call enterPictureInPictureMode() in your activity by providing necesarry params.

val params = PictureInPictureParams.Builder()
            ...
            .build()

setPictureInPictureParams(params)

// switch to PiP mode
enterPictureInPictureMode(params)

    

1.3 Smoother PiP transition using Picture In Picture Params

You can use PictureInPictureParams to configure the Picture-in-Picture mode. It allows you to set parameters like aspect ratio, custom actions (such as play/pause controls), and PiP window bounds.
  • sourceRectHint - Defines the activity area that needs to visible in PiP window. For example, in a video player activity, only the video player should be shown in PiP window.
  • setAutoEnterEnabled - Starting from Android 12, setting setAutoEnterEnabled(true) automatically switches the activity to PiP mode when user moves away from the app by using gester navigation, for example pressing home moves the activity into PiP.
  • onUserLeaveHint - If you are targeting your app below Android 12, you can call enterPictureInPictureModes() in onUserLeaveHint() method to switch to PiP mode. This is not needed if you are using setAutoEnterEnabled(true).
  • setAspectRatio - This ratio defines the desired width and height of PiP window.
  • setActions - Using this method you can add custom action buttons to PiP window. For example, you can add play and pause buttons if you are playing a video.
  • OnBackPressedCallback - If you want to switch to PiP mode when device back is pressed, you can utilize OnBackPressedCallback.

// preparing visible rect of video player
val visibleRect = Rect()
binding.playerView.getGlobalVisibleRect(visibleRect)

val builder = PictureInPictureParams.Builder()
    .setAspectRatio(Rational(visibleRect.width(), visibleRect.height()))
    .setSourceRectHint(visibleRect)

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
    // enable auto enter on Android 12
    builder.setAutoEnterEnabled(true)
}

val params = builder.build()

// set pip params before entering into PiP
setPictureInPictureParams(params)

enterPictureInPictureMode(params)
    

2. Playing ExoPlayer Video in PiP

Now let's see how to play the ExoPlayer video in Picture In Picture mode.
ExoPlayer is a powerful media player for Android that provides efficient, customizable playback of audio and video content. If you’re new to ExoPlayer, you can refer to this article to learn more.{alertInfo}
  1. Create a new project in Android Studio from File => New Project and select Empty Views Activity.
  2. Add ExoPlayer dependencies to app's build.gradle
    build.gradle
    
    dependencies {
        ....
    
        // exoplayer
        implementation("androidx.media3:media3-exoplayer:1.4.1")
        implementation("androidx.media3:media3-ui:1.4.1")
        implementation("androidx.media3:media3-exoplayer-dash:1.4.1")
    }
      
  3. Create a new activity class PlayerActivity and add the explayer to it's layout file.
  4. Open AndroidManifest.xml and add INTERNET permission to play the media from a remote URL. Add the necessary properties supportsPictureInPicture, configChanges, launchMode required for PiP mode.
  5. Open PlayerActivity and do the following changes. In summary
    • In initializePlayer(), the ExoPlayer is initialized and the video is played when player is ready
    • The updatePictureInPictureParams() method takes care of PiP configuration like aspect ratio, view source rect area and adding custom actions like play/pause buttons to PiP window. Here if the video is portrait video, the aspect ratio is set as 9:16, otherwise the ratio will be 16:9
    • Calling enterPipMode() enters the activity into picture-in-picture mode.
    • In onUserLeaveHint(), the activity is entered into PiP mode when app runs on below Android 12.
    • A broadcast receiver is used to receive the events when PiP window custom actions are tapped. Based on playback state, the video is paused or resumed and the custom action icons are toggled by calling updatePictureInPictureParams() at runtime.
    • The back press is handled using OnBackPressedCallback and the activity is entered into PiP if the video is playing. If the video is not playing, the usual back navigation happens.
  6. Finally test the PiP by launching the PlayerActivity by passing the video url.
android picture in picture mode exoplayer tutorial

android examle of exoplayer pip
The complete code of this project can be found here. Let me know your queries in the comments section below.

Cheers!
Happy Coding 🤗

1 Comments

Previous Post Next Post

نموذج الاتصال