Add most events
This commit is contained in:
parent
c6abcdeb2f
commit
f5fa063bc0
@ -14,10 +14,15 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
|
|||||||
paused,
|
paused,
|
||||||
muted,
|
muted,
|
||||||
volume,
|
volume,
|
||||||
|
showNotificationControls,
|
||||||
onBuffer,
|
onBuffer,
|
||||||
onLoad,
|
onLoad,
|
||||||
onProgress,
|
onProgress,
|
||||||
|
onPlaybackRateChange,
|
||||||
onError,
|
onError,
|
||||||
|
onReadyForDisplay,
|
||||||
|
onSeek,
|
||||||
|
onVolumeChange,
|
||||||
onEnd,
|
onEnd,
|
||||||
onPlaybackStateChanged,
|
onPlaybackStateChanged,
|
||||||
},
|
},
|
||||||
@ -27,16 +32,20 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
|
|||||||
const errorHandler = useRef<typeof onError>(onError);
|
const errorHandler = useRef<typeof onError>(onError);
|
||||||
errorHandler.current = onError;
|
errorHandler.current = onError;
|
||||||
|
|
||||||
const seek = useCallback(async (time: number, _tolerance?: number) => {
|
const seek = useCallback(
|
||||||
if (isNaN(time)) {
|
async (time: number, _tolerance?: number) => {
|
||||||
throw new Error('Specified time is not a number');
|
if (isNaN(time)) {
|
||||||
}
|
throw new Error('Specified time is not a number');
|
||||||
if (!nativeRef.current) {
|
}
|
||||||
console.warn('Video Component is not mounted');
|
if (!nativeRef.current) {
|
||||||
return;
|
console.warn('Video Component is not mounted');
|
||||||
}
|
return;
|
||||||
nativeRef.current.currentTime = time;
|
}
|
||||||
}, []);
|
nativeRef.current.currentTime = time;
|
||||||
|
onSeek?.({seekTime: time, currentTime: nativeRef.current.currentTime});
|
||||||
|
},
|
||||||
|
[onSeek],
|
||||||
|
);
|
||||||
|
|
||||||
const pause = useCallback(() => {
|
const pause = useCallback(() => {
|
||||||
if (!nativeRef.current) {
|
if (!nativeRef.current) {
|
||||||
@ -52,6 +61,20 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
|
|||||||
nativeRef.current.play();
|
nativeRef.current.play();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const setVolume = useCallback((vol: number) => {
|
||||||
|
if (!nativeRef.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nativeRef.current.volume = Math.max(0, Math.min(vol, 100)) / 100;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const getCurrentPosition = useCallback(async () => {
|
||||||
|
if (!nativeRef.current) {
|
||||||
|
throw new Error('Video Component is not mounted');
|
||||||
|
}
|
||||||
|
return nativeRef.current.currentTime;
|
||||||
|
}, []);
|
||||||
|
|
||||||
const unsupported = useCallback(() => {
|
const unsupported = useCallback(() => {
|
||||||
throw new Error('This is unsupported on the web');
|
throw new Error('This is unsupported on the web');
|
||||||
}, []);
|
}, []);
|
||||||
@ -62,14 +85,17 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
|
|||||||
seek,
|
seek,
|
||||||
pause,
|
pause,
|
||||||
resume,
|
resume,
|
||||||
|
setVolume,
|
||||||
|
getCurrentPosition,
|
||||||
// making the video fullscreen does not work with some subtitles polyfils
|
// making the video fullscreen does not work with some subtitles polyfils
|
||||||
// so I decided to not include it.
|
// so I decided to not include it.
|
||||||
presentFullscreenPlayer: unsupported,
|
presentFullscreenPlayer: unsupported,
|
||||||
dismissFullscreenPlayer: unsupported,
|
dismissFullscreenPlayer: unsupported,
|
||||||
|
setFullScreen: unsupported,
|
||||||
save: unsupported,
|
save: unsupported,
|
||||||
restoreUserInterfaceForPictureInPictureStopCompleted: unsupported,
|
restoreUserInterfaceForPictureInPictureStopCompleted: unsupported,
|
||||||
}),
|
}),
|
||||||
[seek, pause, resume, unsupported],
|
[seek, pause, resume, unsupported, setVolume, getCurrentPosition],
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -80,24 +106,31 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
|
|||||||
}
|
}
|
||||||
}, [paused, pause, resume]);
|
}, [paused, pause, resume]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!nativeRef.current || !volume) {
|
if (volume === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nativeRef.current.volume = Math.max(0, Math.min(volume, 100)) / 100;
|
setVolume(volume);
|
||||||
}, [volume]);
|
}, [volume, setVolume]);
|
||||||
|
|
||||||
const setPlay = useSetAtom(playAtom);
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!nativeRef.current) return;
|
// Not sure about how to do this but we want to wait for nativeRef to be initialized
|
||||||
// Set play state to the player's value (if autoplay is denied)
|
setTimeout(() => {
|
||||||
setPlay(!nativeRef.current.paused);
|
if (!nativeRef.current) {
|
||||||
}, [setPlay]);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const setProgress = useSetAtom(progressAtom);
|
// Set play state to the player's value (if autoplay is denied)
|
||||||
|
// This is useful if our UI is in a play state but autoplay got denied so
|
||||||
|
// the video is actaully in a paused state.
|
||||||
|
onPlaybackStateChanged?.({isPlaying: !nativeRef.current.paused});
|
||||||
|
}, 500);
|
||||||
|
}, [onPlaybackStateChanged]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<MediaSessionManager {...source.metadata} />
|
{showNotificationControls && (
|
||||||
|
<MediaSessionManager {...source.metadata} />
|
||||||
|
)}
|
||||||
<video
|
<video
|
||||||
ref={nativeRef}
|
ref={nativeRef}
|
||||||
src={source.uri as string | undefined}
|
src={source.uri as string | undefined}
|
||||||
@ -107,11 +140,30 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
|
|||||||
playsInline
|
playsInline
|
||||||
onCanPlay={() => onBuffer?.({isBuffering: false})}
|
onCanPlay={() => onBuffer?.({isBuffering: false})}
|
||||||
onWaiting={() => onBuffer?.({isBuffering: true})}
|
onWaiting={() => onBuffer?.({isBuffering: true})}
|
||||||
|
onRateChange={() => {
|
||||||
|
if (!nativeRef.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
onPlaybackRateChange?.({
|
||||||
|
playbackRate: nativeRef.current?.playbackRate,
|
||||||
|
});
|
||||||
|
}}
|
||||||
onDurationChange={() => {
|
onDurationChange={() => {
|
||||||
if (!nativeRef.current) {
|
if (!nativeRef.current) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
onLoad?.({duration: nativeRef.current.duration} as any);
|
onLoad?.({
|
||||||
|
currentTime: nativeRef.current.currentTime,
|
||||||
|
duration: nativeRef.current.duration,
|
||||||
|
videoTracks: [],
|
||||||
|
textTracks: [],
|
||||||
|
audioTracks: [],
|
||||||
|
naturalSize: {
|
||||||
|
width: nativeRef.current.videoWidth,
|
||||||
|
height: nativeRef.current.videoHeight,
|
||||||
|
orientation: 'landscape',
|
||||||
|
},
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
onTimeUpdate={() => {
|
onTimeUpdate={() => {
|
||||||
if (!nativeRef.current) {
|
if (!nativeRef.current) {
|
||||||
@ -127,6 +179,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
|
|||||||
seekableDuration: 0,
|
seekableDuration: 0,
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
onLoadedData={() => onReadyForDisplay?.()}
|
||||||
onError={() => {
|
onError={() => {
|
||||||
if (
|
if (
|
||||||
nativeRef?.current?.error?.code ===
|
nativeRef?.current?.error?.code ===
|
||||||
@ -147,6 +200,12 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
|
|||||||
}}
|
}}
|
||||||
onPlay={() => onPlaybackStateChanged?.({isPlaying: true})}
|
onPlay={() => onPlaybackStateChanged?.({isPlaying: true})}
|
||||||
onPause={() => onPlaybackStateChanged?.({isPlaying: false})}
|
onPause={() => onPlaybackStateChanged?.({isPlaying: false})}
|
||||||
|
onVolumeChange={() => {
|
||||||
|
if (!nativeRef.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
onVolumeChange?.({volume: nativeRef.current.volume});
|
||||||
|
}}
|
||||||
onEnded={onEnd}
|
onEnded={onEnd}
|
||||||
style={{position: 'absolute', inset: 0, objectFit: 'contain'}}
|
style={{position: 'absolute', inset: 0, objectFit: 'contain'}}
|
||||||
/>
|
/>
|
||||||
|
Loading…
Reference in New Issue
Block a user