-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathWebPresentationModeManager.ts
More file actions
97 lines (88 loc) · 4.3 KB
/
Copy pathWebPresentationModeManager.ts
File metadata and controls
97 lines (88 loc) · 4.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import type { PlayerEventMap } from 'react-native-theoplayer';
import { PresentationMode } from 'react-native-theoplayer';
import type { ChromelessPlayer } from 'theoplayer';
import { DefaultPresentationModeChangeEvent } from '../event/PlayerEvents';
import type { DefaultEventDispatcher } from '../event/DefaultEventDispatcher';
import { fullscreenAPI } from './FullscreenAPI';
import { noOp } from '../../utils/CommonUtils';
export class WebPresentationModeManager {
private readonly _player: ChromelessPlayer;
private _presentationMode: PresentationMode = PresentationMode.inline;
private _eventForwarder: DefaultEventDispatcher<PlayerEventMap>;
constructor(player: ChromelessPlayer, eventForwarder: DefaultEventDispatcher<PlayerEventMap>) {
this._player = player;
this._eventForwarder = eventForwarder;
this._player.presentation.addEventListener('presentationmodechange', this.updatePresentationMode);
this.maybePrepareForPresentationModeChanges();
}
get presentationMode(): PresentationMode {
return this._presentationMode;
}
set presentationMode(presentationMode: PresentationMode) {
if (presentationMode === this._presentationMode) {
// Ignore if presentationMode did not change.
return;
}
if (fullscreenAPI !== undefined) {
// If the browser supports the fullscreenAPI, put the element that encloses the player & UI in fullscreen.
if (presentationMode === PresentationMode.fullscreen) {
const appElement = document.getElementById('theoplayer-root-container');
if (appElement !== null) {
appElement[fullscreenAPI.requestFullscreen_]()?.then?.(noOp, noOp);
}
} else if (presentationMode === PresentationMode.pip) {
this._player.presentation.requestMode('native-picture-in-picture');
} else {
if (this._presentationMode === PresentationMode.fullscreen) {
document[fullscreenAPI.exitFullscreen_]()?.then?.(noOp, noOp);
}
if (this._presentationMode === PresentationMode.pip) {
this._player.presentation.requestMode(PresentationMode.inline);
}
}
} else {
// Some browsers, like iOS Safari, can only put a videoElement in fullscreen; let the player decide which one.
if (presentationMode === PresentationMode.fullscreen) {
this._player.presentation.requestMode(PresentationMode.fullscreen);
} else if (presentationMode === PresentationMode.pip) {
this._player.presentation.requestMode('native-picture-in-picture');
} else {
this._player.presentation.requestMode(PresentationMode.inline);
}
}
}
private maybePrepareForPresentationModeChanges() {
// listen for fullscreen updates on document
if (fullscreenAPI !== undefined) {
document.addEventListener(fullscreenAPI.fullscreenchange_, this.updatePresentationMode);
document.addEventListener(fullscreenAPI.fullscreenerror_, this.updatePresentationMode);
}
}
destroy(): void {
if (fullscreenAPI !== undefined) {
document.removeEventListener(fullscreenAPI.fullscreenchange_, this.updatePresentationMode);
document.removeEventListener(fullscreenAPI.fullscreenerror_, this.updatePresentationMode);
}
this._player?.presentation?.removeEventListener('presentationmodechange', this.updatePresentationMode);
}
private updatePresentationMode = () => {
// detect new presentation mode
let newPresentationMode: PresentationMode = PresentationMode.inline;
if (
// Check if we went into fullscreen using the fullscreen API.
(fullscreenAPI !== undefined && document[fullscreenAPI.fullscreenElement_] !== null) ||
// or otherwise using player APi
this._player.presentation.currentMode === PresentationMode.fullscreen
) {
newPresentationMode = PresentationMode.fullscreen;
} else if (this._player.presentation.currentMode === 'native-picture-in-picture') {
newPresentationMode = PresentationMode.pip;
}
// when changed, notify by dispatching presentationModeChange event
const previousPresentationMode = this._presentationMode;
if (newPresentationMode !== previousPresentationMode) {
this._presentationMode = newPresentationMode;
this._eventForwarder.dispatchEvent(new DefaultPresentationModeChangeEvent(this._presentationMode, previousPresentationMode));
}
};
}