From 0e177edda03b50d8ab3f5c8699c9e79d464321a5 Mon Sep 17 00:00:00 2001 From: mister-ben Date: Wed, 8 Feb 2023 09:53:41 +0100 Subject: [PATCH 01/18] feat: Add document picture-in-picture support --- sandbox/docpip.html.example | 49 +++++++++++++++++++ src/css/components/_layout.scss | 21 ++++++-- src/css/components/_poster.scss | 3 +- .../control-bar/picture-in-picture-toggle.js | 6 ++- src/js/player.js | 41 +++++++++++++++- 5 files changed, 113 insertions(+), 7 deletions(-) create mode 100644 sandbox/docpip.html.example diff --git a/sandbox/docpip.html.example b/sandbox/docpip.html.example new file mode 100644 index 0000000000..92657f93e8 --- /dev/null +++ b/sandbox/docpip.html.example @@ -0,0 +1,49 @@ + + + + + Video.js Sandbox + + + + +
+

You can use /sandbox/ for writing and testing your own code. Nothing in /sandbox/ will get checked into the repo, except files that end in .example (so don't edit or add those files). To get started run `npm start` and open the index.html

+
npm start
+
open http://localhost:9999/sandbox/index.html
+
+ + + + + + + + diff --git a/src/css/components/_layout.scss b/src/css/components/_layout.scss index 0a663fde77..d141ab7bda 100644 --- a/src/css/components/_layout.scss +++ b/src/css/components/_layout.scss @@ -119,13 +119,15 @@ display: none; } -// Fullscreen Styles -body.vjs-full-window { +// Fullscreen and Document Picture-in-Picture Styles +body.vjs-full-window, +body.vjs-pip-window { padding: 0; margin: 0; height: 100%; } -.vjs-full-window .video-js.vjs-fullscreen { +.vjs-full-window .video-js.vjs-fullscreen, +body.vjs-pip-window .video-js { position: fixed; overflow: hidden; z-index: 1000; @@ -134,7 +136,8 @@ body.vjs-full-window { bottom: 0; right: 0; } -.video-js.vjs-fullscreen:not(.vjs-ios-native-fs) { +.video-js.vjs-fullscreen:not(.vjs-ios-native-fs), +body.vjs-pip-window .video-js { width: 100% !important; height: 100% !important; // Undo any aspect ratio padding for fluid layouts @@ -145,6 +148,16 @@ body.vjs-full-window { cursor: none; } +.vjs-pip-container .vjs-pip-text { + position: absolute; + bottom: 10%; + font-size: 2em; /* Needs sizes for responsive classes */ + background-color: rgba(0, 0, 0, .7); + padding: .5em; + text-align: center; + width: 100% +} + // Hide disabled or unsupported controls. .vjs-hidden { display: none !important; } diff --git a/src/css/components/_poster.scss b/src/css/components/_poster.scss index ba77026332..d1f1d224a9 100644 --- a/src/css/components/_poster.scss +++ b/src/css/components/_poster.scss @@ -20,7 +20,8 @@ // Don't hide the poster if we're playing audio or when audio-poster-mode is true .vjs-audio.vjs-has-started .vjs-poster, -.vjs-has-started.vjs-audio-poster-mode .vjs-poster { +.vjs-has-started.vjs-audio-poster-mode .vjs-poster, +.vjs-pip-container.vjs-has-started .vjs-poster { display: block; } diff --git a/src/js/control-bar/picture-in-picture-toggle.js b/src/js/control-bar/picture-in-picture-toggle.js index cadafbe041..869f6061f2 100644 --- a/src/js/control-bar/picture-in-picture-toggle.js +++ b/src/js/control-bar/picture-in-picture-toggle.js @@ -4,6 +4,7 @@ import Button from '../button.js'; import Component from '../component.js'; import document from 'global/document'; +import window from 'global/window'; /** * Toggle Picture-in-Picture mode @@ -63,7 +64,10 @@ class PictureInPictureToggle extends Button { * or on value returned by player.disablePictureInPicture() method. */ handlePictureInPictureEnabledChange() { - if (document.pictureInPictureEnabled && this.player_.disablePictureInPicture() === false) { + if ( + (document.pictureInPictureEnabled && this.player_.disablePictureInPicture() === false) || + (this.player_.options_.preferDocumentPictureInPicture && 'documentPictureInPicture' in window) + ) { this.enable(); } else { this.disable(); diff --git a/src/js/player.js b/src/js/player.js index cc886944e4..f126914d6d 100644 --- a/src/js/player.js +++ b/src/js/player.js @@ -3031,6 +3031,42 @@ class Player extends Component { * A promise with a Picture-in-Picture window. */ requestPictureInPicture() { + if (this.options_.preferDocumentPictureInPicture && 'documentPictureInPicture' in window) { + const pipContainer = document.createElement(this.el().tagName); + + pipContainer.classList = this.el().classList; + pipContainer.classList.add('vjs-pip-container'); + if (this.posterImage) { + pipContainer.appendChild(this.posterImage.el().cloneNode(true)); + } + if (this.titleBar) { + pipContainer.appendChild(this.titleBar.el().cloneNode(true)); + } + pipContainer.appendChild(Dom.createEl('p', { className: 'vjs-pip-text' }, {}, this.localize('Playing in picture-in-picture'))); + + window.documentPictureInPicture.requestWindow({ + // This aspect ratio doesn't seem to be respected + initialAspectRatio: this.videoWidth() / this.videoHeight(), + copyStyleSheets: true + }).then(pipWindow => { + this.el_.parentNode.insertBefore(pipContainer, this.el_); + + pipWindow.document.title = 'Video.js'; + pipWindow.document.body.append(this.el_); + pipWindow.document.body.classList.add('vjs-pip-window'); + + this.player_.isInPictureInPicture(true); + + // Listen for the PiP closing event to move the video back. + pipWindow.addEventListener('unload', (event) => { + const pipVideo = event.target.querySelector('.video-js'); + + pipContainer.replaceWith(pipVideo); + this.player_.isInPictureInPicture(false); + }); + }); + return; + } if ('pictureInPictureEnabled' in document && this.disablePictureInPicture() === false) { /** * This event fires when the player enters picture in picture mode @@ -3053,7 +3089,10 @@ class Player extends Component { * A promise. */ exitPictureInPicture() { - if ('pictureInPictureEnabled' in document) { + if (window.documentPictureInPicture && window.documentPictureInPicture.window) { + window.documentPictureInPicture.window.close(); + return; + } else if ('pictureInPictureEnabled' in document) { /** * This event fires when the player leaves picture in picture mode * From ee56466318b99edd9126c0d87e69e121d14f6872 Mon Sep 17 00:00:00 2001 From: mister-ben Date: Wed, 8 Feb 2023 10:07:36 +0100 Subject: [PATCH 02/18] add origin trial token --- index.html | 1 + sandbox/docpip.html.example | 3 +++ 2 files changed, 4 insertions(+) diff --git a/index.html b/index.html index 9a5cbe77d5..108f3c33d6 100644 --- a/index.html +++ b/index.html @@ -27,6 +27,7 @@

Navigation

  • QualityLevels Demo
  • Autoplay Tests
  • noUITitleAttributes Demo
  • +
  • Document Picture-In-Picture Demo
  • Videojs debug build test page
  • diff --git a/sandbox/docpip.html.example b/sandbox/docpip.html.example index 92657f93e8..d918a70aec 100644 --- a/sandbox/docpip.html.example +++ b/sandbox/docpip.html.example @@ -5,6 +5,7 @@ Video.js Sandbox +
    @@ -13,6 +14,8 @@
    open http://localhost:9999/sandbox/index.html
    +

    Docuemnt Picture-in-Picture is available in Chrome version 111 onwards.

    + Date: Thu, 16 Feb 2023 18:50:52 +0100 Subject: [PATCH 03/18] Update sandbox/docpip.html.example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: François Beaufort --- sandbox/docpip.html.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sandbox/docpip.html.example b/sandbox/docpip.html.example index d918a70aec..1cc67f45f6 100644 --- a/sandbox/docpip.html.example +++ b/sandbox/docpip.html.example @@ -14,7 +14,7 @@
    open http://localhost:9999/sandbox/index.html
    -

    Docuemnt Picture-in-Picture is available in Chrome version 111 onwards.

    +

    Document Picture-in-Picture is available in Chrome version 111 onwards.

    Date: Wed, 22 Feb 2023 18:30:07 +0100 Subject: [PATCH 04/18] Localisation --- lang/de.json | 3 ++- lang/en.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lang/de.json b/lang/de.json index 110684e966..03830e5ed7 100644 --- a/lang/de.json +++ b/lang/de.json @@ -90,6 +90,7 @@ "Color": "Farbe", "Opacity": "Deckkraft", "Text Background": "Texthintergrund", - "Caption Area Background": "Hintergrund des Untertitelbereichs" + "Caption Area Background": "Hintergrund des Untertitelbereichs", + "Playing in Picture-in-Picture": "Wird im Bild-im-Bild-Modus wiedergegeben" } diff --git a/lang/en.json b/lang/en.json index 308a0bb1e8..166ebf4537 100644 --- a/lang/en.json +++ b/lang/en.json @@ -90,5 +90,6 @@ "Color": "Color", "Opacity": "Opacity", "Text Background": "Text Background", - "Caption Area Background": "Caption Area Background" + "Caption Area Background": "Caption Area Background", + "Playing in Picture-in-Picture": "Playing in Picture-in-Picture" } From 933fd15a8e47f0259be2a985aa2dd727956f746b Mon Sep 17 00:00:00 2001 From: mister-ben Date: Wed, 22 Feb 2023 18:30:29 +0100 Subject: [PATCH 05/18] Hide fullscreen/pip in pip --- src/css/components/_fullscreen.scss | 3 ++- src/css/components/_picture-in-picture.scss | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/css/components/_fullscreen.scss b/src/css/components/_fullscreen.scss index a9deba41f1..f682341818 100644 --- a/src/css/components/_fullscreen.scss +++ b/src/css/components/_fullscreen.scss @@ -7,7 +7,8 @@ } } -.video-js.vjs-audio-only-mode .vjs-fullscreen-control { +.video-js.vjs-audio-only-mode .vjs-fullscreen-control, +.vjs-pip-window .vjs-fullscreen-control { display: none; } diff --git a/src/css/components/_picture-in-picture.scss b/src/css/components/_picture-in-picture.scss index cfba09b928..5992407361 100644 --- a/src/css/components/_picture-in-picture.scss +++ b/src/css/components/_picture-in-picture.scss @@ -7,7 +7,8 @@ } } -.video-js.vjs-audio-only-mode .vjs-picture-in-picture-control { +.video-js.vjs-audio-only-mode .vjs-picture-in-picture-control, +.vjs-pip-window .vjs-picture-in-picture-control { display: none; } From 7875d1b8fe467982ff2836797b8a2f9f87034da3 Mon Sep 17 00:00:00 2001 From: mister-ben Date: Wed, 22 Feb 2023 18:31:04 +0100 Subject: [PATCH 06/18] Match elPiP events, promises --- sandbox/docpip.html.example | 2 +- .../control-bar/picture-in-picture-toggle.js | 11 ++-- src/js/player.js | 54 ++++++++++++------- 3 files changed, 43 insertions(+), 24 deletions(-) diff --git a/sandbox/docpip.html.example b/sandbox/docpip.html.example index 1cc67f45f6..724aa58868 100644 --- a/sandbox/docpip.html.example +++ b/sandbox/docpip.html.example @@ -27,7 +27,7 @@