diff --git a/readme.md b/readme.md index 1653f65d..2503b5fb 100644 --- a/readme.md +++ b/readme.md @@ -417,7 +417,7 @@ player.fullscreen.active; // false; | `language` | ✓ | ✓ | Gets or sets the preferred captions language for the player. The setter accepts an ISO two-letter language code. Support for the languages is dependent on the captions you include. If your captions don't have any language data, or if you have multiple tracks with the same language, you may want to use `currentTrack` instead. | | `fullscreen.active` | ✓ | - | Returns a boolean indicating if the current player is in fullscreen mode. | | `fullscreen.enabled` | ✓ | - | Returns a boolean indicating if the current player has fullscreen enabled. | -| `pip` | ✓ | ✓ | Gets or sets the picture-in-picture state of the player. The setter accepts a boolean. This currently only supported on Safari 10+ on MacOS Sierra+ and iOS 10+. | +| `pip` | ✓ | ✓ | Gets or sets the picture-in-picture state of the player. The setter accepts a boolean. This currently only supported on Safari 10+ (on MacOS Sierra+ and iOS 10+) and Chrome 70+. | 1. YouTube only. HTML5 will follow. 2. HTML5 only diff --git a/src/js/config/states.js b/src/js/config/states.js new file mode 100644 index 00000000..7dd1476b --- /dev/null +++ b/src/js/config/states.js @@ -0,0 +1,10 @@ +// ========================================================================== +// Plyr states +// ========================================================================== + +export const pip = { + active: 'picture-in-picture', + inactive: 'inline', +}; + +export default { pip }; diff --git a/src/js/plyr.js b/src/js/plyr.js index 3824f38d..9dadfb5f 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -7,6 +7,7 @@ import captions from './captions'; import defaults from './config/defaults'; +import { pip } from './config/states'; import { getProviderByUrl, providers, types } from './config/types'; import Console from './console'; import controls from './controls'; @@ -896,21 +897,28 @@ class Plyr { * TODO: detect outside changes */ set pip(input) { - const states = { - pip: 'picture-in-picture', - inline: 'inline', - }; - // Bail if no support if (!support.pip) { return; } // Toggle based on current state if not passed - const toggle = is.boolean(input) ? input : this.pip === states.inline; + const toggle = is.boolean(input) ? input : !this.pip; // Toggle based on current state - this.media.webkitSetPresentationMode(toggle ? states.pip : states.inline); + // Safari + if (is.function(this.media.webkitSetPresentationMode)) { + this.media.webkitSetPresentationMode(toggle ? pip.active : pip.inactive); + } + + // Chrome + if (is.function(this.media.requestPictureInPicture)) { + if (!this.pip && toggle) { + this.media.requestPictureInPicture(); + } else if (this.pip && !toggle) { + document.exitPictureInPicture(); + } + } } /** @@ -921,7 +929,13 @@ class Plyr { return null; } - return this.media.webkitPresentationMode; + // Safari + if (!is.empty(this.media.webkitPresentationMode)) { + return this.media.webkitPresentationMode === pip.active; + } + + // Chrome + return this.media === document.pictureInPictureElement; } /** diff --git a/src/js/support.js b/src/js/support.js index 6395293f..59f27c3b 100644 --- a/src/js/support.js +++ b/src/js/support.js @@ -36,8 +36,26 @@ const support = { }, // Picture-in-picture support - // Safari only currently - pip: (() => !browser.isIPhone && is.function(createElement('video').webkitSetPresentationMode))(), + // Safari & Chrome only currently + pip: (() => { + if (browser.isIPhone) { + return false; + } + + // Safari + // https://developer.apple.com/documentation/webkitjs/adding_picture_in_picture_to_your_safari_media_controls + if (is.function(createElement('video').webkitSetPresentationMode)) { + return true; + } + + // Chrome + // https://developers.google.com/web/updates/2018/10/watch-video-using-picture-in-picture + if (document.pictureInPictureEnabled && !createElement('video').disablePictureInPicture) { + return true; + } + + return false; + })(), // Airplay support // Safari only currently