diff --git a/packages/core/src/buffer-until-first-frame.ts b/packages/core/src/buffer-until-first-frame.ts index 4b37bc30acf..7462e818294 100644 --- a/packages/core/src/buffer-until-first-frame.ts +++ b/packages/core/src/buffer-until-first-frame.ts @@ -28,18 +28,40 @@ export const useBufferUntilFirstFrame = ({ } if (skipIfPaused && current.paused) { - console.log('not seeking because paused'); + return; } bufferingRef.current = true; const playback = delayPlayback(); - current.requestVideoFrameCallback((_, info2) => { - console.log('requestVideoFrameCallback', _, info2); - bufferingRef.current = false; + const unblock = () => { playback.unblock(); + current.removeEventListener('ended', unblock, { + // @ts-expect-error + once: true, + }); + current.removeEventListener('pause', unblock, { + // @ts-expect-error + once: true, + }); + }; + + const onEndedOrPause = () => { + unblock(); + }; + + current.requestVideoFrameCallback(() => { + // Safari often seeks and then stalls. + // This makes sure that the video actually starts playing. + current.requestVideoFrameCallback(() => { + bufferingRef.current = false; + unblock(); + }); }); + + current.addEventListener('ended', onEndedOrPause, {once: true}); + current.addEventListener('pause', onEndedOrPause, {once: true}); }, [delayPlayback, mediaRef, mediaType], ); diff --git a/packages/core/src/play-and-handle-not-allowed-error.ts b/packages/core/src/play-and-handle-not-allowed-error.ts index f3cd9446bd5..0c410f55467 100644 --- a/packages/core/src/play-and-handle-not-allowed-error.ts +++ b/packages/core/src/play-and-handle-not-allowed-error.ts @@ -54,9 +54,9 @@ export const playAndHandleNotAllowedError = ( console.log(`Could not play ${mediaType} due to following error: `, err); if (!current.muted) { // eslint-disable-next-line no-console - console.log(`The video will be muted and we'll retry playing it.`, err); + console.log(`The video will be muted and we'll retry playing it.`); current.muted = true; - current.play(); + playAndHandleNotAllowedError(mediaRef, mediaType); } }); } diff --git a/packages/core/src/use-request-video-callback-time.ts b/packages/core/src/use-request-video-callback-time.ts index e7b1c8f2d21..8f81598a67a 100644 --- a/packages/core/src/use-request-video-callback-time.ts +++ b/packages/core/src/use-request-video-callback-time.ts @@ -8,28 +8,39 @@ export const useRequestVideoCallbackTime = ( const currentTime = useRef(null); useEffect(() => { - if (mediaRef.current) { - currentTime.current = mediaRef.current.currentTime; + const {current} = mediaRef; + if (current) { + currentTime.current = current.currentTime; } else { currentTime.current = null; + return; } if (mediaType !== 'video') { currentTime.current = null; + return; + } + + const videoTag = current as HTMLVideoElement; + + if (!videoTag.requestVideoFrameCallback) { + return; } let cancel = () => undefined; const request = () => { - const cb = ( - mediaRef.current as HTMLVideoElement - ).requestVideoFrameCallback((_, info) => { + if (!videoTag) { + return; + } + + const cb = videoTag.requestVideoFrameCallback((_, info) => { currentTime.current = info.mediaTime; request(); }); cancel = () => { - (mediaRef.current as HTMLVideoElement)?.cancelVideoFrameCallback(cb); + videoTag.cancelVideoFrameCallback(cb); cancel = () => undefined; }; };