PiP - videos in a floating window
Tags: web, api, javascript, video
Published: 2019-01-02 23:25:35

---
title: PiP - videos in a floating window
published: true
description: 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
tags: web, api, javascript, video
cover_image: https://thepracticaldev.s3.amazonaws.com/i/njv23gb1e56q6wna426n.png
---

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:

```javascript
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](https://github.com/WICG/feature-policy/blob/master/features.md#picture-in-picture). Luckily, you can use the new boolean `document.pictureInPictureEnabled` to determine this.

Request or exist Picture-in-Picture:

```javascript
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](https://w3c.github.io/webappsec-feature-policy/#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:

```javascript
// 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

{% instagram BsJoT9LlU-4 %}

Check out sample demo here [https://elmahdim.github.io/pip/](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](https://wicg.github.io/feature-policy/#policy-controlled-feature) that controls whether the [request Picture-in-Picture algorithm](https://wicg.github.io/picture-in-picture/#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/