A partial archive of discourse.wicg.io as of Saturday February 24, 2024.

[Proposal] Document Picture-in-Picture

steimel
2022-01-14

Summary

There currently exists a Web API for putting an HTMLVideoElement into a Picture-in-Picture window (HTMLVideoElement.requestPictureInPicture()). If a website wants to have something as simple as custom media controls icons or as complex as a full scrollable playlist in the PiP window, they can’t currently provide it in the existing HTMLVideoElement experience.

We want to expand upon that functionality with a new method on the Window object (window.requestPictureInPictureWindow()) which opens a picture-in-picture (i.e. always-on-top) window with a blank document that can be populated with arbitrary HTMLElements instead of only a single HTMLVideoElement.

Example code

HTML

<body>
  <div id="player-container">
    <div id="player">
      <video id="video" src="foo.webm"></video>
      <!-- more player elements here -->
    </div>
  </div>
  <input type="button" onclick="enterPiP();" value="Enter PiP" />
</body>

JavaScript

// Handle to the picture-in-picture window.
let pipWindow = null;

function enterPiP() {
  const player = document.getElementById('player');
  let pipOptions = { width: player.clientWidth, height: player.clientHeight,
                     constrainAspectRatio: true };
  window.requestPictureInPictureWindow(pipOptions).then(pipWin => {
    pipWindow = pipWin;

    // Style remaining container to imply the player is in PiP.
    playerContainer.classList.add('pip-mode');

    // Add styles to the PiP window.
    const styleLink = document.createElement('link');
    styleLink.href = 'pip.css';
    styleLink.rel = 'stylesheet';
    styleLink.type = 'text/css';
    pipWindow.document.body.appendChild(styleLink);

    // Add player to the PiP window.
    pipWindow.document.body.appendChild(player);

    // Listen for the PiP closing event to put the video back.
    window.addEventListener('exitpictureinpicture', onExitPiP,
        { once: true });
  });
}

// Called when the PiP window has closed.
function onExitPiP(event) {
    // Remove pip styling from the container.
    const playerContainer = document.getElementById('player-container');
    playerContainer.classList.remove('pip-mode');

    // Add the player back to the main window.
    const player = event.pictureInPictureWindow.document
                        .getElementById('player');
    playerContainer.appendChild(player);

    pipWindow = null;
}
AshleyScirra
2022-01-15

This looks like it might be good for using with canvas. Perhaps small web games could go in PiP windows!

tomayac
2022-01-17

Also see Picture-in-Picture for arbitrary content - Chrome Platform Status where this has been proposed before.

chrisn
2022-01-24

Very happy to see this, we are interested in using this for video with custom player controls and caption rendering for accessibility. See also discussion in Picture-in-Picture for any Element · Issue #113 · w3c/picture-in-picture · GitHub

Xaekai
2022-02-08

As per the related issue I raised on the github issue tracker, I believe this proposal would enable useful functionality for my end users by facilitating a canvas overlayed atop a video element for displaying supplementary information in the PIP in a manner a simple solution like webvtts would simply be incapable of, such as animated sliding comments a la Nicovideo, or a webassembly of libass rendering SSA formatted subtitles.

I hope this moves forward.

BEEDELLROKEJULIANLOC
2022-02-22

This was extensively discussed at ‘http://github.com/w3c/picture-in-picture/issues/113#issuecomment-1047201076’, so consider observation of some of the useful suggestion that was provided.