Live player fixes (#13143)

* Jump to live when exceeding buffer time threshold in MSE player

* clean up

* Try adjusting playback rate instead of jumping to live

* clean up

* fallback to webrtc if enabled before jsmpeg

* baseline

* clean up

* remove comments

* adaptive playback rate and intelligent switching improvements

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

* jump to live on safari/iOS

* clean up

* clean up

* refactor camera live mode hook

* remove key listener

* resolve conflicts
This commit is contained in:
Josh Hawkins
2024-08-17 13:16:48 -05:00
committed by GitHub
parent 4133e454c4
commit 8c23ede683
7 changed files with 228 additions and 120 deletions

View File

@@ -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 };
}