Picture-in-Picture
is a feature supported by some smart televisions, devices to show the content(like videos) on a floating window(on the top of other windows) so that users can continue to see the content while interacting with the background page, other sites.
Have you noticed the mini-player option when you watch a video on Youtube? You can watch the video in the Picture-in-Picture-like mode while interacting with the other part of the application.
Figure 1: Example of a Youtube video playing in the mini-player
The Google Chrome browser started supporting the Picture-in-Picture
mode. You can use this extension to enable it in the chrome browser. Once enabled, you can see it appearing beside the browser's address bar.
For Mozilla Firefox, you may have to enable it from the about.config
page by setting the media.videocontrols.picture-in-picture.enabled
property to true
Picture-in-Picture using JavaScript
JavaScript provides you the Picture-in-Picture
API to create and control the feature programmatically. Here goes the browser support information:
- Google Chrome version >= 70
- Microsoft Edge version >= 79
- Safari version >= 13.1
- Mozilla Firefox: Partial(Conditional) Support
You can find the other browser and device support details from here.
The picture-in-picture API methods are available in the HTMLVideoElement(<video>)
and Document
interfaces to allow users to toggle between the standard presentation and picture-in-picture modes.
Check Browser's Support
We can check the browser's support for this API using the following code,
if (document.pictureInPictureEnabled) {
// The picture-in-picture feature is supported
} else {
// Ther is no Support for the picture-in-picture feature
}
Picture-in-Picture Mode: Enter and Exit
To enter into the picture-in-picture
mode, you can call the method requestPictureInPicture()
on the <video>
element. When you call the method exitPictureInPicture()
on the document
object, the video exits from the picture-in-picture mode and enter the standard presentation mode.
Let's add a simple video element in the HTML file,
<video
src="path_to_video_file"
id="video" muted autoplay loop>
</video>
Next, we will add a button to toggle between the modes. Then, finally, add a click handler to call the toggle()
function.
<button
id="actionBtnId"
class="action"
onclick="toggle()"
disabled>
Enter Picture-in-Picture mode
</button>
In the JavaScript, we will define the toggle()
function as,
function toggle() {
if (document.pictureInPictureElement) {
document.exitPictureInPicture();
} else if (document.pictureInPictureEnabled) {
video.requestPictureInPicture();
}
}
In the code above, we check if the picture-in-picture feature is enabled. If so, call the requestPictureInPicture
on the video element to get into the picture-in-picture mode. Once the picture-in-picture mode is enabled, the document object will have the pictureInPictureElement
. So, when the toggle function gets called next time, it checks the pictureInPictureElement
. If found, it exits from the picture-in-picture mode.
Here is a CodePen
to see it as an example. Try clicking on the button below the video and see the video getting into the picture-in-picture mode. Click on the same button again to exit from the mode.
Please note: As explained before, to see the picture-picture feature working in the Mozilla Firefox browser, you have to enable it first. Once enabled, you can right-click on the video and select the option
Watch in Picture-in-Picture
.
Picture-in-Picture API Events
The Picture-in-Picture
API defines three events.
-
enterpictureinpicture
: Triggers when a video element enters the picture-in-picture mode. -
leavepictureinpicture
: Triggers when the video element exits the picture-in-picture mode. -
resize
: Triggers when the picture-in-picture windows resize.
These events can come in handy when you want to perform any custom actions based on a video enters or exit the picture-in-picture mode. Here is an example of changing a button text and color when a video toggles between the modes.
video.addEventListener('enterpictureinpicture', () => {
actionBtnId.textContent = 'Exit Picture-in-Picture mode';
actionBtnId.classList.add("redBtn");
});
video.addEventListener('leavepictureinpicture', () => {
actionBtnId.textContent = 'Enter Picture-in-Picture mode';
actionBtnId.classList.remove("redBtn");
});
You must have noticed it working in the code pen example we have seen above.
Picture-in-Picture API Properties
The Picture-in-Picture
API provides properties in multiple JavaScript interfaces like, HTMLVideoElement(<video>)
, Document
, and ShadowRoot
.
-
pictureInPictureEnabled
: We have seen this property already. It tells us whether or not it is possible to engage in picture-in-picture mode.
if (document.pictureInPictureEnabled) {
video.requestPictureInPicture();
}
autoPictureInPicture
: It is a video element property that automatically enables a video to get into the picture-in-picture mode and exits when the user switches the tab/application. For example, right-click on the video in the CodePen below and enter into the picture-in-picture mode. Then switch tabs and come back to the same pen to see it exiting automatically.
-
disablePictureInPicture
: This video element property will disable the picture-in-picture feature. Here is a CodePen to try out this property.
How to Control Styling?
The CSS pseudo-class :picture-in-picture
allows us to adjust the size, style, or layout of content when a video switches back and forth between picture-in-picture and standard modes.
:picture-in-picture {
box-shadow: 0 0 0 5px #0081ff;
background-color: #565652;
}
Stream Webcam Capture into the Picture-in-Picture mode
Let us do something a bit more fun now. How about capturing the video using your webcam and show it in the picture-in-picture mode.
First create a video element,
<video id="videostreamId" autoplay="" controls></video>
Now we can start the webcam, and once we start receiving the stream, we can pass it to the video element to play it.
await navigator.mediaDevices.getUserMedia({ video: true })
.then(stream => {
window.localStream = stream;
video.srcObject = stream;
video.play();
});
Next, we use the Picture-in-Picture
API method when the video is fully loaded into the video element.
video.addEventListener('loadedmetadata', () => {
video.requestPictureInPicture();
});
You can try out the same in the CodePen below.
Please note: You may have to open the pen in a new tab and see the webcam working. Also, feel free to fork and fix a bug I left unfixed in the code 🐞.
That's all for now. If you enjoyed this article or found it helpful, let's connect. You can find me on Twitter(@tapasadhikary) sharing thoughts, tips, and code practices.
You may also like,
Top comments (2)
that awesome , thank you keep it up❤❤
Thank you!