From bf3a0e79443678c251c8d1bf78462f2d14dc49f8 Mon Sep 17 00:00:00 2001 From: dumdum7 <95527094+dumdum7@users.noreply.github.com> Date: Fri, 28 Feb 2025 04:11:50 +0100 Subject: [PATCH] Handy integration improvements (#5576) * Use playing event instead of play * Remove unnecessary ensurePlaying() from timeupdate listener Eliminates redundant API calls by only relying on playing and pause events. Handles edge cases for playback before script upload completion. * Remove unnecessary video seeking event listener We don't need it anymore, listening for playing and pause events is enough. * Send second play event after a play event to adjust for video player issues * Fix script being paused and played after 10 seconds because of activity tracker dependency change --- .../components/ScenePlayer/ScenePlayer.tsx | 49 +++++++++++-------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/ui/v2.5/src/components/ScenePlayer/ScenePlayer.tsx b/ui/v2.5/src/components/ScenePlayer/ScenePlayer.tsx index 036e4272d..b88e7f51b 100644 --- a/ui/v2.5/src/components/ScenePlayer/ScenePlayer.tsx +++ b/ui/v2.5/src/components/ScenePlayer/ScenePlayer.tsx @@ -434,6 +434,14 @@ export const ScenePlayer: React.FC = ({ scene.paths.funscript, ]); + // play the script if video started before script upload finished + useEffect(() => { + if (interactiveState !== ConnectionState.Ready) return; + const player = getPlayer(); + if (!player || player.paused()) return; + interactiveClient.ensurePlaying(player.currentTime()); + }, [interactiveState, getPlayer, interactiveClient]); + useEffect(() => { const player = getPlayer(); if (!player) return; @@ -492,13 +500,23 @@ export const ScenePlayer: React.FC = ({ }; }, [getPlayer]); + // delay before second play event after a play event to adjust for video player issues + const DELAY_FOR_SECOND_PLAY_MS = 1000; + const playingTimer = useRef(); + useEffect(() => { const player = getPlayer(); if (!player) return; - function onplay(this: VideoJsPlayer) { + function playing(this: VideoJsPlayer) { if (scene.interactive && interactiveReady.current) { interactiveClient.play(this.currentTime()); + // trigger a second script play event to adjust for video player issues + clearTimeout(playingTimer.current); + playingTimer.current = setTimeout(() => { + if (this.paused()) return; + interactiveClient.play(this.currentTime()); + }, DELAY_FOR_SECOND_PLAY_MS); } } @@ -506,31 +524,20 @@ export const ScenePlayer: React.FC = ({ interactiveClient.pause(); } - function seeking(this: VideoJsPlayer) { - if (this.paused()) return; - if (scene.interactive && interactiveReady.current) { - interactiveClient.play(this.currentTime()); - } - } - function timeupdate(this: VideoJsPlayer) { if (this.paused()) return; - if (scene.interactive && interactiveReady.current) { - interactiveClient.ensurePlaying(this.currentTime()); - } setTime(this.currentTime()); } - player.on("play", onplay); + player.on("playing", playing); player.on("pause", pause); - player.on("seeking", seeking); player.on("timeupdate", timeupdate); return () => { - player.off("play", onplay); + player.off("playing", playing); player.off("pause", pause); - player.off("seeking", seeking); player.off("timeupdate", timeupdate); + clearTimeout(playingTimer.current); }; }, [getPlayer, interactiveClient, scene]); @@ -676,11 +683,6 @@ export const ScenePlayer: React.FC = ({ }); started.current = false; - - return () => { - // stop the interactive client - interactiveClient.pause(); - }; }, [ getPlayer, file, @@ -693,6 +695,13 @@ export const ScenePlayer: React.FC = ({ _initialTimestamp, ]); + useEffect(() => { + return () => { + // stop the interactive client on unmount + interactiveClient.pause(); + }; + }, [interactiveClient]); + const loadMarkers = useCallback(() => { const player = getPlayer(); if (!player) return;