From 8b4b715f5e212e659b5f1b4d4831cc2978a57df5 Mon Sep 17 00:00:00 2001 From: kensand Date: Tue, 30 Jul 2024 21:28:00 -0400 Subject: [PATCH] Change Automatic Live View setting to allow for continuous playback --- web/src/types/live.ts | 3 + web/src/views/live/DraggableGridLayout.tsx | 9 +- web/src/views/live/LiveDashboardView.tsx | 9 +- .../views/settings/GeneralSettingsView.tsx | 171 ++++++++++-------- 4 files changed, 109 insertions(+), 83 deletions(-) diff --git a/web/src/types/live.ts b/web/src/types/live.ts index f6c8e463a..470c0843f 100644 --- a/web/src/types/live.ts +++ b/web/src/types/live.ts @@ -32,3 +32,6 @@ export type LiveStreamMetadata = { }; export type LivePlayerError = "stalled" | "startup" | "mse-decode"; + +export const LiveViewModes = ["Auto", "Static", "Continuous"] as const +export type LiveViewMode = (typeof LiveViewModes)[number]; diff --git a/web/src/views/live/DraggableGridLayout.tsx b/web/src/views/live/DraggableGridLayout.tsx index 165829719..a58bfb237 100644 --- a/web/src/views/live/DraggableGridLayout.tsx +++ b/web/src/views/live/DraggableGridLayout.tsx @@ -20,7 +20,7 @@ import { } from "react-grid-layout"; import "react-grid-layout/css/styles.css"; import "react-resizable/css/styles.css"; -import { LivePlayerError, LivePlayerMode } from "@/types/live"; +import { LivePlayerError, LivePlayerMode, LiveViewMode } from "@/types/live"; import { ASPECT_VERTICAL_LAYOUT, ASPECT_WIDE_LAYOUT } from "@/types/record"; import { Skeleton } from "@/components/ui/skeleton"; import { useResizeObserver } from "@/hooks/resize-observer"; @@ -74,10 +74,10 @@ export default function DraggableGridLayout({ const birdseyeConfig = useMemo(() => config?.birdseye, [config]); // preferred live modes per camera - const [preferredLiveModes, setPreferredLiveModes] = useState<{ [key: string]: LivePlayerMode; }>({}); + const [liveViewMode] = usePersistence("liveViewMode", "Auto"); useEffect(() => { if (!cameras) return; @@ -463,6 +463,7 @@ export default function DraggableGridLayout({ } cameraConfig={camera} preferredLiveMode={preferredLiveModes[camera.name] ?? "mse"} + liveViewMode={liveViewMode} onClick={() => { !isEditMode && onSelectCamera(camera.name); }} @@ -635,6 +636,7 @@ type LivePlayerGridItemProps = { preferredLiveMode: LivePlayerMode; onClick: () => void; onError: (e: LivePlayerError) => void; + liveViewMode?: LiveViewMode; }; const LivePlayerGridItem = React.forwardRef< @@ -655,6 +657,7 @@ const LivePlayerGridItem = React.forwardRef< preferredLiveMode, onClick, onError, + liveViewMode, ...props }, ref, @@ -677,6 +680,8 @@ const LivePlayerGridItem = React.forwardRef< onClick={onClick} onError={onError} containerRef={ref as React.RefObject} + autoLive={liveViewMode == "Auto" || liveViewMode == "Continuous"} + showStillWithoutActivity={liveViewMode != "Continuous"} /> {children} diff --git a/web/src/views/live/LiveDashboardView.tsx b/web/src/views/live/LiveDashboardView.tsx index bcee49811..34bf36139 100644 --- a/web/src/views/live/LiveDashboardView.tsx +++ b/web/src/views/live/LiveDashboardView.tsx @@ -28,7 +28,7 @@ import DraggableGridLayout from "./DraggableGridLayout"; import { IoClose } from "react-icons/io5"; import { LuLayoutDashboard } from "react-icons/lu"; import { cn } from "@/lib/utils"; -import { LivePlayerError, LivePlayerMode } from "@/types/live"; +import {LivePlayerError, LivePlayerMode, LiveViewMode} from "@/types/live"; import { FaCompress, FaExpand } from "react-icons/fa"; import { useResizeObserver } from "@/hooks/resize-observer"; @@ -128,7 +128,7 @@ export default function LiveDashboardView({ // camera live views - const [autoLiveView] = usePersistence("autoLiveView", true); + const [liveViewMode] = usePersistence("liveViewMode", "Auto"); const [preferredLiveModes, setPreferredLiveModes] = useState<{ [key: string]: LivePlayerMode; }>({}); @@ -377,7 +377,10 @@ export default function LiveDashboardView({ } cameraConfig={camera} preferredLiveMode={preferredLiveModes[camera.name] ?? "mse"} - autoLive={autoLiveView} + autoLive={ + liveViewMode == "Auto" || liveViewMode == "Continuous" + } + showStillWithoutActivity={liveViewMode != "Continuous"} onClick={() => onSelectCamera(camera.name)} onError={(e) => handleError(camera.name, e)} /> diff --git a/web/src/views/settings/GeneralSettingsView.tsx b/web/src/views/settings/GeneralSettingsView.tsx index 0cb7689f6..ad1f03e8b 100644 --- a/web/src/views/settings/GeneralSettingsView.tsx +++ b/web/src/views/settings/GeneralSettingsView.tsx @@ -18,6 +18,7 @@ import { SelectItem, SelectTrigger, } from "../../components/ui/select"; +import { LiveViewMode, LiveViewModes } from "@/types/live.ts"; const PLAYBACK_RATE_DEFAULT = isSafari ? [0.5, 1, 2] : [0.5, 1, 2, 4, 8, 16]; const WEEK_STARTS_ON = ["Sunday", "Monday"]; @@ -52,52 +53,65 @@ export default function GeneralSettingsView() { // settings - const [autoLive, setAutoLive] = usePersistence("autoLiveView", true); + const [liveViewMode, setLiveViewMode] = usePersistence( + "liveViewMode", + "Auto", + ); const [playbackRate, setPlaybackRate] = usePersistence("playbackRate", 1); const [weekStartsOn, setWeekStartsOn] = usePersistence("weekStartsOn", 0); const [alertVideos, setAlertVideos] = usePersistence("alertVideos", true); return ( - <> + <>
- -
+ +
General Settings - + Live Dashboard
-
-
- - -
-
-

- Automatically switch to a camera's live view when activity is - detected. Disabling this option causes static camera images on - the Live dashboard to only update once per minute. -

-
+
Live View Modes
+
+

The mode for live streams.
Auto mode (default) will begin streaming when motion is + detected.
Static mode will update images on live streams once per minute.
Continuous mode + will stream cameras regardless of motion. Caution: Continuous mode will increase bandwidth + usage and may affect performance.

+
- + Recordings Viewer @@ -143,65 +157,66 @@ export default function GeneralSettingsView() {
- + > + {rate}x + + ))} + + + + - - Calendar - + + Calendar + -
-
-
First Weekday
-
-

The day that the weeks of the review calendar begin on.

-
-
+
+
+
First Weekday
+
+

The day that the weeks of the review calendar begin on.

- setWeekStartsOn(parseInt(value))} + > + + {WEEK_STARTS_ON[weekStartsOn ?? 0]} + + + + {WEEK_STARTS_ON.map((day, index) => ( + - {day} - - ))} - - - - -
-
+ > + {day} + + ))} + + + +
- - ); +
+
+ +) + ; }