diff --git a/src/routes/Player/ControlBar/ControlBar.js b/src/routes/Player/ControlBar/ControlBar.js index 6f41f3c21..5deabf08d 100644 --- a/src/routes/Player/ControlBar/ControlBar.js +++ b/src/routes/Player/ControlBar/ControlBar.js @@ -168,9 +168,14 @@ const ControlBar = ({
- + { + document.pictureInPictureEnabled ? + + : + null + } diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index 8e92c1516..7ac40d63f 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -279,18 +279,39 @@ const Player = ({ urlParams, queryParams }) => { const onPipEnableRequested = React.useCallback(() => { console.log("Entering picture in picture"); const videoElement = video.containerRef.current?.querySelector('video'); - videoElement.requestPictureInPicture().then(() => { - video.setPictureInPicture(true); - }); + if (videoElement && videoElement !== document.pictureInPictureElement) { + videoElement.requestPictureInPicture(); + } }, []); const onPipDisableRequested = React.useCallback(() => { - console.log("Exiting picture in picture"); - document.exitPictureInPicture().then(() => { - video.setPictureInPicture(false); - }); + if (document.pictureInPictureElement) { + document.exitPictureInPicture(); + } }, []); + // Listen to PiP events to sync state + React.useEffect(() => { + const videoElement = video.containerRef.current?.querySelector('video'); + if (!videoElement) return; + + const onEnterPip = () => { + video.setPictureInPicture(true); + }; + + const onLeavePip = () => { + video.setPictureInPicture(false); + }; + + videoElement.addEventListener('enterpictureinpicture', onEnterPip); + videoElement.addEventListener('leavepictureinpicture', onLeavePip); + + return () => { + videoElement.removeEventListener('enterpictureinpicture', onEnterPip); + videoElement.removeEventListener('leavepictureinpicture', onLeavePip); + }; + }, [video.state.stream]); + const onVideoClick = React.useCallback(() => { if (video.state.paused !== null) { if (video.state.paused) {