- 1 :
/**
- 2 :
* @file picture-in-picture-toggle.js
- 3 :
*/
- 4 :
import Button from '../button.js';
- 5 :
import Component from '../component.js';
- 6 :
import document from 'global/document';
- 7 :
import window from 'global/window';
- 8 :
- 9 :
/**
- 10 :
* Toggle Picture-in-Picture mode
- 11 :
*
- 12 :
* @extends Button
- 13 :
*/
- 14 :
class PictureInPictureToggle extends Button {
- 15 :
- 16 :
/**
- 17 :
* Creates an instance of this class.
- 18 :
*
- 19 :
* @param { import('./player').default } player
- 20 :
* The `Player` that this class should be attached to.
- 21 :
*
- 22 :
* @param {Object} [options]
- 23 :
* The key/value store of player options.
- 24 :
*
- 25 :
* @listens Player#enterpictureinpicture
- 26 :
* @listens Player#leavepictureinpicture
- 27 :
*/
- 28 :
constructor(player, options) {
- 29 :
super(player, options);
- 30 :
this.on(player, ['enterpictureinpicture', 'leavepictureinpicture'], (e) => this.handlePictureInPictureChange(e));
- 31 :
this.on(player, ['disablepictureinpicturechanged', 'loadedmetadata'], (e) => this.handlePictureInPictureEnabledChange(e));
- 32 :
- 33 :
this.on(player, ['loadedmetadata', 'audioonlymodechange', 'audiopostermodechange'], () => {
- 34 :
// This audio detection will not detect HLS or DASH audio-only streams because there was no reliable way to detect them at the time
- 35 :
const isSourceAudio = player.currentType().substring(0, 5) === 'audio';
- 36 :
- 37 :
if (isSourceAudio || player.audioPosterMode() || player.audioOnlyMode()) {
- 38 :
if (player.isInPictureInPicture()) {
- 39 :
player.exitPictureInPicture();
- 40 :
}
- 41 :
this.hide();
- 42 :
} else {
- 43 :
this.show();
- 44 :
}
- 45 :
- 46 :
});
- 47 :
- 48 :
// TODO: Deactivate button on player emptied event.
- 49 :
this.disable();
- 50 :
}
- 51 :
- 52 :
/**
- 53 :
* Builds the default DOM `className`.
- 54 :
*
- 55 :
* @return {string}
- 56 :
* The DOM `className` for this object.
- 57 :
*/
- 58 :
buildCSSClass() {
- 59 :
return `vjs-picture-in-picture-control ${super.buildCSSClass()}`;
- 60 :
}
- 61 :
- 62 :
/**
- 63 :
* Enables or disables button based on availability of a Picture-In-Picture mode.
- 64 :
*
- 65 :
* Enabled if
- 66 :
* - `player.options().enableDocumentPictureInPicture` is true and
- 67 :
* window.documentPictureInPicture is available; or
- 68 :
* - `player.disablePictureInPicture()` is false and
- 69 :
* element.requestPictureInPicture is available
- 70 :
*/
- 71 :
handlePictureInPictureEnabledChange() {
- 72 :
if (
- 73 :
(document.pictureInPictureEnabled && this.player_.disablePictureInPicture() === false) ||
- 74 :
(this.player_.options_.enableDocumentPictureInPicture && 'documentPictureInPicture' in window)
- 75 :
) {
- 76 :
this.enable();
- 77 :
} else {
- 78 :
this.disable();
- 79 :
}
- 80 :
}
- 81 :
- 82 :
/**
- 83 :
* Handles enterpictureinpicture and leavepictureinpicture on the player and change control text accordingly.
- 84 :
*
- 85 :
* @param {Event} [event]
- 86 :
* The {@link Player#enterpictureinpicture} or {@link Player#leavepictureinpicture} event that caused this function to be
- 87 :
* called.
- 88 :
*
- 89 :
* @listens Player#enterpictureinpicture
- 90 :
* @listens Player#leavepictureinpicture
- 91 :
*/
- 92 :
handlePictureInPictureChange(event) {
- 93 :
if (this.player_.isInPictureInPicture()) {
- 94 :
this.controlText('Exit Picture-in-Picture');
- 95 :
} else {
- 96 :
this.controlText('Picture-in-Picture');
- 97 :
}
- 98 :
this.handlePictureInPictureEnabledChange();
- 99 :
}
- 100 :
- 101 :
/**
- 102 :
* This gets called when an `PictureInPictureToggle` is "clicked". See
- 103 :
* {@link ClickableComponent} for more detailed information on what a click can be.
- 104 :
*
- 105 :
* @param {Event} [event]
- 106 :
* The `keydown`, `tap`, or `click` event that caused this function to be
- 107 :
* called.
- 108 :
*
- 109 :
* @listens tap
- 110 :
* @listens click
- 111 :
*/
- 112 :
handleClick(event) {
- 113 :
if (!this.player_.isInPictureInPicture()) {
- 114 :
this.player_.requestPictureInPicture();
- 115 :
} else {
- 116 :
this.player_.exitPictureInPicture();
- 117 :
}
- 118 :
}
- 119 :
- 120 :
}
- 121 :
- 122 :
/**
- 123 :
* The text that should display over the `PictureInPictureToggle`s controls. Added for localization.
- 124 :
*
- 125 :
* @type {string}
- 126 :
* @protected
- 127 :
*/
- 128 :
PictureInPictureToggle.prototype.controlText_ = 'Picture-in-Picture';
- 129 :
- 130 :
Component.registerComponent('PictureInPictureToggle', PictureInPictureToggle);
- 131 :
export default PictureInPictureToggle;