From fdaf524015dce1caa74e78d15715666e75eeb81c Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Mon, 10 Nov 2025 14:20:19 -0700 Subject: [PATCH] Improve stream fetching logic --- web/src/hooks/use-camera-live-mode.ts | 13 +++++--- web/src/views/live/DraggableGridLayout.tsx | 35 +++++++++++++++++----- web/src/views/live/LiveDashboardView.tsx | 35 +++++++++++++++++----- 3 files changed, 63 insertions(+), 20 deletions(-) diff --git a/web/src/hooks/use-camera-live-mode.ts b/web/src/hooks/use-camera-live-mode.ts index 17dfaee91..1c52648d3 100644 --- a/web/src/hooks/use-camera-live-mode.ts +++ b/web/src/hooks/use-camera-live-mode.ts @@ -6,6 +6,7 @@ import { LivePlayerMode, LiveStreamMetadata } from "@/types/live"; export default function useCameraLiveMode( cameras: CameraConfig[], windowVisible: boolean, + activeStreams?: { [cameraName: string]: string }, ) { const { data: config } = useSWR("config"); @@ -20,16 +21,20 @@ export default function useCameraLiveMode( ); if (isRestreamed) { - Object.values(camera.live.streams).forEach((streamName) => { - streamNames.add(streamName); - }); + if (activeStreams && activeStreams[camera.name]) { + streamNames.add(activeStreams[camera.name]); + } else { + Object.values(camera.live.streams).forEach((streamName) => { + streamNames.add(streamName); + }); + } } }); return streamNames.size > 0 ? Array.from(streamNames).sort().join(",") : null; - }, [cameras, config]); + }, [cameras, config, activeStreams]); const streamsFetcher = useCallback(async (key: string) => { const streamNames = key.split(","); diff --git a/web/src/views/live/DraggableGridLayout.tsx b/web/src/views/live/DraggableGridLayout.tsx index 5239fe388..259e4093f 100644 --- a/web/src/views/live/DraggableGridLayout.tsx +++ b/web/src/views/live/DraggableGridLayout.tsx @@ -86,14 +86,6 @@ export default function DraggableGridLayout({ // preferred live modes per camera - const { - preferredLiveModes, - setPreferredLiveModes, - resetPreferredLiveMode, - isRestreamedStates, - supportsAudioOutputStates, - } = useCameraLiveMode(cameras, windowVisible); - const [globalAutoLive] = usePersistence("autoLiveView", true); const [displayCameraNames] = usePersistence("displayCameraNames", false); @@ -106,6 +98,33 @@ export default function DraggableGridLayout({ } }, [allGroupsStreamingSettings, cameraGroup]); + const activeStreams = useMemo(() => { + const streams: { [cameraName: string]: string } = {}; + cameras.forEach((camera) => { + const availableStreams = camera.live.streams || {}; + const streamNameFromSettings = + currentGroupStreamingSettings?.[camera.name]?.streamName || ""; + const streamExists = + streamNameFromSettings && + Object.values(availableStreams).includes(streamNameFromSettings); + + const streamName = streamExists + ? streamNameFromSettings + : Object.values(availableStreams)[0] || ""; + + streams[camera.name] = streamName; + }); + return streams; + }, [cameras, currentGroupStreamingSettings]); + + const { + preferredLiveModes, + setPreferredLiveModes, + resetPreferredLiveMode, + isRestreamedStates, + supportsAudioOutputStates, + } = useCameraLiveMode(cameras, windowVisible, activeStreams); + // grid layout const ResponsiveGridLayout = useMemo(() => WidthProvider(Responsive), []); diff --git a/web/src/views/live/LiveDashboardView.tsx b/web/src/views/live/LiveDashboardView.tsx index 8b7dd1336..c4104576c 100644 --- a/web/src/views/live/LiveDashboardView.tsx +++ b/web/src/views/live/LiveDashboardView.tsx @@ -202,14 +202,6 @@ export default function LiveDashboardView({ }; }, []); - const { - preferredLiveModes, - setPreferredLiveModes, - resetPreferredLiveMode, - isRestreamedStates, - supportsAudioOutputStates, - } = useCameraLiveMode(cameras, windowVisible); - const [globalAutoLive] = usePersistence("autoLiveView", true); const [displayCameraNames] = usePersistence("displayCameraNames", false); @@ -239,6 +231,33 @@ export default function LiveDashboardView({ [visibleCameraObserver.current], ); + const activeStreams = useMemo(() => { + const streams: { [cameraName: string]: string } = {}; + cameras.forEach((camera) => { + const availableStreams = camera.live.streams || {}; + const streamNameFromSettings = + currentGroupStreamingSettings?.[camera.name]?.streamName || ""; + const streamExists = + streamNameFromSettings && + Object.values(availableStreams).includes(streamNameFromSettings); + + const streamName = streamExists + ? streamNameFromSettings + : Object.values(availableStreams)[0] || ""; + + streams[camera.name] = streamName; + }); + return streams; + }, [cameras, currentGroupStreamingSettings]); + + const { + preferredLiveModes, + setPreferredLiveModes, + resetPreferredLiveMode, + isRestreamedStates, + supportsAudioOutputStates, + } = useCameraLiveMode(cameras, windowVisible, activeStreams); + const birdseyeConfig = useMemo(() => config?.birdseye, [config]); const handleError = useCallback(