From 38f00be23132c38c45559c9172d911816712160f Mon Sep 17 00:00:00 2001 From: David Granado Date: Wed, 2 Mar 2022 10:13:46 -0600 Subject: [PATCH 1/6] When video is playing, save position intermittently --- ui/component/viewers/videoViewer/view.jsx | 11 +++++++++++ ui/effects/use-interval.js | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 ui/effects/use-interval.js diff --git a/ui/component/viewers/videoViewer/view.jsx b/ui/component/viewers/videoViewer/view.jsx index f23b92771..aa2f652e8 100644 --- a/ui/component/viewers/videoViewer/view.jsx +++ b/ui/component/viewers/videoViewer/view.jsx @@ -27,9 +27,11 @@ import { getAllIds } from 'util/buildHomepage'; import type { HomepageCat } from 'util/buildHomepage'; import debounce from 'util/debounce'; import { formatLbryUrlForWeb, generateListSearchUrlParams } from 'util/url'; +import useInterval from 'effects/use-interval'; // const PLAY_TIMEOUT_ERROR = 'play_timeout_error'; // const PLAY_TIMEOUT_LIMIT = 2000; +const PLAY_POSITION_SAVE_INTERVAL = 1500; type Props = { position: number, @@ -137,6 +139,7 @@ function VideoViewer(props: Props) { const [videoNode, setVideoNode] = useState(); const [localAutoplayNext, setLocalAutoplayNext] = useState(autoplayNext); const isFirstRender = React.useRef(true); + const playerRef = React.useRef(null); useEffect(() => { if (isFirstRender.current) { @@ -146,6 +149,12 @@ function VideoViewer(props: Props) { toggleAutoplayNext(); }, [localAutoplayNext]); + useInterval(() => { + if (playerRef.current && isPlaying) { + handlePosition(playerRef.current); + } + }, PLAY_POSITION_SAVE_INTERVAL); + const updateVolumeState = React.useCallback( debounce((volume, muted) => { changeVolume(volume); @@ -420,6 +429,8 @@ function VideoViewer(props: Props) { if (position) { player.currentTime(position); } + + playerRef.current = player; }, playerReadyDependencyList); // eslint-disable-line return ( diff --git a/ui/effects/use-interval.js b/ui/effects/use-interval.js new file mode 100644 index 000000000..bffe7c18e --- /dev/null +++ b/ui/effects/use-interval.js @@ -0,0 +1,19 @@ +import { useRef, useEffect } from 'react'; + +export default function useInterval(callback, delay) { + const savedCallback = useRef(); + + useEffect(() => { + savedCallback.current = callback; + }, [callback]); + + useEffect(() => { + const tick = () => { + savedCallback.current(); + }; + if (delay !== null) { + let id = setInterval(tick, delay); + return () => clearInterval(id); + } + }, [delay]); +} From 4d438ed62fb303c48a334833a6188f94ab595716 Mon Sep 17 00:00:00 2001 From: David Granado Date: Wed, 2 Mar 2022 10:18:17 -0600 Subject: [PATCH 2/6] Widen save interval --- ui/component/viewers/videoViewer/view.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/component/viewers/videoViewer/view.jsx b/ui/component/viewers/videoViewer/view.jsx index aa2f652e8..806ae33ce 100644 --- a/ui/component/viewers/videoViewer/view.jsx +++ b/ui/component/viewers/videoViewer/view.jsx @@ -31,7 +31,7 @@ import useInterval from 'effects/use-interval'; // const PLAY_TIMEOUT_ERROR = 'play_timeout_error'; // const PLAY_TIMEOUT_LIMIT = 2000; -const PLAY_POSITION_SAVE_INTERVAL = 1500; +const PLAY_POSITION_SAVE_INTERVAL = 15000; type Props = { position: number, From abb92726ab68e2cd3e038a3f453a57e296177fe0 Mon Sep 17 00:00:00 2001 From: David Granado Date: Wed, 2 Mar 2022 20:25:14 -0600 Subject: [PATCH 3/6] Rename variable to include value units --- ui/component/viewers/videoViewer/view.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/component/viewers/videoViewer/view.jsx b/ui/component/viewers/videoViewer/view.jsx index 806ae33ce..4aa119ea9 100644 --- a/ui/component/viewers/videoViewer/view.jsx +++ b/ui/component/viewers/videoViewer/view.jsx @@ -31,7 +31,7 @@ import useInterval from 'effects/use-interval'; // const PLAY_TIMEOUT_ERROR = 'play_timeout_error'; // const PLAY_TIMEOUT_LIMIT = 2000; -const PLAY_POSITION_SAVE_INTERVAL = 15000; +const PLAY_POSITION_SAVE_INTERVAL_MS = 15000; type Props = { position: number, @@ -153,7 +153,7 @@ function VideoViewer(props: Props) { if (playerRef.current && isPlaying) { handlePosition(playerRef.current); } - }, PLAY_POSITION_SAVE_INTERVAL); + }, PLAY_POSITION_SAVE_INTERVAL_MS); const updateVolumeState = React.useCallback( debounce((volume, muted) => { From 0f2eba8733f11473d01f9b3ba16b5fa84a39456a Mon Sep 17 00:00:00 2001 From: David Granado Date: Wed, 2 Mar 2022 20:25:44 -0600 Subject: [PATCH 4/6] Switch unnecessary let to const --- ui/effects/use-interval.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/effects/use-interval.js b/ui/effects/use-interval.js index bffe7c18e..e0bf92b24 100644 --- a/ui/effects/use-interval.js +++ b/ui/effects/use-interval.js @@ -12,7 +12,7 @@ export default function useInterval(callback, delay) { savedCallback.current(); }; if (delay !== null) { - let id = setInterval(tick, delay); + const id = setInterval(tick, delay); return () => clearInterval(id); } }, [delay]); From 3631bdddbc2f030cca42a6cfeff54695b0fd8c95 Mon Sep 17 00:00:00 2001 From: David Granado Date: Wed, 2 Mar 2022 20:41:37 -0600 Subject: [PATCH 5/6] Adjust logic to only run interval when video is playing. --- ui/component/viewers/videoViewer/view.jsx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ui/component/viewers/videoViewer/view.jsx b/ui/component/viewers/videoViewer/view.jsx index 4aa119ea9..442357cd6 100644 --- a/ui/component/viewers/videoViewer/view.jsx +++ b/ui/component/viewers/videoViewer/view.jsx @@ -127,6 +127,7 @@ function VideoViewer(props: Props) { const [ended, setEnded] = useState(false); const [showAutoplayCountdown, setShowAutoplayCountdown] = useState(false); const [isEndedEmbed, setIsEndedEmbed] = useState(false); + const [playerObj, setPlayerObj] = useState(null); const vjsCallbackDataRef: any = React.useRef(); const previousUri = usePrevious(uri); const embedded = useContext(EmbedContext); @@ -139,7 +140,7 @@ function VideoViewer(props: Props) { const [videoNode, setVideoNode] = useState(); const [localAutoplayNext, setLocalAutoplayNext] = useState(autoplayNext); const isFirstRender = React.useRef(true); - const playerRef = React.useRef(null); + const savePositionInterval = isPlaying ? PLAY_POSITION_SAVE_INTERVAL_MS : null; useEffect(() => { if (isFirstRender.current) { @@ -150,10 +151,10 @@ function VideoViewer(props: Props) { }, [localAutoplayNext]); useInterval(() => { - if (playerRef.current && isPlaying) { - handlePosition(playerRef.current); + if (playerObj) { + handlePosition(playerObj); } - }, PLAY_POSITION_SAVE_INTERVAL_MS); + }, savePositionInterval); const updateVolumeState = React.useCallback( debounce((volume, muted) => { @@ -430,7 +431,7 @@ function VideoViewer(props: Props) { player.currentTime(position); } - playerRef.current = player; + setPlayerObj(player); }, playerReadyDependencyList); // eslint-disable-line return ( From 7263bde491bc07887a62d7b0e035bd89694ad21e Mon Sep 17 00:00:00 2001 From: David Granado Date: Wed, 2 Mar 2022 22:12:11 -0600 Subject: [PATCH 6/6] Revert "Adjust logic to only run interval when video is playing." This reverts commit 5ce6ab9689c1610f24869c7347b823cc2023b767. --- ui/component/viewers/videoViewer/view.jsx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ui/component/viewers/videoViewer/view.jsx b/ui/component/viewers/videoViewer/view.jsx index 442357cd6..4aa119ea9 100644 --- a/ui/component/viewers/videoViewer/view.jsx +++ b/ui/component/viewers/videoViewer/view.jsx @@ -127,7 +127,6 @@ function VideoViewer(props: Props) { const [ended, setEnded] = useState(false); const [showAutoplayCountdown, setShowAutoplayCountdown] = useState(false); const [isEndedEmbed, setIsEndedEmbed] = useState(false); - const [playerObj, setPlayerObj] = useState(null); const vjsCallbackDataRef: any = React.useRef(); const previousUri = usePrevious(uri); const embedded = useContext(EmbedContext); @@ -140,7 +139,7 @@ function VideoViewer(props: Props) { const [videoNode, setVideoNode] = useState(); const [localAutoplayNext, setLocalAutoplayNext] = useState(autoplayNext); const isFirstRender = React.useRef(true); - const savePositionInterval = isPlaying ? PLAY_POSITION_SAVE_INTERVAL_MS : null; + const playerRef = React.useRef(null); useEffect(() => { if (isFirstRender.current) { @@ -151,10 +150,10 @@ function VideoViewer(props: Props) { }, [localAutoplayNext]); useInterval(() => { - if (playerObj) { - handlePosition(playerObj); + if (playerRef.current && isPlaying) { + handlePosition(playerRef.current); } - }, savePositionInterval); + }, PLAY_POSITION_SAVE_INTERVAL_MS); const updateVolumeState = React.useCallback( debounce((volume, muted) => { @@ -431,7 +430,7 @@ function VideoViewer(props: Props) { player.currentTime(position); } - setPlayerObj(player); + playerRef.current = player; }, playerReadyDependencyList); // eslint-disable-line return (