Add web support for fullscreen

This commit is contained in:
Zoe Roux 2024-07-10 17:18:21 +07:00
parent ffb4631854
commit fc5b2d4563
No known key found for this signature in database
3 changed files with 83 additions and 11 deletions

View File

@ -6,7 +6,7 @@ This page shows the list of available methods
### `dismissFullscreenPlayer` ### `dismissFullscreenPlayer`
<PlatformsList types={['Android', 'iOS']} /> <PlatformsList types={['Android', 'iOS', 'web']} />
`dismissFullscreenPlayer(): Promise<void>` `dismissFullscreenPlayer(): Promise<void>`
@ -25,7 +25,7 @@ Pause the video.
### `presentFullscreenPlayer` ### `presentFullscreenPlayer`
<PlatformsList types={['Android', 'iOS']} /> <PlatformsList types={['Android', 'iOS', 'web']} />
`presentFullscreenPlayer(): Promise<void>` `presentFullscreenPlayer(): Promise<void>`
@ -117,7 +117,7 @@ This function will throw an error if player is not initialized.
### `setFullScreen` ### `setFullScreen`
<PlatformsList types={['Android', 'iOS']} /> <PlatformsList types={['Android', 'iOS', 'web']} />
`setFullScreen(fullscreen): Promise<void>` `setFullScreen(fullscreen): Promise<void>`
@ -178,7 +178,7 @@ Possible values are:
### `isCodecSupported` ### `isCodecSupported`
<PlatformsList types={['Android']} /> <PlatformsList types={['Android', 'web']} />
Indicates whether the provided codec is supported level supported by device. Indicates whether the provided codec is supported level supported by device.

View File

@ -270,7 +270,7 @@ Whether this video view should be focusable with a non-touch input device, eg. r
### `fullscreen` ### `fullscreen`
<PlatformsList types={['Android', 'iOS', 'visionOS']} /> <PlatformsList types={['Android', 'iOS', 'visionOS', 'web']} />
Controls whether the player enters fullscreen on play. Controls whether the player enters fullscreen on play.
See [presentFullscreenPlayer](#presentfullscreenplayer) for details. See [presentFullscreenPlayer](#presentfullscreenplayer) for details.
@ -286,7 +286,7 @@ If a preferred [fullscreenOrientation](#fullscreenorientation) is set, causes th
### `fullscreenOrientation` ### `fullscreenOrientation`
<PlatformsList types={['iOS', 'visionOS']} /> <PlatformsList types={['iOS', 'visionOS', 'web']} />
- **all (default)** - - **all (default)** -
- **landscape** - **landscape**

View File

@ -20,6 +20,9 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
controls, controls,
showNotificationControls = false, showNotificationControls = false,
poster, poster,
fullscreen,
fullscreenAutorotate,
fullscreenOrientation,
onBuffer, onBuffer,
onLoad, onLoad,
onProgress, onProgress,
@ -83,6 +86,74 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
throw new Error('This is unsupported on the web'); throw new Error('This is unsupported on the web');
}, []); }, []);
// Stock this in a ref to not invalidate memoization when those changes.
const fsPrefs = useRef({
fullscreenAutorotate,
fullscreenOrientation,
});
fsPrefs.current = {
fullscreenOrientation,
fullscreenAutorotate,
};
const setFullScreen = useCallback(
(
newVal: boolean,
orientation?: ReactVideoProps['fullscreenOrientation'],
autorotate?: boolean,
) => {
orientation ??= fsPrefs.current.fullscreenOrientation;
autorotate ??= fsPrefs.current.fullscreenAutorotate;
const run = async () => {
try {
if (newVal) {
await nativeRef.current?.requestFullscreen({
navigationUI: 'hide',
});
if (orientation === 'all' || !orientation || autorotate) {
screen.orientation.unlock();
} else {
await screen.orientation.lock(orientation);
}
} else {
if (document.fullscreenElement) {
await document.exitFullscreen();
}
screen.orientation.unlock();
}
} catch (e) {
// Changing fullscreen status without a button click is not allowed so it throws.
// Some browsers also used to throw when locking screen orientation was not supported.
console.error('Could not toggle fullscreen/screen lock status', e);
}
};
run();
},
[],
);
useEffect(() => {
setFullScreen(
fullscreen || false,
fullscreenOrientation,
fullscreenAutorotate,
);
}, [
setFullScreen,
fullscreen,
fullscreenAutorotate,
fullscreenOrientation,
]);
const presentFullscreenPlayer = useCallback(
() => setFullScreen(true),
[setFullScreen],
);
const dismissFullscreenPlayer = useCallback(
() => setFullScreen(false),
[setFullScreen],
);
useImperativeHandle( useImperativeHandle(
ref, ref,
() => ({ () => ({
@ -91,11 +162,9 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
resume, resume,
setVolume, setVolume,
getCurrentPosition, getCurrentPosition,
// making the video fullscreen does not work with some subtitles polyfils presentFullscreenPlayer,
// so I decided to not include it. dismissFullscreenPlayer,
presentFullscreenPlayer: unsupported, setFullScreen,
dismissFullscreenPlayer: unsupported,
setFullScreen: unsupported,
save: unsupported, save: unsupported,
restoreUserInterfaceForPictureInPictureStopCompleted: unsupported, restoreUserInterfaceForPictureInPictureStopCompleted: unsupported,
nativeHtmlVideoRef: nativeRef, nativeHtmlVideoRef: nativeRef,
@ -108,6 +177,9 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
setVolume, setVolume,
getCurrentPosition, getCurrentPosition,
nativeRef, nativeRef,
presentFullscreenPlayer,
dismissFullscreenPlayer,
setFullScreen,
], ],
); );