From 474c004eea4548f34b43c9096f4183c94e3e17b6 Mon Sep 17 00:00:00 2001 From: IEduStu <125146135+IEduStu@users.noreply.github.com> Date: Sat, 20 Apr 2024 17:46:23 +0000 Subject: [PATCH] fix: airplay active state effects --- src/routes/Player/ControlBar/ControlBar.js | 14 ++++++++++++++ src/routes/Player/Player.js | 10 ++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/routes/Player/ControlBar/ControlBar.js b/src/routes/Player/ControlBar/ControlBar.js index 19925be4a..7d112e339 100644 --- a/src/routes/Player/ControlBar/ControlBar.js +++ b/src/routes/Player/ControlBar/ControlBar.js @@ -45,6 +45,7 @@ const ControlBar = ({ onToggleOptionsMenu, onToggleStatisticsMenu, videoContainerElementRef, + setAirplayActive, ...props }) => { const { chromecast } = useServices(); @@ -52,6 +53,10 @@ const ControlBar = ({ const [chromecastServiceActive, setChromecastServiceActive] = React.useState(() => chromecast.active); const [airplayAvailable, setAirplayAvailable] = React.useState(false); const [buttonsMenuOpen, , , toogleButtonsMenu] = useBinaryState(false); + + const setAirplayActiveRef = React.useRef(); + setAirplayActiveRef.current = setAirplayActive; + const getVideoElement = React.useCallback(() => { if (videoContainerElementRef && videoContainerElementRef.current) { if (videoContainerElementRef.current instanceof HTMLVideoElement) @@ -78,15 +83,23 @@ const ControlBar = ({ } } + function airplayActiveChanged() { + if (setAirplayActiveRef.current) + setAirplayActiveRef.current(!!videoTag.webkitCurrentPlaybackTargetIsWireless); + } + if (window.WebKitPlaybackTargetAvailabilityEvent) { videoTag.addEventListener('webkitplaybacktargetavailabilitychanged', onAirplayAvailabilityChanged); + videoTag.addEventListener('webkitcurrentplaybacktargetiswirelesschanged', airplayActiveChanged); setAirplayAvailable(!!videoTag.webkitWirelessVideoPlaybackDisabled); + airplayActiveChanged(); } return () => { if (window.WebKitPlaybackTargetAvailabilityEvent) { videoTag.removeEventListener('webkitplaybacktargetavailabilitychanged', onAirplayAvailabilityChanged); + videoTag.removeEventListener('webkitcurrentplaybacktargetiswirelesschanged', airplayActiveChanged); } }; }, [getVideoElement()]); @@ -273,6 +286,7 @@ ControlBar.propTypes = { onToggleOptionsMenu: PropTypes.func, onToggleStatisticsMenu: PropTypes.func, videoContainerElementRef: PropTypes.object, + setAirplayActive: PropTypes.func, }; module.exports = ControlBar; diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index 7b36e57e8..267ebbe80 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -48,6 +48,7 @@ const Player = ({ urlParams, queryParams }) => { const [casting, setCasting] = React.useState(() => { return chromecast.active && chromecast.transport.getCastState() === cast.framework.CastState.CONNECTED; }); + const [airplayActive, setAirplayActive] = React.useState(false); const [immersed, setImmersed] = React.useState(true); const setImmersedDebounced = React.useCallback(debounce(setImmersed, 3000), []); @@ -75,8 +76,8 @@ const Player = ({ urlParams, queryParams }) => { }, []); const overlayHidden = React.useMemo(() => { - return immersed && !casting && video.state.paused !== null && (!video.state.paused || isMobile) && !menusOpen && !nextVideoPopupOpen; - }, [immersed, casting, video.state.paused, menusOpen, nextVideoPopupOpen]); + return immersed && !casting && !airplayActive && video.state.paused !== null && (!video.state.paused || isMobile) && !menusOpen && !nextVideoPopupOpen; + }, [immersed, casting, airplayActive, video.state.paused, menusOpen, nextVideoPopupOpen]); const nextVideoPopupDismissed = React.useRef(false); const defaultSubtitlesSelected = React.useRef(false); @@ -323,7 +324,7 @@ const Player = ({ urlParams, queryParams }) => { player.libraryItem.state.timeOffset : 0, - forceTranscoding: forceTranscoding || casting, + forceTranscoding: forceTranscoding || casting || airplayActive, maxAudioChannels: settings.surroundSound ? 32 : 2, streamingServerURL: streamingServer.baseUrl ? casting ? @@ -338,7 +339,7 @@ const Player = ({ urlParams, queryParams }) => { shellTransport: shell.active ? shell.transport : null, }); } - }, [streamingServer.baseUrl, player.selected, player.metaItem, forceTranscoding, casting]); + }, [streamingServer.baseUrl, player.selected, player.metaItem, forceTranscoding, casting, airplayActive]); React.useEffect(() => { if (video.state.stream !== null) { const tracks = player.subtitles.map((subtitles) => ({ @@ -709,6 +710,7 @@ const Player = ({ urlParams, queryParams }) => { nextVideo={player.nextVideo} stream={player.selected !== null ? player.selected.stream : null} videoContainerElementRef={video.containerElement} + setAirplayActive={setAirplayActive} statistics={statistics} onPlayRequested={onPlayRequested} onPauseRequested={onPauseRequested}