From 3d2d51860d13824dea3b24991106cbab64f79762 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Wed, 13 Nov 2024 08:46:18 -0600 Subject: [PATCH] apply streaming settings in camera groups --- .../components/player/BirdseyeLivePlayer.tsx | 1 + web/src/components/player/JSMpegPlayer.tsx | 6 ++- web/src/components/player/LivePlayer.tsx | 3 ++ .../settings/CameraStreamingDialog.tsx | 14 ++++--- web/src/types/frigateConfig.ts | 4 +- web/src/views/live/DraggableGridLayout.tsx | 41 ++++++++++++++++++- web/src/views/live/LiveDashboardView.tsx | 12 +----- 7 files changed, 62 insertions(+), 19 deletions(-) diff --git a/web/src/components/player/BirdseyeLivePlayer.tsx b/web/src/components/player/BirdseyeLivePlayer.tsx index 2666ac9f7..286f19216 100644 --- a/web/src/components/player/BirdseyeLivePlayer.tsx +++ b/web/src/components/player/BirdseyeLivePlayer.tsx @@ -58,6 +58,7 @@ export default function BirdseyeLivePlayer({ height={birdseyeConfig.height} containerRef={containerRef} playbackEnabled={true} + useWebGL={true} /> ); } else { diff --git a/web/src/components/player/JSMpegPlayer.tsx b/web/src/components/player/JSMpegPlayer.tsx index 401e85869..811f3da29 100644 --- a/web/src/components/player/JSMpegPlayer.tsx +++ b/web/src/components/player/JSMpegPlayer.tsx @@ -12,6 +12,7 @@ type JSMpegPlayerProps = { height: number; containerRef: React.MutableRefObject; playbackEnabled: boolean; + useWebGL: boolean; onPlaying?: () => void; }; @@ -22,6 +23,7 @@ export default function JSMpegPlayer({ className, containerRef, playbackEnabled, + useWebGL = false, onPlaying, }: JSMpegPlayerProps) { const url = `${baseUrl.replace(/^http/, "ws")}live/jsmpeg/${camera}`; @@ -123,8 +125,8 @@ export default function JSMpegPlayer({ { protocols: [], audio: false, - disableGl: camera != "birdseye", - disableWebAssembly: camera != "birdseye", + disableGl: !useWebGL, + disableWebAssembly: !useWebGL, videoBufferSize: 1024 * 1024 * 4, onVideoDecode: () => { if (!hasDataRef.current) { diff --git a/web/src/components/player/LivePlayer.tsx b/web/src/components/player/LivePlayer.tsx index 4be653667..a5ff127e0 100644 --- a/web/src/components/player/LivePlayer.tsx +++ b/web/src/components/player/LivePlayer.tsx @@ -29,6 +29,7 @@ type LivePlayerProps = { streamName: string; preferredLiveMode: LivePlayerMode; showStillWithoutActivity?: boolean; + useWebGL: boolean; windowVisible?: boolean; playAudio?: boolean; micEnabled?: boolean; // only webrtc supports mic @@ -49,6 +50,7 @@ export default function LivePlayer({ streamName, preferredLiveMode, showStillWithoutActivity = true, + useWebGL = false, windowVisible = true, playAudio = false, micEnabled = false, @@ -219,6 +221,7 @@ export default function LivePlayer({ playbackEnabled={ cameraActive || !showStillWithoutActivity || liveReady } + useWebGL={useWebGL} containerRef={containerRef ?? internalContainerRef} onPlaying={playerIsPlaying} /> diff --git a/web/src/components/settings/CameraStreamingDialog.tsx b/web/src/components/settings/CameraStreamingDialog.tsx index 03ddf5cb6..586ed73b6 100644 --- a/web/src/components/settings/CameraStreamingDialog.tsx +++ b/web/src/components/settings/CameraStreamingDialog.tsx @@ -21,7 +21,8 @@ import { Label } from "@/components/ui/label"; import { cn } from "@/lib/utils"; import { FrigateConfig, - GroupStreamingSettingsType, + GroupStreamingSettings, + StreamType, } from "@/types/frigateConfig"; import ActivityIndicator from "../indicators/activity-indicator"; import { LuSettings } from "react-icons/lu"; @@ -30,9 +31,9 @@ type CameraStreamingDialogProps = { camera: string; selectedCameras: string[]; config?: FrigateConfig; - groupStreamingSettings: GroupStreamingSettingsType; + groupStreamingSettings: GroupStreamingSettings; setGroupStreamingSettings: React.Dispatch< - React.SetStateAction + React.SetStateAction >; }; @@ -47,7 +48,7 @@ export function CameraStreamingDialog({ const [isLoading, setIsLoading] = useState(false); const [streamName, setStreamName] = useState(""); - const [streamType, setStreamType] = useState("smart"); + const [streamType, setStreamType] = useState("smart"); const [compatibilityMode, setCompatibilityMode] = useState(false); useEffect(() => { @@ -154,7 +155,10 @@ export function CameraStreamingDialog({ - setStreamType(value as StreamType)} + > diff --git a/web/src/types/frigateConfig.ts b/web/src/types/frigateConfig.ts index 5e84f3fe0..30a1d2e99 100644 --- a/web/src/types/frigateConfig.ts +++ b/web/src/types/frigateConfig.ts @@ -229,9 +229,11 @@ export type CameraGroupConfig = { order: number; }; +export type StreamType = "no-streaming" | "smart" | "continuous"; + export type CameraStreamingSettings = { streamName: string; - streamType: string; + streamType: StreamType; compatibilityMode: boolean; }; diff --git a/web/src/views/live/DraggableGridLayout.tsx b/web/src/views/live/DraggableGridLayout.tsx index c67e74fa9..d8a1ee144 100644 --- a/web/src/views/live/DraggableGridLayout.tsx +++ b/web/src/views/live/DraggableGridLayout.tsx @@ -57,6 +57,7 @@ type DraggableGridLayoutProps = { setIsEditMode: React.Dispatch>; fullscreen: boolean; toggleFullscreen: () => void; + allGroupsStreamingSettings: AllGroupsStreamingSettings; setAllGroupsStreamingSettings: React.Dispatch< React.SetStateAction >; @@ -74,6 +75,7 @@ export default function DraggableGridLayout({ setIsEditMode, fullscreen, toggleFullscreen, + allGroupsStreamingSettings, setAllGroupsStreamingSettings, }: DraggableGridLayoutProps) { const { data: config } = useSWR("config"); @@ -84,6 +86,16 @@ export default function DraggableGridLayout({ const { preferredLiveModes, setPreferredLiveModes, resetPreferredLiveMode } = useCameraLiveMode(cameras, windowVisible); + const [globalAutoLive] = usePersistence("autoLiveView", true); + + const currentGroupStreamingSettings = useMemo(() => { + if (cameraGroup && cameraGroup != "default" && allGroupsStreamingSettings) { + return allGroupsStreamingSettings[cameraGroup]; + } + }, [allGroupsStreamingSettings, cameraGroup]); + + // grid layout + const ResponsiveGridLayout = useMemo(() => WidthProvider(Responsive), []); const [gridLayout, setGridLayout, isGridLayoutLoaded] = usePersistence< @@ -426,9 +438,25 @@ export default function DraggableGridLayout({ } else { grow = "aspect-video"; } + const streamName = + currentGroupStreamingSettings?.[camera.name]?.streamName || + Object.values(camera.live.streams)[0]; + const autoLive = + currentGroupStreamingSettings?.[camera.name]?.streamType !== + "no-streaming"; + const showStillWithoutActivity = + currentGroupStreamingSettings?.[camera.name]?.streamType !== + "continuous"; + const useWebGL = + currentGroupStreamingSettings?.[camera.name] + ?.compatibilityMode || false; return ( void; onError: (e: LivePlayerError) => void; onResetLiveMode: () => void; + streamName: string; + autoLive: boolean; + showStillWithoutActivity: boolean; + useWebGL: boolean; }; const LivePlayerGridItem = React.forwardRef< @@ -637,6 +669,10 @@ const LivePlayerGridItem = React.forwardRef< onClick, onError, onResetLiveMode, + autoLive, + showStillWithoutActivity, + streamName, + useWebGL, ...props }, ref, @@ -656,11 +692,14 @@ const LivePlayerGridItem = React.forwardRef< windowVisible={windowVisible} cameraConfig={cameraConfig} preferredLiveMode={preferredLiveMode} - streamName={Object.values(cameraConfig.live.streams)[0]} + streamName={streamName} onClick={onClick} onError={onError} onResetLiveMode={onResetLiveMode} containerRef={ref as React.RefObject} + autoLive={autoLive} + showStillWithoutActivity={showStillWithoutActivity} + useWebGL={useWebGL} /> {children} diff --git a/web/src/views/live/LiveDashboardView.tsx b/web/src/views/live/LiveDashboardView.tsx index c8712efe7..9d3335ac4 100644 --- a/web/src/views/live/LiveDashboardView.tsx +++ b/web/src/views/live/LiveDashboardView.tsx @@ -197,22 +197,12 @@ export default function LiveDashboardView({ const [persistedStreamingSettings, _, isStreamingSettingsLoaded] = usePersistence("streaming-settings"); - const currentGroupStreamingSettings = useMemo(() => { - if (cameraGroup && cameraGroup != "default" && allGroupsStreamingSettings) { - return allGroupsStreamingSettings[cameraGroup]; - } - }, [allGroupsStreamingSettings, cameraGroup]); - useEffect(() => { if (isStreamingSettingsLoaded) { setAllGroupsStreamingSettings(persistedStreamingSettings ?? {}); } }, [isStreamingSettingsLoaded, persistedStreamingSettings]); - useEffect(() => { - // console.log("group settings", cameraGroup, currentGroupStreamingSettings); - }, [currentGroupStreamingSettings, cameraGroup]); - const cameraRef = useCallback( (node: HTMLElement | null) => { if (!visibleCameraObserver.current) { @@ -384,6 +374,7 @@ export default function LiveDashboardView({ cameraConfig={camera} preferredLiveMode={preferredLiveModes[camera.name] ?? "mse"} autoLive={autoLiveView} + useWebGL={false} streamName={Object.values(camera.live.streams)[0]} onClick={() => onSelectCamera(camera.name)} onError={(e) => handleError(camera.name, e)} @@ -436,6 +427,7 @@ export default function LiveDashboardView({ setIsEditMode={setIsEditMode} fullscreen={fullscreen} toggleFullscreen={toggleFullscreen} + allGroupsStreamingSettings={allGroupsStreamingSettings} setAllGroupsStreamingSettings={setAllGroupsStreamingSettings} /> )}