/
VideoView.js
114 lines (114 loc) · 4.21 KB
/
VideoView.js
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import { PureComponent, createRef, useRef, useMemo, useEffect, } from 'react';
import NativeVideoModule from './NativeVideoModule';
import NativeVideoView from './NativeVideoView';
/**
* Creates a `VideoPlayer`, which will be automatically cleaned up when the component is unmounted.
* @param source - A video source to initialize the player with
* @param setup - A function that allows setting up the player. It will run after the player is created.
*/
export function useVideoPlayer(source, setup) {
const parsedSource = typeof source === 'string' ? { uri: source } : source;
return useReleasingSharedObject(() => {
const player = new NativeVideoModule.VideoPlayer(parsedSource);
setup?.(player);
return player;
}, [JSON.stringify(parsedSource)]);
}
/**
* Returns whether the current device supports Picture in Picture (PiP) mode.
* @returns A `boolean` which is `true` if the device supports PiP mode, and `false` otherwise.
* @platform android
* @platform ios
*/
export function isPictureInPictureSupported() {
return NativeVideoModule.isPictureInPictureSupported();
}
export class VideoView extends PureComponent {
nativeRef = createRef();
/**
* Enters fullscreen mode.
*/
enterFullscreen() {
this.nativeRef.current?.enterFullscreen();
}
/**
* Exits fullscreen mode.
*/
exitFullscreen() {
this.nativeRef.current?.exitFullscreen();
}
/**
* Enters Picture in Picture (PiP) mode. Throws an exception if the device does not support PiP.
* > **Note:** Only one player can be in Picture in Picture (PiP) mode at a time.
* @platform android
* @platform ios 14+
*/
startPictureInPicture() {
return this.nativeRef.current?.startPictureInPicture();
}
/**
* Exits Picture in Picture (PiP) mode.
* @platform android
* @platform ios 14+
*/
stopPictureInPicture() {
return this.nativeRef.current?.stopPictureInPicture();
}
render() {
const { player, ...props } = this.props;
const playerId = getPlayerId(player);
return <NativeVideoView {...props} player={playerId} ref={this.nativeRef}/>;
}
}
// Temporary solution to pass the shared object ID instead of the player object.
// We can't really pass it as an object in the old architecture.
// Technically we can in the new architecture, but it's not possible yet.
function getPlayerId(player) {
if (player instanceof NativeVideoModule.VideoPlayer) {
// @ts-expect-error
return player.__expo_shared_object_id__;
}
if (typeof player === 'number') {
return player;
}
return null;
}
/**
* Returns a shared object, which is automatically cleaned up when the component is unmounted.
*/
function useReleasingSharedObject(factory, dependencies) {
const objectRef = useRef(null);
const isFastRefresh = useRef(false);
const previousDependencies = useRef(dependencies);
if (objectRef.current == null) {
objectRef.current = factory();
}
const object = useMemo(() => {
let newObject = objectRef.current;
const dependenciesAreEqual = previousDependencies.current?.length === dependencies.length &&
dependencies.every((value, index) => value === previousDependencies.current[index]);
// If the dependencies have changed, release the previous object and create a new one, otherwise this has been called
// because of a fast refresh, and we don't want to release the object.
if (!newObject || !dependenciesAreEqual) {
objectRef.current?.release();
newObject = factory();
objectRef.current = newObject;
previousDependencies.current = dependencies;
}
else {
isFastRefresh.current = true;
}
return newObject;
}, dependencies);
useEffect(() => {
isFastRefresh.current = false;
return () => {
// This will be called on every fast refresh and on unmount, but we only want to release the object on unmount.
if (!isFastRefresh.current && objectRef.current) {
objectRef.current.release();
}
};
}, []);
return object;
}
//# sourceMappingURL=VideoView.js.map