mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-13 14:45:25 +03:00
refactor camera live mode hook
This commit is contained in:
parent
b6b96dafa3
commit
398ad2e6cc
@ -1,49 +1,65 @@
|
||||
import { CameraConfig, FrigateConfig } from "@/types/frigateConfig";
|
||||
import { useMemo } from "react";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import useSWR from "swr";
|
||||
import { usePersistence } from "./use-persistence";
|
||||
import { LivePlayerMode } from "@/types/live";
|
||||
|
||||
export default function useCameraLiveMode(
|
||||
cameraConfig: CameraConfig,
|
||||
preferredMode?: LivePlayerMode,
|
||||
): LivePlayerMode | undefined {
|
||||
cameras: CameraConfig[],
|
||||
windowVisible: boolean,
|
||||
) {
|
||||
const { data: config } = useSWR<FrigateConfig>("config");
|
||||
const [preferredLiveModes, setPreferredLiveModes] = useState<{
|
||||
[key: string]: LivePlayerMode;
|
||||
}>({});
|
||||
|
||||
const restreamEnabled = useMemo(() => {
|
||||
if (!config) {
|
||||
return false;
|
||||
}
|
||||
useEffect(() => {
|
||||
if (!cameras) return;
|
||||
|
||||
return (
|
||||
cameraConfig &&
|
||||
Object.keys(config.go2rtc.streams || {}).includes(
|
||||
cameraConfig.live.stream_name,
|
||||
)
|
||||
const mseSupported =
|
||||
"MediaSource" in window || "ManagedMediaSource" in window;
|
||||
|
||||
const newPreferredLiveModes = cameras.reduce(
|
||||
(acc, camera) => {
|
||||
const isRestreamed =
|
||||
config &&
|
||||
Object.keys(config.go2rtc.streams || {}).includes(
|
||||
camera.live.stream_name,
|
||||
);
|
||||
|
||||
if (!mseSupported) {
|
||||
acc[camera.name] = isRestreamed ? "webrtc" : "jsmpeg";
|
||||
} else {
|
||||
acc[camera.name] = isRestreamed ? "mse" : "jsmpeg";
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{} as { [key: string]: LivePlayerMode },
|
||||
);
|
||||
}, [config, cameraConfig]);
|
||||
const defaultLiveMode = useMemo<LivePlayerMode | undefined>(() => {
|
||||
if (config) {
|
||||
if (restreamEnabled) {
|
||||
return preferredMode || "mse";
|
||||
}
|
||||
|
||||
return "jsmpeg";
|
||||
}
|
||||
setPreferredLiveModes(newPreferredLiveModes);
|
||||
}, [cameras, config, windowVisible]);
|
||||
|
||||
return undefined;
|
||||
}, [config, preferredMode, restreamEnabled]);
|
||||
const [viewSource] = usePersistence<LivePlayerMode>(
|
||||
`${cameraConfig.name}-source`,
|
||||
defaultLiveMode,
|
||||
const resetPreferredLiveMode = useCallback(
|
||||
(cameraName: string) => {
|
||||
const mseSupported =
|
||||
"MediaSource" in window || "ManagedMediaSource" in window;
|
||||
const isRestreamed =
|
||||
config && Object.keys(config.go2rtc.streams || {}).includes(cameraName);
|
||||
|
||||
setPreferredLiveModes((prevModes) => {
|
||||
const newModes = { ...prevModes };
|
||||
|
||||
if (!mseSupported) {
|
||||
newModes[cameraName] = isRestreamed ? "webrtc" : "jsmpeg";
|
||||
} else {
|
||||
newModes[cameraName] = isRestreamed ? "mse" : "jsmpeg";
|
||||
}
|
||||
|
||||
return newModes;
|
||||
});
|
||||
},
|
||||
[config],
|
||||
);
|
||||
|
||||
if (
|
||||
restreamEnabled &&
|
||||
(preferredMode == "mse" || preferredMode == "webrtc")
|
||||
) {
|
||||
return preferredMode;
|
||||
} else {
|
||||
return viewSource;
|
||||
}
|
||||
return { preferredLiveModes, setPreferredLiveModes, resetPreferredLiveMode };
|
||||
}
|
||||
|
||||
@ -41,6 +41,7 @@ import {
|
||||
TooltipContent,
|
||||
} from "@/components/ui/tooltip";
|
||||
import { Toaster } from "@/components/ui/sonner";
|
||||
import useCameraLiveMode from "@/hooks/use-camera-live-mode";
|
||||
|
||||
type DraggableGridLayoutProps = {
|
||||
cameras: CameraConfig[];
|
||||
@ -55,7 +56,6 @@ type DraggableGridLayoutProps = {
|
||||
setIsEditMode: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
fullscreen: boolean;
|
||||
toggleFullscreen: () => void;
|
||||
resetPreferredLiveMode: (camera: string) => void;
|
||||
};
|
||||
export default function DraggableGridLayout({
|
||||
cameras,
|
||||
@ -70,43 +70,14 @@ export default function DraggableGridLayout({
|
||||
setIsEditMode,
|
||||
fullscreen,
|
||||
toggleFullscreen,
|
||||
resetPreferredLiveMode,
|
||||
}: DraggableGridLayoutProps) {
|
||||
const { data: config } = useSWR<FrigateConfig>("config");
|
||||
const birdseyeConfig = useMemo(() => config?.birdseye, [config]);
|
||||
|
||||
// preferred live modes per camera
|
||||
|
||||
const [preferredLiveModes, setPreferredLiveModes] = useState<{
|
||||
[key: string]: LivePlayerMode;
|
||||
}>({});
|
||||
|
||||
useEffect(() => {
|
||||
if (!cameras) return;
|
||||
|
||||
const mseSupported =
|
||||
"MediaSource" in window || "ManagedMediaSource" in window;
|
||||
|
||||
const newPreferredLiveModes = cameras.reduce(
|
||||
(acc, camera) => {
|
||||
const isRestreamed =
|
||||
config &&
|
||||
Object.keys(config.go2rtc.streams || {}).includes(
|
||||
camera.live.stream_name,
|
||||
);
|
||||
|
||||
if (!mseSupported) {
|
||||
acc[camera.name] = isRestreamed ? "webrtc" : "jsmpeg";
|
||||
} else {
|
||||
acc[camera.name] = isRestreamed ? "mse" : "jsmpeg";
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{} as { [key: string]: LivePlayerMode },
|
||||
);
|
||||
|
||||
setPreferredLiveModes(newPreferredLiveModes);
|
||||
}, [cameras, config, windowVisible]);
|
||||
const { preferredLiveModes, setPreferredLiveModes, resetPreferredLiveMode } =
|
||||
useCameraLiveMode(cameras, windowVisible);
|
||||
|
||||
const ResponsiveGridLayout = useMemo(() => WidthProvider(Responsive), []);
|
||||
|
||||
|
||||
@ -28,10 +28,11 @@ 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 } from "@/types/live";
|
||||
import { FaCompress, FaExpand } from "react-icons/fa";
|
||||
import { useResizeObserver } from "@/hooks/resize-observer";
|
||||
import useKeyboardListener from "@/hooks/use-keyboard-listener";
|
||||
import useCameraLiveMode from "@/hooks/use-camera-live-mode";
|
||||
|
||||
type LiveDashboardViewProps = {
|
||||
cameras: CameraConfig[];
|
||||
@ -130,9 +131,6 @@ export default function LiveDashboardView({
|
||||
// camera live views
|
||||
|
||||
const [autoLiveView] = usePersistence("autoLiveView", true);
|
||||
const [preferredLiveModes, setPreferredLiveModes] = useState<{
|
||||
[key: string]: LivePlayerMode;
|
||||
}>({});
|
||||
|
||||
const [{ height: containerHeight }] = useResizeObserver(containerRef);
|
||||
|
||||
@ -187,54 +185,8 @@ export default function LiveDashboardView({
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!cameras) return;
|
||||
|
||||
const mseSupported =
|
||||
"MediaSource" in window || "ManagedMediaSource" in window;
|
||||
|
||||
const newPreferredLiveModes = cameras.reduce(
|
||||
(acc, camera) => {
|
||||
const isRestreamed =
|
||||
config &&
|
||||
Object.keys(config.go2rtc.streams || {}).includes(
|
||||
camera.live.stream_name,
|
||||
);
|
||||
|
||||
if (!mseSupported) {
|
||||
acc[camera.name] = isRestreamed ? "webrtc" : "jsmpeg";
|
||||
} else {
|
||||
acc[camera.name] = isRestreamed ? "mse" : "jsmpeg";
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{} as { [key: string]: LivePlayerMode },
|
||||
);
|
||||
|
||||
setPreferredLiveModes(newPreferredLiveModes);
|
||||
}, [cameras, config, windowVisible]);
|
||||
|
||||
const resetPreferredLiveMode = useCallback(
|
||||
(cameraName: string) => {
|
||||
const mseSupported =
|
||||
"MediaSource" in window || "ManagedMediaSource" in window;
|
||||
const isRestreamed =
|
||||
config && Object.keys(config.go2rtc.streams || {}).includes(cameraName);
|
||||
|
||||
setPreferredLiveModes((prevModes) => {
|
||||
const newModes = { ...prevModes };
|
||||
|
||||
if (!mseSupported) {
|
||||
newModes[cameraName] = isRestreamed ? "webrtc" : "jsmpeg";
|
||||
} else {
|
||||
newModes[cameraName] = isRestreamed ? "mse" : "jsmpeg";
|
||||
}
|
||||
|
||||
return newModes;
|
||||
});
|
||||
},
|
||||
[config],
|
||||
);
|
||||
const { preferredLiveModes, setPreferredLiveModes, resetPreferredLiveMode } =
|
||||
useCameraLiveMode(cameras, windowVisible);
|
||||
|
||||
const cameraRef = useCallback(
|
||||
(node: HTMLElement | null) => {
|
||||
@ -465,7 +417,6 @@ export default function LiveDashboardView({
|
||||
setIsEditMode={setIsEditMode}
|
||||
fullscreen={fullscreen}
|
||||
toggleFullscreen={toggleFullscreen}
|
||||
resetPreferredLiveMode={resetPreferredLiveMode}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user