increase logging and reset live mode after camera is no longer active on dashboard only

This commit is contained in:
Josh Hawkins 2024-08-16 12:34:20 -05:00
parent 2b0c3a7bf6
commit 86a989ef53
4 changed files with 50 additions and 1 deletions

View File

@ -35,6 +35,7 @@ type LivePlayerProps = {
onClick?: () => void; onClick?: () => void;
setFullResolution?: React.Dispatch<React.SetStateAction<VideoResolutionType>>; setFullResolution?: React.Dispatch<React.SetStateAction<VideoResolutionType>>;
onError?: (error: LivePlayerError) => void; onError?: (error: LivePlayerError) => void;
onResetLiveMode?: () => void;
}; };
export default function LivePlayer({ export default function LivePlayer({
@ -53,6 +54,7 @@ export default function LivePlayer({
onClick, onClick,
setFullResolution, setFullResolution,
onError, onError,
onResetLiveMode,
}: LivePlayerProps) { }: LivePlayerProps) {
const internalContainerRef = useRef<HTMLDivElement | null>(null); const internalContainerRef = useRef<HTMLDivElement | null>(null);
// camera activity // camera activity
@ -88,6 +90,7 @@ export default function LivePlayer({
const timer = setTimeout(() => { const timer = setTimeout(() => {
if (liveReadyRef.current && !cameraActiveRef.current) { if (liveReadyRef.current && !cameraActiveRef.current) {
setLiveReady(false); setLiveReady(false);
onResetLiveMode?.();
} }
}, 500); }, 500);
@ -207,7 +210,12 @@ export default function LivePlayer({
} }
useEffect(() => { useEffect(() => {
console.log(cameraConfig.name, "switching to", preferredLiveMode); console.log(
cameraConfig.name,
cameraConfig.live.stream_name,
"switching to",
preferredLiveMode,
);
}, [preferredLiveMode]); }, [preferredLiveMode]);
return ( return (

View File

@ -224,8 +224,10 @@ function MSEPlayer({
onDisconnect(); onDisconnect();
} }
if (isIOS || isSafari) { if (isIOS || isSafari) {
console.log(camera, "Safari MSE sourceopen error");
onError?.("mse-decode"); onError?.("mse-decode");
} else { } else {
console.log(camera, "MSE sourceopen error");
onError?.("startup"); onError?.("startup");
} }
}); });
@ -254,8 +256,10 @@ function MSEPlayer({
onDisconnect(); onDisconnect();
} }
if (isIOS || isSafari) { if (isIOS || isSafari) {
console.log(camera, "Safari MSE sourceopen error");
onError?.("mse-decode"); onError?.("mse-decode");
} else { } else {
console.log(camera, "MSE sourceopen error");
onError?.("startup"); onError?.("startup");
} }
}); });
@ -481,6 +485,7 @@ function MSEPlayer({
(bufferThreshold > 10 || bufferTime > 10) (bufferThreshold > 10 || bufferTime > 10)
) { ) {
onDisconnect(); onDisconnect();
console.log(camera, "MSE stream buffer is > 10 seconds");
onError?.("stalled"); onError?.("stalled");
} }
@ -533,6 +538,7 @@ function MSEPlayer({
videoRef.current videoRef.current
) { ) {
onDisconnect(); onDisconnect();
console.log(camera, "MSE buffer timeout > 3 seconds");
onError("stalled"); onError("stalled");
} }
}, 3000), }, 3000),
@ -547,6 +553,7 @@ function MSEPlayer({
if (wsRef.current) { if (wsRef.current) {
onDisconnect(); onDisconnect();
} }
console.log(camera, "MSE network error");
onError?.("startup"); onError?.("startup");
} }
@ -558,6 +565,7 @@ function MSEPlayer({
if (wsRef.current) { if (wsRef.current) {
onDisconnect(); onDisconnect();
} }
console.log(camera, "Safari MSE decoding error");
onError?.("mse-decode"); onError?.("mse-decode");
} }
@ -567,6 +575,7 @@ function MSEPlayer({
onDisconnect(); onDisconnect();
if (errorCount >= 3) { if (errorCount >= 3) {
// too many mse errors, try jsmpeg // too many mse errors, try jsmpeg
console.log(camera, "too many MSE errors");
onError?.("startup"); onError?.("startup");
} else { } else {
reconnect(5000); reconnect(5000);

View File

@ -55,6 +55,7 @@ type DraggableGridLayoutProps = {
setIsEditMode: React.Dispatch<React.SetStateAction<boolean>>; setIsEditMode: React.Dispatch<React.SetStateAction<boolean>>;
fullscreen: boolean; fullscreen: boolean;
toggleFullscreen: () => void; toggleFullscreen: () => void;
resetPreferredLiveMode: (camera: string) => void;
}; };
export default function DraggableGridLayout({ export default function DraggableGridLayout({
cameras, cameras,
@ -69,6 +70,7 @@ export default function DraggableGridLayout({
setIsEditMode, setIsEditMode,
fullscreen, fullscreen,
toggleFullscreen, toggleFullscreen,
resetPreferredLiveMode,
}: DraggableGridLayoutProps) { }: DraggableGridLayoutProps) {
const { data: config } = useSWR<FrigateConfig>("config"); const { data: config } = useSWR<FrigateConfig>("config");
const birdseyeConfig = useMemo(() => config?.birdseye, [config]); const birdseyeConfig = useMemo(() => config?.birdseye, [config]);
@ -477,6 +479,7 @@ export default function DraggableGridLayout({
return newModes; return newModes;
}); });
}} }}
onResetLiveMode={() => resetPreferredLiveMode(camera.name)}
> >
{isEditMode && showCircles && <CornerCircles />} {isEditMode && showCircles && <CornerCircles />}
</LivePlayerGridItem> </LivePlayerGridItem>
@ -635,6 +638,7 @@ type LivePlayerGridItemProps = {
preferredLiveMode: LivePlayerMode; preferredLiveMode: LivePlayerMode;
onClick: () => void; onClick: () => void;
onError: (e: LivePlayerError) => void; onError: (e: LivePlayerError) => void;
onResetLiveMode: () => void;
}; };
const LivePlayerGridItem = React.forwardRef< const LivePlayerGridItem = React.forwardRef<
@ -655,6 +659,7 @@ const LivePlayerGridItem = React.forwardRef<
preferredLiveMode, preferredLiveMode,
onClick, onClick,
onError, onError,
onResetLiveMode,
...props ...props
}, },
ref, ref,
@ -676,6 +681,7 @@ const LivePlayerGridItem = React.forwardRef<
preferredLiveMode={preferredLiveMode} preferredLiveMode={preferredLiveMode}
onClick={onClick} onClick={onClick}
onError={onError} onError={onError}
onResetLiveMode={onResetLiveMode}
containerRef={ref as React.RefObject<HTMLDivElement>} containerRef={ref as React.RefObject<HTMLDivElement>}
/> />
{children} {children}

View File

@ -214,6 +214,30 @@ export default function LiveDashboardView({
setPreferredLiveModes(newPreferredLiveModes); setPreferredLiveModes(newPreferredLiveModes);
}, [cameras, config, windowVisible]); }, [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";
}
console.log("resetting", cameraName, "to", newModes[cameraName]);
return newModes;
});
},
[config],
);
const cameraRef = useCallback( const cameraRef = useCallback(
(node: HTMLElement | null) => { (node: HTMLElement | null) => {
if (!visibleCameraObserver.current) { if (!visibleCameraObserver.current) {
@ -394,6 +418,7 @@ export default function LiveDashboardView({
autoLive={autoLiveView} autoLive={autoLiveView}
onClick={() => onSelectCamera(camera.name)} onClick={() => onSelectCamera(camera.name)}
onError={(e) => handleError(camera.name, e)} onError={(e) => handleError(camera.name, e)}
onResetLiveMode={() => resetPreferredLiveMode(camera.name)}
/> />
); );
})} })}
@ -442,6 +467,7 @@ export default function LiveDashboardView({
setIsEditMode={setIsEditMode} setIsEditMode={setIsEditMode}
fullscreen={fullscreen} fullscreen={fullscreen}
toggleFullscreen={toggleFullscreen} toggleFullscreen={toggleFullscreen}
resetPreferredLiveMode={resetPreferredLiveMode}
/> />
)} )}
</div> </div>