Chrome 70+ introduces the picture-in-picture API. Would be cool to have an extra button in the player for this, allowing you to switch to PIP.
Demo: https://googlechrome.github.io/samples/picture-in-picture/
API: https://developers.google.com/web/updates/2018/10/watch-video-using-picture-in-picture and https://wicg.github.io/picture-in-picture/
Status: https://github.com/WICG/picture-in-picture/blob/master/implementation-status.md
Icon: https://material.io/tools/icons/?search=pic&icon=picture_in_picture&style=baseline
Simple button subclass that works:
class PictureInPictureToggle extends Button {
async handleClick(event) {
let mediaElement = this.player_.el().firstChild();
// disable button during picture-in-picture switch
this.disable();
// switch picture-in-picture mode
try {
if (mediaElement !== document.pictureInPictureElement) {
// request picture-in-picture
await mediaElement.requestPictureInPicture();
} else {
// exit picture-in-picture
await document.exitPictureInPicture();
}
} catch (error) {
// notify listeners
this.player_.trigger('error', error);
} finally {
// switch completed
this.enable();
}
}
}
It's now supported in the videojs-record plugin, e.g.
Demo: https://collab-project.github.io/videojs-record/examples/picture-in-picture.html
And it's really cool to see a video element flip to an external window so easily.
I think PiP should be part of video.js, not just a plugin.
Yes this should be a good feature .
Yeah, this is definitely something we'll look into.
Put together a really rough version to test just using the airplay icon works in Safari and Chrome not Firefox.
~~~
(function(vjs) {
var pipPlugin = function(options) {
var player = this;
// Needed if the player is loaded multiple times before being disposed
if (!player.el()) {
return;
}
// VIDEO EL::
var video = player.player().el().getElementsByTagName('video')[0];
if (video.webkitSupportsPresentationMode && typeof video.webkitSetPresentationMode === "function" || ('pictureInPictureEnabled' in document)) {
var pipToggle = videojs.getComponent("Button");
var pipButton = videojs.extend(pipToggle, {
constructor: function(player, options) {
pipToggle.call(this, player, options);
this.controlText("Picture-in-Picture");
},
handleClick: function() {
if(('pictureInPictureEnabled' in document)){
video.requestPictureInPicture();
}else{
video.webkitSetPresentationMode('picture-in-picture');
}
},
buildCSSClass: function() {
return "vjs-icon-airplay vjs-control vjs-button";
}
});
videojs.registerComponent("pipToggle", pipButton);
// WAIT FOR LOAD::
player.on('loadeddata', function() {
var pipToggleBtn = player.controlBar.addChild('pipToggle', {});
player.controlBar.el().insertBefore(pipToggleBtn.el(), player.controlBar.fullscreenToggle.el());
});
}
};
vjs.registerPlugin('pipPlugin', pipPlugin);
})(window.videojs);
~~~
@gkatsev What is the status for this feature? I'd love to see built-in support for PiP in video.js.
This week I'll be working on an actual roadmap for Video.js. This will definitely be on it. Unfortunately, I can't promise that it'll be prioritized over other work that we want or need to do.
@gkatsev Thanks for the update.
I'll be happy to review the Picture-in-Picture PR if needed.
Any updates on this....
I see it in players like https://plyr.io/ and i believe it should be here first....
This is on the team's backlog but, unfortunately, there's a lot of work that is higher priority (https://github.com/videojs/http-streaming/milestone/3 and more).
When the core team gets started on this, we'll definitely post here.
However, until that happens, if anyone wants to work on this, feel free to ping me here on on our slack and I can help go over the requirements for it. (If I have time, I'll write out a spec in this issue but may not get around to it without a nudge).
@gkatsev I'd love to help actually. Please write down requirements in this issue and I'll start working on it.
Below is the req for it. I think it can be done in at least 4 stages, it's better to have it done in many PRs rather than one giant PR. Also, I'd wait a couple of days before starting so that people can add comments on the req below (feel free to add comments yourself as well) and I'll update as necessary.
I think this can be done in a few stages:
The spec is here: https://wicg.github.io/picture-in-picture
There's also a good writeup on the google dev website https://developers.google.com/web/updates/2018/10/watch-video-using-picture-in-picture
requestPictureInPicture methodsexitPictureInPicture methodsisInPictureInPicture which returns whether we're in a PiP right now or notenterpictureinpicture, leavepictureinpicture) on the playerSafari has their own implementation. For it, we need to update the requestPictureInPicture and exitPictureInPicture methods appropriately.
Safari's API is here: https://developer.apple.com/library/archive/releasenotes/General/WhatsNewInSafari/Articles/Safari_9_0.html#//apple_ref/doc/uid/TP40014305-CH9-SW18
exitPictureInPicture method for safarienterpictureinpicture, leavepictureinpicture) if we're in safariAdd autoPictureInPicture and disablePictureInPicture as allowed options in html5.js.
This button should function similarly to the fullscreen toggle button
document.pictureInPictureEnabled is falseAlso, feel free to drop by our slack for more real-time chat :)
I've started implemented Picture-in-Picture. You should see some PRs popping up soon.
For info, I wrote https://developers.google.com/web/updates/2018/10/watch-video-using-picture-in-picture ;)
@beaufortfrancois hahaha, I totally didn't make the connection, super appreciate the help!
what's the status of this? does 7.6.0 contain all functionality?
7.6 contains the button and the WICG-specced API. It won't work in Safari currently, but that could be added at a later date (or safari could ship the WICG API).
hello guys , thanks a lot for this feature, but i think we need to show subtitle in picture-in-picture mode

@osamaalnuimi Subtitles are not supported yet in Picture-in-Picture in Chrome. They are in Safari though.
You can star bug at https://bugs.chromium.org/p/chromium/issues/detail?id=854935
Thanks for the answer @beaufortfrancois!
At some point, video.js will need to switch over to native text tracks when captions in PiP is supported (or at least switch to native tracks when using the PiP). Right now, native support is severely lacking (something I'm trying to fix).
@gkatsev I noticed the PiP button is always visible but disabled in browsers that do no support it. Is this intentional? I find it kind of confusing and rather hide it in places where it's unsupported. I can do this manually of course but I wonder why a non-functional button is part of the controlbar in some browsers.
Yeah, I think it's an oversight, it makes sense to leave it out on browsers that don't support it at all and have it be disabled if the iframe/page disables it.
Firefox 69 Beta enables PiP but for windows only: https://hacks.mozilla.org/2019/07/testing-picture-in-picture-for-videos-in-firefox-69/
So is there a method for disabling picture in picture? I'm not seeing anything here: https://docs.videojs.com/tutorial-options.html
@MrWiLofDoom you can pass in the following option to hide the button: https://github.com/videojs/video.js/pull/6002#issuecomment-510620446
Please add:
{
controlBar: {
'pictureInPictureToggle': false
}
}
to the docs at: https://docs.videojs.com/docs/guides/options.html -- Ah, found it here: https://docs.videojs.com/docs/guides/components.html
Most helpful comment
Yeah, this is definitely something we'll look into.