diff --git a/web/src/components/player/DynamicVideoPlayer.tsx b/web/src/components/player/DynamicVideoPlayer.tsx index 462bb44e2..0c5b98e69 100644 --- a/web/src/components/player/DynamicVideoPlayer.tsx +++ b/web/src/components/player/DynamicVideoPlayer.tsx @@ -12,7 +12,6 @@ import TimelineEventOverlay from "../overlay/TimelineDataOverlay"; import { useApiHost } from "@/api"; import useSWR from "swr"; import { FrigateConfig } from "@/types/frigateConfig"; -import ActivityIndicator from "../indicators/activity-indicator"; import useKeyboardListener from "@/hooks/use-keyboard-listener"; import { Recording } from "@/types/record"; import { Preview } from "@/types/preview"; @@ -64,14 +63,14 @@ export default function DynamicVideoPlayer({ // controlling playback - const playerRef = useRef(undefined); + const [playerRef, setPlayerRef] = useState(undefined); const previewRef = useRef(null); const [isScrubbing, setIsScrubbing] = useState(previewOnly); const [focusedItem, setFocusedItem] = useState( undefined, ); const controller = useMemo(() => { - if (!config) { + if (!config || !playerRef || !previewRef.current) { return undefined; } @@ -84,10 +83,12 @@ export default function DynamicVideoPlayer({ setIsScrubbing, setFocusedItem, ); - }, [camera, config, previewOnly]); + // we only want to fire once when players are ready + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [camera, config, playerRef, previewRef]); useEffect(() => { - if (!playerRef.current && !previewRef.current) { + if (!controller) { return; } @@ -97,7 +98,23 @@ export default function DynamicVideoPlayer({ // we only want to fire once when players are ready // eslint-disable-next-line react-hooks/exhaustive-deps - }, [playerRef, previewRef]); + }, [controller]); + + useEffect(() => { + if (!controller || !playerRef) { + return; + } + + if (previewOnly) { + playerRef.autoplay(false); + controller.removePlayerListeners(); + } else { + controller.setPlayerListeners(); + playerRef.play(); + } + // we only want to fire once when players are ready + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [controller, previewOnly]); const [hasRecordingAtTime, setHasRecordingAtTime] = useState(true); @@ -108,33 +125,33 @@ export default function DynamicVideoPlayer({ switch (key) { case "ArrowLeft": if (down) { - const currentTime = playerRef.current?.currentTime(); + const currentTime = playerRef?.currentTime(); if (currentTime) { - playerRef.current?.currentTime(Math.max(0, currentTime - 5)); + playerRef?.currentTime(Math.max(0, currentTime - 5)); } } break; case "ArrowRight": if (down) { - const currentTime = playerRef.current?.currentTime(); + const currentTime = playerRef?.currentTime(); if (currentTime) { - playerRef.current?.currentTime(currentTime + 5); + playerRef?.currentTime(currentTime + 5); } } break; case "m": - if (down && !repeat && playerRef.current) { - playerRef.current.muted(!playerRef.current.muted()); + if (down && !repeat && playerRef) { + playerRef.muted(!playerRef.muted()); } break; case " ": - if (down && playerRef.current) { - if (playerRef.current.paused()) { - playerRef.current.play(); + if (down && playerRef) { + if (playerRef.paused()) { + playerRef.play(); } else { - playerRef.current.pause(); + playerRef.pause(); } } break; @@ -244,58 +261,47 @@ export default function DynamicVideoPlayer({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [controller, recordings]); - if (!controller) { - return ; - } - return (
- {!previewOnly && ( -
- + { - playerRef.current = player; - player.on("playing", () => setFocusedItem(undefined)); - player.on("timeupdate", () => { - controller.updateProgress(player.currentTime() || 0); - }); - player.on("ended", () => - controller.fireClipChangeEvent("forward"), - ); - }} - onDispose={() => { - playerRef.current = undefined; - }} - > - {config && focusedItem && ( - - )} - -
- )} + }, + }} + seekOptions={{ forward: 10, backward: 5 }} + onReady={(player) => { + setPlayerRef(player); + }} + onDispose={() => { + setPlayerRef(undefined); + }} + > + {config && focusedItem && ( + + )} + +