logo

Picture-in-Picture

This guide explains what Picture-in-Picture (PiP) is, describes how to implement it and links relevant resources.

The Picture-in-Picture feature allows developers to create a floating player. This is commonly used to let the video remain playing on screen even if:

  • The user scrolls to another section of the page (causing the original player to no longer be visible).
  • The user sends the application to the background.
  • The user opens a new page within the same application.

Table of Contents

SDKs

Type Web SDK Android SDK Android TV SDK iOS SDK tvOS SDK Roku SDK Fire TV SDK Chromecast SDK
in-app* Yes No No Yes No No No N/A
out-of-app** No Yes Yes Yes Yes No Yes N/A

* While using in-app picture-in-picture, the visibility of the PiP window is contained to the inside of the app. It will, in other words, go to background/foreground with the application.
** While using out-of-app picture-in-picture, the visibility of the PiP windows is not contained to the inside of the app. It can remain visibile while the user navigates to other views, pages or apps.

How to use Picture-in-Picture

Picture-in-Picture is an interesting option on both desktop and mobile to keep showing the video while the user nagivates to different parts of the content. PiP in THEOplayer presents several possibilities: this section shows how to enable, configure and observe the Picture-in-Picture option for all available SDKs. A distinction is made between in-app and out-of-app Picture-in-picture, where in the latter the PiP-window can also remain visible if the application is sent to background or another view is presented.

Code Examples

Enable Picture-In-Picture mode

Web SDK

In this SDK, PiP is enabled by default if the player configuration contains any PiP configuration (see below image). For this reason, there is no need to use any specific snippet to enable it. Note that in this SDK out-of-app Picture is (currently) not supported.

Picture-in-Picture

The PiP configuration for this SDK includes 3 properties:

  • position: (optional, possible values: "top-left", "top-right", "bottom-left", "bottom-right")
    The corner in which the player should be shown while in PiP mode. Defaults to the bottom right corner.
  • visibility: (optional, a number from 0 to 1)
    The maximum percentage of the original player position that should be visible to enable PiP automatically. If not configured, PiP can only be turned on by setting presentationMode to "picture-in-picture".
  • retainPresentationModeOnSourceChange: (optional, possible values: true or false)
    If set to true, the previous presentationMode is retained even as the source changes. It is set to false by default.
var playerConfig = {
                ...
                pip: {
                        visibility: 0.7,
                        position: "bottom-left",
                        retainPresentationModeOnSourceChange: true           
                        }                 
                };
iOS / tvOS SDK

If you want to use Picture-In-Picture in your appication you can instantiate the player with a PiPConfiguration, to be passed in the THEOplayerConfiguration. Using this PiPConfiguration you can configure whether the player should retain its presentation mode upon source-change. You can also choose whether to make use of out-of-app PiP (=nativePictureInPicture). Note that to make use of out-of-app PiP the minimum required iOS version is 14.0.

/* Configure whether presentation mode should be retained on source changes and whether to use native PiP */
let pipConfig = PiPConfiguration(retainPresentationModeOnSourceChange: true, nativePictureInPicture: true)
let playerConfig = THEOplayerConfiguration(... , pip: pipConfig)
var theoplayer = THEOplayer(configuration: playerConfig)

Once the Picture-In-Picture mode is enabled, the player's pip property can be accessed.

While using in-app PiP you can use the configure(movable:defaultCorner:) method of the player's pip property to configure the picture-in-picture.

You can configure:

  • whether the PiP view is movable or not (default to true);
  • the default corner of the PiP view (default to bottom right);
theoplayer.pip!.configure(movable: false, defaultCorner: .bottomLeft)

Notes:

  • configure is only available when using in-app PiP.
  • tvOS only supports in-app PiP, which is enabled by default if the OS version supports it (minimum tvOS 14.0).
  • iPadOS 14.0 (and above) also supports in-app PiP.
Android / Fire TV SDK

If you want to use Picture-In-Picture in your appication you can instantiate the player with a PiPConfiguration, to be passed in the THEOplayerConfig. When passing a PipConfiguration, the Android SDK will always make use of out-of-app PiP. Note that to make use of out-of-app PiP the minimum required Android version is Oreo (API level 26).

THEOplayerConfig playerConfig = new THEOplayerConfig.Builder().pipConfiguration(new PipConfiguration.Builder().build()).build();
THEOplayerView tpv = new THEOplayerView(context, playerConfig);

Once the Picture-In-Picture mode is enabled, the player's pip property can be accessed.

Observe events in Picture-In-Picture

iOS SDK
in-app Picture in Picture

Using the notification center you can listen to the PictureInPictureMoved notification. This notification will be pushed every time the picture-in-picture view moves to a different corner.

In the callback, you can retrieve the previous and the new corner in the userInfo dictionary respectively with the PictureInPictureOldCornerUserInfoKey and the PictureInPictureNewCornerUserInfoKey keys.

NotificationCenter.default.addObserver(self, selector: #selector(onPiPMoved), name: Notification.Name.PictureInPictureMoved, object: nil)

@objc func onPiPMoved(notif: Notification) {
    let userInfo = notif.userInfo as! [String: Any]
    let oldCorner : PictureInPictureCorner = userInfo[PictureInPictureOldCornerUserInfoKey]! as! PictureInPictureCorner
    let newCorner : PictureInPictureCorner = userInfo[PictureInPictureNewCornerUserInfoKey]! as! PictureInPictureCorner
    print("PiP has moved from \(oldCorner) to \(newCorner)")
}
out-of-app Picture in Picture

By using your own implementation of the AVPictureinpictureControllerDelegate you are able to listen to a number of events. These contain, but are not limited to, when the player will enter/exit PiP, has entered/exited PiP, ... To achieve this you just have to set your implementation of the delegate as the one of the PictureInPictureController.

class CustomPiPDelegate: NSObject, AVPictureInPictureControllerDelegate {
    func pictureInPictureControllerDidStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
        // Custom action when picture in picture started
    }
    // ... Others here.
}

let customDelegate = CustomPiPDelegate()
var THEOPiP = theoplayer?.pip
if #available(iOS 14.0, *) { 
    THEOPiP?.nativePictureInPictureDelegate = customDelegate
} else {
    // Fallback on earlier versions
}
Android SDK

For the Android SDK it is possible to listen for a *presentationmodechange *event or verify the presentationMode of the player in case you need to find out what the presentation mode is at a given moment or detect a change.

// Assuming you have an instance of the player called 'theoplayer'
theoplayer.addEventListener(PlayerEventTypes.PRESENTATIONMODECHANGE, new EventListener<PresentationModeChange>() {
    @Override
    public void handleEvent(PresentationModeChange event) {
        PresentationMode currentMode = event.getPresentationMode();
        if (currentMode == PresentationMode.PICTURE_IN_PICTURE) {
            // Currently in PiP
        }
    }
});
// The listener above will be triggered by one of:
theoPlayerView.getPiPManager().enterPiP();
theoPlayerView.getPiPManager().exitPiP();

Sample applications

A demo (Web SDK) of this feature can be found at

To see PiP in action, start the video and scroll down on the page.

Remarks

The following remarks can help:

  • PiP is a presentation mode of the player. As such, you can listen for a *presentationmodechange *event or verify the presentationMode of the player in case you need to find out what the presentation mode is at a given moment or detect a change.
  • This feature is not completely the same on all SDKs, as the options may vary. For example, in the Web SDK it is not possible to drag and drop the floating player to a new position (PiP is not movable).

Known Limitations

  • iOS: VR360 is not supported in combination with PiP.
  • iOS: Only SSAI is supported, no CSAI (both are supported for Android)
  • iOS: No support for sideloaded texttrack.
  • Android TV: A limitation from the Android Framework - When the player is showing a native Google IMA advertising while being in Picture in Picture mode and the user triggers something which moves the PiP window (such as opening the keyboard) then the view showing the advertisement might be misaligned.

Resources

The following resources provide more information:

Web SDK
iOS SDK
Android SDK
github
Make sure to follow us on GitHub!
THEO-logo-white
twitter
facebook
linkedin
Copyright © 2022. All Rights Reserved.
Leuven
New York
Singapore
Barcelona