From 39cd42f0035bbabdd9bb078fc8df9192f3b6c42f Mon Sep 17 00:00:00 2001 From: Oliver Lazoroski Date: Thu, 19 Oct 2023 10:51:27 +0200 Subject: [PATCH] fix: sync video "paused" state more accurately (#1150) In some cases, a stream may start playing before our `play` and `pause` event handlers are attached to the appropriate `video` element and our state will have incorrect values. In that case, we may incorrectly render a placeholder instead of the actual video. --- .../src/core/components/Video/Video.tsx | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/packages/react-sdk/src/core/components/Video/Video.tsx b/packages/react-sdk/src/core/components/Video/Video.tsx index de4cfc6f19..0723d70bc0 100644 --- a/packages/react-sdk/src/core/components/Video/Video.tsx +++ b/packages/react-sdk/src/core/components/Video/Video.tsx @@ -31,8 +31,20 @@ export type VideoProps = ComponentPropsWithoutRef<'video'> & { * Override the default UI that's visible when a participant turned off their video. */ VideoPlaceholder?: ComponentType; + /** + * An object with setRef functions + * meant for exposing some of the internal elements of this component. + */ refs?: { + /** + * The video element that's used to play the video stream. + * @param element the video element. + */ setVideoElement?: (element: HTMLVideoElement | null) => void; + /** + * The video placeholder element that's used when the video stream is not playing. + * @param element the video placeholder element. + */ setVideoPlaceholderElement?: (element: HTMLDivElement | null) => void; }; }; @@ -93,6 +105,11 @@ export const Video = ({ setIsWideMode(width >= height); }; + // playback may have started before we had a chance to + // attach the 'play/pause' event listener, so we set the state + // here to make sure it's in sync + setIsVideoPaused(videoElement.paused); + videoElement.addEventListener('play', handlePlayPause); videoElement.addEventListener('pause', handlePlayPause); track.addEventListener('unmute', handlePlayPause); @@ -100,6 +117,9 @@ export const Video = ({ videoElement.removeEventListener('play', handlePlayPause); videoElement.removeEventListener('pause', handlePlayPause); track.removeEventListener('unmute', handlePlayPause); + + // reset the 'pause' state once we unmount the video element + setIsVideoPaused(true); }; }, [stream, videoElement]);