From 3e1185dfb032b007dc6956299c39f48600c19926 Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Fri, 9 Feb 2024 11:04:00 -0700 Subject: [PATCH] Create live mode hook and make sure jsmpeg can be used --- web/src/components/player/LivePlayer.tsx | 10 +++-- web/src/hooks/use-camera-live-mode.ts | 49 ++++++++++++++++++++++++ web/src/pages/Live.tsx | 1 + web/src/types/live.ts | 1 + 4 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 web/src/hooks/use-camera-live-mode.ts create mode 100644 web/src/types/live.ts diff --git a/web/src/components/player/LivePlayer.tsx b/web/src/components/player/LivePlayer.tsx index 654fbb61b..a13a43707 100644 --- a/web/src/components/player/LivePlayer.tsx +++ b/web/src/components/player/LivePlayer.tsx @@ -16,15 +16,15 @@ import { BsSoundwave } from "react-icons/bs"; import Chip from "../Chip"; import useCameraActivity from "@/hooks/use-camera-activity"; import { useRecordingsState } from "@/api/ws"; +import { LivePlayerMode } from "@/types/live"; +import useCameraLiveMode from "@/hooks/use-camera-live-mode"; const emptyObject = Object.freeze({}); -type LivePlayerMode = "webrtc" | "mse" | "jsmpeg" | "debug"; - type LivePlayerProps = { className?: string; cameraConfig: CameraConfig; - liveMode?: LivePlayerMode; + preferredLiveMode?: LivePlayerMode; showStillWithoutActivity?: boolean; }; @@ -33,13 +33,15 @@ type Options = { [key: string]: boolean }; export default function LivePlayer({ className, cameraConfig, - liveMode = "jsmpeg", + preferredLiveMode, showStillWithoutActivity = true, }: LivePlayerProps) { // camera activity const { activeMotion, activeAudio, activeTracking } = useCameraActivity(cameraConfig); + const liveMode = useCameraLiveMode(cameraConfig, preferredLiveMode); + const [liveReady, setLiveReady] = useState(false); useEffect(() => { if (!liveReady) { diff --git a/web/src/hooks/use-camera-live-mode.ts b/web/src/hooks/use-camera-live-mode.ts new file mode 100644 index 000000000..214713dc1 --- /dev/null +++ b/web/src/hooks/use-camera-live-mode.ts @@ -0,0 +1,49 @@ +import { CameraConfig, FrigateConfig } from "@/types/frigateConfig"; +import { useMemo } from "react"; +import useSWR from "swr"; +import { usePersistence } from "./use-persistence"; +import { LivePlayerMode } from "@/types/live"; + +export default function useCameraLiveMode( + cameraConfig: CameraConfig, + preferredMode?: string +): LivePlayerMode { + const { data: config } = useSWR("config"); + + const restreamEnabled = useMemo(() => { + if (!config) { + return false; + } + + return ( + cameraConfig && + Object.keys(config.go2rtc.streams || {}).includes( + cameraConfig.live.stream_name + ) + ); + }, [config, cameraConfig]); + const defaultLiveMode = useMemo(() => { + if (config && cameraConfig) { + if (restreamEnabled) { + return cameraConfig.ui.live_mode || config?.ui.live_mode; + } + + return "jsmpeg"; + } + + return undefined; + }, [cameraConfig, restreamEnabled]); + const [viewSource] = usePersistence( + `${cameraConfig.name}-source`, + defaultLiveMode + ); + + if ( + restreamEnabled && + (preferredMode == "mse" || preferredMode == "webrtc") + ) { + return preferredMode; + } else { + return viewSource; + } +} diff --git a/web/src/pages/Live.tsx b/web/src/pages/Live.tsx index 93987a17b..164576ac9 100644 --- a/web/src/pages/Live.tsx +++ b/web/src/pages/Live.tsx @@ -87,6 +87,7 @@ function Live() { key={camera.name} className={`mb-2 md:mb-0 rounded-2xl bg-black ${grow}`} cameraConfig={camera} + preferredLiveMode="mse" /> ); })} diff --git a/web/src/types/live.ts b/web/src/types/live.ts new file mode 100644 index 000000000..65911ac3d --- /dev/null +++ b/web/src/types/live.ts @@ -0,0 +1 @@ +export type LivePlayerMode = "webrtc" | "mse" | "jsmpeg" | "debug"; \ No newline at end of file