Added support for picture-in-picture in Chrome

This commit is contained in:
Sam Potts 2018-10-25 09:17:15 +11:00
parent df4bc268dc
commit fe26d383f1
4 changed files with 53 additions and 11 deletions

View File

@ -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. | | `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.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. | | `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. 1. YouTube only. HTML5 will follow.
2. HTML5 only 2. HTML5 only

10
src/js/config/states.js Normal file
View File

@ -0,0 +1,10 @@
// ==========================================================================
// Plyr states
// ==========================================================================
export const pip = {
active: 'picture-in-picture',
inactive: 'inline',
};
export default { pip };

View File

@ -7,6 +7,7 @@
import captions from './captions'; import captions from './captions';
import defaults from './config/defaults'; import defaults from './config/defaults';
import { pip } from './config/states';
import { getProviderByUrl, providers, types } from './config/types'; import { getProviderByUrl, providers, types } from './config/types';
import Console from './console'; import Console from './console';
import controls from './controls'; import controls from './controls';
@ -896,21 +897,28 @@ class Plyr {
* TODO: detect outside changes * TODO: detect outside changes
*/ */
set pip(input) { set pip(input) {
const states = {
pip: 'picture-in-picture',
inline: 'inline',
};
// Bail if no support // Bail if no support
if (!support.pip) { if (!support.pip) {
return; return;
} }
// Toggle based on current state if not passed // 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 // 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 null;
} }
return this.media.webkitPresentationMode; // Safari
if (!is.empty(this.media.webkitPresentationMode)) {
return this.media.webkitPresentationMode === pip.active;
}
// Chrome
return this.media === document.pictureInPictureElement;
} }
/** /**

View File

@ -36,8 +36,26 @@ const support = {
}, },
// Picture-in-picture support // Picture-in-picture support
// Safari only currently // Safari & Chrome only currently
pip: (() => !browser.isIPhone && is.function(createElement('video').webkitSetPresentationMode))(), 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 // Airplay support
// Safari only currently // Safari only currently