Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for picture-in-picture API #5824

Open
thijstriemstra opened this issue Feb 26, 2019 · 26 comments
Open

Support for picture-in-picture API #5824

thijstriemstra opened this issue Feb 26, 2019 · 26 comments
Assignees

Comments

@thijstriemstra
Copy link
Contributor

thijstriemstra commented Feb 26, 2019

Description

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

@thijstriemstra
Copy link
Contributor Author

thijstriemstra commented Feb 27, 2019

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

@thijstriemstra
Copy link
Contributor Author

thijstriemstra commented Feb 28, 2019

It's now supported in the videojs-record plugin, e.g.

picture-in-picture

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.

@MR-AMDEV
Copy link

MR-AMDEV commented Mar 2, 2019

Yes this should be a good feature .

@gkatsev
Copy link
Member

gkatsev commented Mar 4, 2019

Yeah, this is definitely something we'll look into.

@samueleastdev
Copy link

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

@beaufortfrancois
Copy link
Contributor

@gkatsev What is the status for this feature? I'd love to see built-in support for PiP in video.js.

@gkatsev
Copy link
Member

gkatsev commented Apr 16, 2019

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.

@beaufortfrancois
Copy link
Contributor

@gkatsev Thanks for the update.
I'll be happy to review the Picture-in-Picture PR if needed.

@waakobrian
Copy link

Any updates on this....
I see it in players like https://plyr.io/ and i believe it should be here first....

@gkatsev
Copy link
Member

gkatsev commented May 17, 2019

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).

@beaufortfrancois
Copy link
Contributor

@gkatsev I'd love to help actually. Please write down requirements in this issue and I'll start working on it.

@gkatsev
Copy link
Member

gkatsev commented May 20, 2019

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:

  1. add the correct API methods
  2. support both the spec and custom implementations (this is for Safari as they aren't spec compliant yet)
  3. support the auto pip and disable pip options
  4. add in a control bar button

add the correct API methods

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

  • add requestPictureInPicture methods
    • player.js: should just do a techGet (as the native methods returns a promise, we want to be able to return it as well). We should also track whether we're in PiP or not similar to fullscreen.
    • tech.js: should be a no-op or throw an error (this is for when it's used by a tech that doesn't implement pip
    • html5.js: this should call the native method and respond handle the returned promise properly
  • add exitPictureInPicture methods
    • player.js: should call document.exitPictureInPicture
  • player.js: add isInPictureInPicture which returns whether we're in a PiP right now or not
  • should fail gracefully when on a browser with no support
  • make sure that you can listen to the PiP events (enterpictureinpicture, leavepictureinpicture) on the player

support both the spec and custom implementations (this is for Safari as they aren't spec compliant yet)

Safari 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

  • html5: requestPictureInPicture should call either the spec version of the safari version using feature detection
  • player.js: exitPictureInPicture should do a techCall if we're in safari, via feature detection
  • html5.js: add exitPictureInPicture method for safari
  • trigger custom PiP events (enterpictureinpicture, leavepictureinpicture) if we're in safari

support the auto pip and disable pip options

Add autoPictureInPicture and disablePictureInPicture as allowed options in html5.js.

add in a control bar button

This button should function similarly to the fullscreen toggle button

@gkatsev
Copy link
Member

gkatsev commented May 20, 2019

Also, feel free to drop by our slack for more real-time chat :)

@beaufortfrancois
Copy link
Contributor

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

@gkatsev
Copy link
Member

gkatsev commented May 21, 2019

@beaufortfrancois hahaha, I totally didn't make the connection, super appreciate the help!

gkatsev pushed a commit that referenced this issue Jun 11, 2019
Following #5824, this PR adds support for some Picture-in-Picture methods described in the spec and article. It also makes sure that we can listen to the enterpictureinpicture and leavepictureinpicture events on the player.
gkatsev pushed a commit that referenced this issue Jun 18, 2019
Adds a new PictureInPictureToggle component in the controls bar of the player. It depends on videojs-font 3.2.0 (videojs/font#41) for icons.

Final spec piece from #5824.
@thijstriemstra
Copy link
Contributor Author

what's the status of this? does 7.6.0 contain all functionality?

@gkatsev
Copy link
Member

gkatsev commented Jun 24, 2019

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).

@osamaalnuimi
Copy link

osamaalnuimi commented Jul 15, 2019

hello guys , thanks a lot for this feature, but i think we need to show subtitle in picture-in-picture mode

image

@beaufortfrancois
Copy link
Contributor

@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

@gkatsev
Copy link
Member

gkatsev commented Jul 15, 2019

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).

@thijstriemstra
Copy link
Contributor Author

@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.

@gkatsev
Copy link
Member

gkatsev commented Jul 15, 2019

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.

@thijstriemstra
Copy link
Contributor Author

Firefox 69 Beta enables PiP but for windows only: https://hacks.mozilla.org/2019/07/testing-picture-in-picture-for-videos-in-firefox-69/

@MrWiLofDoom
Copy link

So is there a method for disabling picture in picture? I'm not seeing anything here: https://docs.videojs.com/tutorial-options.html

@gkatsev
Copy link
Member

gkatsev commented Aug 6, 2019

@MrWiLofDoom you can pass in the following option to hide the button: #6002 (comment)

@q2apro
Copy link

q2apro commented Jan 8, 2020

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants