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;
}