Frontend Development 8 min read

Implementing Picture-in-Picture (PiP) with the Web API

This article explains how to use the new Picture-in-Picture Web API to enable floating video playback on web pages, covering setup of video and button elements, request handling, error management, event listeners, window‑size tracking, feature detection, and best‑practice UI considerations.

UC Tech Team
UC Tech Team
UC Tech Team
Implementing Picture-in-Picture (PiP) with the Web API

Picture-in-Picture (PiP) lets users watch a video in a floating window that stays on top of other content, allowing interaction with other sites or applications while keeping the video visible.

The PiP Web API, first supported in Safari on macOS Sierra and later in Chrome on Android O, enables web developers to launch and control PiP mode for video elements.

Start by adding a <video id="videoElement" src="https://example.com/file.mp4"></video> element and a button <button id="pipButtonElement"></button> to trigger PiP.

Request PiP only in response to a user gesture, e.g., a click handler on the button:

pipButtonElement.addEventListener('click', async function() {
  pipButtonElement.disabled = true;
  await videoElement.requestPictureInPicture();
  pipButtonElement.disabled = false;
});

Wrap the request in a try...catch block to handle possible rejections such as unsupported system, policy restrictions, missing metadata, audio‑only files, the disablePictureInPicture attribute, or calls made outside a user gesture.

pipButtonElement.addEventListener('click', async function() {
  pipButtonElement.disabled = true;
  try {
    await videoElement.requestPictureInPicture();
  } catch (error) {
    // TODO: Show error message to user.
  } finally {
    pipButtonElement.disabled = false;
  }
});

To toggle between entering and exiting PiP, check document.pictureInPictureElement and call the appropriate method:

try {
  if (videoElement !== document.pictureInPictureElement) {
    await videoElement.requestPictureInPicture();
  } else {
    await document.exitPictureInPicture();
  }
} catch (e) { /* handle errors */ }

Listen for enterpictureinpicture and leavepictureinpicture events to customize the user experience, such as updating UI or handling playback state.

videoElement.addEventListener('enterpictureinpicture', function(event) {
  // Video entered PiP.
});
videoElement.addEventListener('leavepictureinpicture', function(event) {
  // Video left PiP.
});

To react to window size changes, capture the pictureInPictureWindow from the enterpictureinpicture event and listen for its resize event:

let pipWindow;
videoElement.addEventListener('enterpictureinpicture', function(event) {
  pipWindow = event.pictureInPictureWindow;
  console.log(`> Window size is ${pipWindow.width}x${pipWindow.height}`);
  pipWindow.addEventListener('resize', onPipWindowResize);
});
videoElement.addEventListener('leavepictureinpicture', function(event) {
  pipWindow.removeEventListener('resize', onPipWindowResize);
});
function onPipWindowResize(event) {
  console.log(`> Window size changed to ${pipWindow.width}x${pipWindow.height}`);
  // TODO: Adjust video quality based on size.
}

Perform feature detection using document.pictureInPictureEnabled and hide or disable the PiP button when the API is unavailable or disabled:

if ('pictureInPictureEnabled' in document) {
  // Set button ability depending on support.
  setPipButton();
  videoElement.addEventListener('loadedmetadata', setPipButton);
  videoElement.addEventListener('emptied', setPipButton);
} else {
  pipButtonElement.hidden = true;
}
function setPipButton() {
  pipButtonElement.disabled = (videoElement.readyState === 0) ||
    !document.pictureInPictureEnabled ||
    videoElement.disablePictureInPicture;
}

Future enhancements include PiP support on Chrome OS and Android O, integration of MediaStreams from getUserMedia() , and custom PiP controls for web developers.

JavaScriptvideoWeb APIPicture-in-Picturehtml5
UC Tech Team
Written by

UC Tech Team

We provide high-quality technical articles on client, server, algorithms, testing, data, front-end, and more, including both original and translated content.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.