Added support for picture-in-picture in Chrome
This commit is contained in:
parent
df4bc268dc
commit
fe26d383f1
@ -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
10
src/js/config/states.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// ==========================================================================
|
||||||
|
// Plyr states
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
export const pip = {
|
||||||
|
active: 'picture-in-picture',
|
||||||
|
inactive: 'inline',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default { pip };
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user