I used to watch conferences, DIY tutorials, a new piece of tech review or even a standup comedy videos in a floating mini player playing down there in the corner on top of the other windows while interacting with other tasks like writing code, an article, or reading reddit, twitter or hacker news.
As far as I know there's a pretty awesome extensions for both of Chrome and Safari that handle such a thing for YouTube videos. This can be done with a JavaScript/Web API!
Picture-in-Picture Web API
Picture-in-Picture (PiP) is a common platform-level feature among desktop and mobile OSs. Picture-in-Picture (PiP) allows users to watch videos in a floating window (always on top of other windows) so they can keep an eye on what they’re watching while interacting with other tasks. This window stays visible even when user agent is not visible.
The specification aims to allow websites to initiate and control this behavior by exposing the following sets of properties to the API:
- Notify the website when it enters and leave Picture-in-Picture (floating) mode.
- Allow the website to trigger Picture-in-Picture via a user gesture on a video element.
- Allow the website to know the size of Picture-in-Picture window and notify the website when it changes.
- Allow the website to exit Picture-in-Picture.
- Allow the website to check if Picture-in-Picture can be triggered.
Usage
Check if Picture-in-Picture is supported and available:
const isPiPAvailable = () => {
return document.pictureInPictureEnabled || !videoElement.disablePictureInPicture;
}
isPiPAvailable() ? showPiPButton() : hidePiPButton();
The Picture-in-Picture Web API may not be supported, so we have to detect this to provide progressive enhancement. Even when it is supported, it may be turned off by the user or disabled by a feature policy. Luckily, you can use the new boolean document.pictureInPictureEnabled
to determine this.
Request or exist Picture-in-Picture:
try {
if (!document.pictureInPictureElement) {
videoElement.requestPictureInPicture()
} else {
document.exitPictureInPicture();
}
} catch(reason) {
console.error(reason);
}
- If Picture-in-Picture support is false, throw a
NotSupportedError
- If document is not allowed to use the policy-controlled feature named "picture-in-picture", throw a
SecurityError
- If the disablePictureInPicture attribute is present on video, throw a
InvalidStateError
Monitor video Picture-in-Picture changes:
// Video entered Picture-in-Picture mode.
video.addEventListener('enterpictureinpicture', (event) => console.log(event))
// Video left Picture-in-Picture mode.
video.addEventListener('leavepictureinpicture', (event) => console.log(event))
Listen to Picture-in-Picture events instead of waiting for promises to update your media player controls. It's possible for the video to enter and exit Picture-in-Picture at any time (e.g. user clicks some browser context menu or Picture-in-Picture is triggered automatically). User may have played a Picture-in-Picture video from a different page.
MediaStream video support
Video playing MediaStream objects (e.g. getUserMedia()
, getDisplayMedia()
, canvas.captureStream()
) also support Picture-in-Picture in Chrome 71. This means you can show a Picture-in-Picture window that contains user's webcam video stream, display video stream, or even a canvas element. Note that the video element doesn't have to be attached to the DOM to enter Picture-in-Picture.
Picture-in-Picture Demo
Check out sample demo here https://elmahdim.github.io/pip/.
Security considerations
The API applies only to HTMLVideoElement
in order to start on a minimal viable product that has limited security issues. Later versions of this specification may allow PIP-ing arbitrary HTML content.
Feature Policy
This specification defines a policy-controlled feature that controls whether the request Picture-in-Picture algorithm may return a SecurityError
and whether pictureInPictureEnabled
is true
or false
.
Resources
- Chrome Feature Status: https://www.chromestatus.com/feature/5729206566649856
- Picture-in-Picture Web API Spec: https://wicg.github.io/picture-in-picture
- Unofficial Picture-in-Picture polyfill: https://github.com/gbentaieb/pip-polyfill/
Top comments (0)