Understanding the Picture-in-Picture web API with examples

Tapas Adhikary - May 6 '21 - - Dev Community

Picture-in-Picture is a feature supported by some smart televisions, devices to show the content(like videos) on a floating window(on the top of other windows) so that users can continue to see the content while interacting with the background page, other sites.

Have you noticed the mini-player option when you watch a video on Youtube? You can watch the video in the Picture-in-Picture-like mode while interacting with the other part of the application.

youtube_miniplayer.png
Figure 1: Example of a Youtube video playing in the mini-player

The Google Chrome browser started supporting the Picture-in-Picture mode. You can use this extension to enable it in the chrome browser. Once enabled, you can see it appearing beside the browser's address bar.

image.png
Figure 2: Picture-In-Picture extension for Chrome browser

For Mozilla Firefox, you may have to enable it from the about.config page by setting the media.videocontrols.picture-in-picture.enabled property to true

image.png
Figure 3: Enable picture-in-picture in the firefox browser.

Picture-in-Picture using JavaScript

JavaScript provides you the Picture-in-Picture API to create and control the feature programmatically. Here goes the browser support information:

  • Google Chrome version >= 70
  • Microsoft Edge version >= 79
  • Safari version >= 13.1
  • Mozilla Firefox: Partial(Conditional) Support

You can find the other browser and device support details from here.

The picture-in-picture API methods are available in the HTMLVideoElement(<video>) and Document interfaces to allow users to toggle between the standard presentation and picture-in-picture modes.

Check Browser's Support

We can check the browser's support for this API using the following code,

if (document.pictureInPictureEnabled) {
  // The picture-in-picture feature is supported
} else {
  // Ther is no Support for the picture-in-picture feature
}
Enter fullscreen mode Exit fullscreen mode

Picture-in-Picture Mode: Enter and Exit

To enter into the picture-in-picture mode, you can call the method requestPictureInPicture() on the <video> element. When you call the method exitPictureInPicture() on the document object, the video exits from the picture-in-picture mode and enter the standard presentation mode.

Let's add a simple video element in the HTML file,

<video 
   src="path_to_video_file" 
   id="video" muted autoplay loop>
</video>
Enter fullscreen mode Exit fullscreen mode

Next, we will add a button to toggle between the modes. Then, finally, add a click handler to call the toggle() function.

<button 
   id="actionBtnId" 
   class="action" 
   onclick="toggle()" 
   disabled>
     Enter Picture-in-Picture mode
</button>
Enter fullscreen mode Exit fullscreen mode

In the JavaScript, we will define the toggle() function as,

function toggle() {
  if (document.pictureInPictureElement) {
      document.exitPictureInPicture();
  } else if (document.pictureInPictureEnabled) {
      video.requestPictureInPicture();
  }
}
Enter fullscreen mode Exit fullscreen mode

In the code above, we check if the picture-in-picture feature is enabled. If so, call the requestPictureInPicture on the video element to get into the picture-in-picture mode. Once the picture-in-picture mode is enabled, the document object will have the pictureInPictureElement. So, when the toggle function gets called next time, it checks the pictureInPictureElement. If found, it exits from the picture-in-picture mode.

Here is a CodePen to see it as an example. Try clicking on the button below the video and see the video getting into the picture-in-picture mode. Click on the same button again to exit from the mode.

Please note: As explained before, to see the picture-picture feature working in the Mozilla Firefox browser, you have to enable it first. Once enabled, you can right-click on the video and select the option Watch in Picture-in-Picture.
image.png

Picture-in-Picture API Events

The Picture-in-Picture API defines three events.

  • enterpictureinpicture: Triggers when a video element enters the picture-in-picture mode.
  • leavepictureinpicture: Triggers when the video element exits the picture-in-picture mode.
  • resize: Triggers when the picture-in-picture windows resize.

These events can come in handy when you want to perform any custom actions based on a video enters or exit the picture-in-picture mode. Here is an example of changing a button text and color when a video toggles between the modes.

video.addEventListener('enterpictureinpicture', () => {
  actionBtnId.textContent = 'Exit Picture-in-Picture mode';
  actionBtnId.classList.add("redBtn");
});

video.addEventListener('leavepictureinpicture', () => {
  actionBtnId.textContent = 'Enter Picture-in-Picture mode';
  actionBtnId.classList.remove("redBtn");
});
Enter fullscreen mode Exit fullscreen mode

You must have noticed it working in the code pen example we have seen above.

Picture-in-Picture API Properties

The Picture-in-Picture API provides properties in multiple JavaScript interfaces like, HTMLVideoElement(<video>), Document, and ShadowRoot.

  • pictureInPictureEnabled: We have seen this property already. It tells us whether or not it is possible to engage in picture-in-picture mode.
   if (document.pictureInPictureEnabled) {
      video.requestPictureInPicture();
  }
Enter fullscreen mode Exit fullscreen mode

autoPictureInPicture: It is a video element property that automatically enables a video to get into the picture-in-picture mode and exits when the user switches the tab/application. For example, right-click on the video in the CodePen below and enter into the picture-in-picture mode. Then switch tabs and come back to the same pen to see it exiting automatically.

  • disablePictureInPicture: This video element property will disable the picture-in-picture feature. Here is a CodePen to try out this property.

How to Control Styling?

The CSS pseudo-class :picture-in-picture allows us to adjust the size, style, or layout of content when a video switches back and forth between picture-in-picture and standard modes.

:picture-in-picture {
  box-shadow: 0 0 0 5px #0081ff;
  background-color: #565652;
}
Enter fullscreen mode Exit fullscreen mode

Stream Webcam Capture into the Picture-in-Picture mode

Let us do something a bit more fun now. How about capturing the video using your webcam and show it in the picture-in-picture mode.

First create a video element,

<video id="videostreamId" autoplay="" controls></video>
Enter fullscreen mode Exit fullscreen mode

Now we can start the webcam, and once we start receiving the stream, we can pass it to the video element to play it.

 await navigator.mediaDevices.getUserMedia({ video: true })
 .then(stream => {
    window.localStream = stream;
    video.srcObject = stream;
    video.play();
  });
Enter fullscreen mode Exit fullscreen mode

Next, we use the Picture-in-Picture API method when the video is fully loaded into the video element.

 video.addEventListener('loadedmetadata', () => {
    video.requestPictureInPicture();
  });
Enter fullscreen mode Exit fullscreen mode

You can try out the same in the CodePen below.

Please note: You may have to open the pen in a new tab and see the webcam working. Also, feel free to fork and fix a bug I left unfixed in the code 🐞.



That's all for now. If you enjoyed this article or found it helpful, let's connect. You can find me on Twitter(@tapasadhikary) sharing thoughts, tips, and code practices.

You may also like,

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .