mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-08-02 09:02:15 +03:00
Improve live streaming (#16447)
* config file changes * config migrator * stream selection on single camera live view * camera streaming settings dialog * manage persistent group streaming settings * apply streaming settings in camera groups * add ability to clear all streaming settings from settings * docs * update reference config * fixes * clarify docs * use first stream as default in dialog * ensure still image is visible after switching stream type to none * docs * clarify docs * add ability to continue playing stream in background * fix props * put stream selection inside dropdown on desktop * add capabilities to live mode hook * live context menu component * resize observer: only return new dimensions if they've actually changed * pass volume prop to players * fix slider bug, https://github.com/shadcn-ui/ui/issues/1448 * update react-grid-layout * prevent animated transitions on draggable grid layout * add context menu to dashboards * use provider * streaming dialog from context menu * docs * add jsmpeg warning to context menu * audio and two way talk indicators in single camera view * add link to debug view * don't use hook * create manual events from live camera view * maintain grow classes on grid items * fix initial volume state on default dashboard * fix pointer events causing context menu to end up underneath image on iOS * mobile drawer tweaks * stream stats * show settings menu for non-restreamed cameras * consistent settings icon * tweaks * optional stats to fix birdseye player * add toaster to live camera view * fix crash on initial save in streaming dialog * don't require restreaming for context menu streaming settings * add debug view to context menu * stats fixes * update docs * always show stream info when restreamed * update camera streaming dialog * make note of no h265 support for webrtc * docs clarity * ensure docs show streams as a dict * docs clarity * fix css file * tweaks
This commit is contained in:
@@ -1,16 +1,29 @@
|
||||
import { CameraConfig, FrigateConfig } from "@/types/frigateConfig";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import useSWR from "swr";
|
||||
import { LivePlayerMode } from "@/types/live";
|
||||
import { LivePlayerMode, LiveStreamMetadata } from "@/types/live";
|
||||
|
||||
export default function useCameraLiveMode(
|
||||
cameras: CameraConfig[],
|
||||
windowVisible: boolean,
|
||||
) {
|
||||
const { data: config } = useSWR<FrigateConfig>("config");
|
||||
const { data: allStreamMetadata } = useSWR<{
|
||||
[key: string]: LiveStreamMetadata;
|
||||
}>(config ? "go2rtc/streams" : null, { revalidateOnFocus: false });
|
||||
|
||||
const [preferredLiveModes, setPreferredLiveModes] = useState<{
|
||||
[key: string]: LivePlayerMode;
|
||||
}>({});
|
||||
const [isRestreamedStates, setIsRestreamedStates] = useState<{
|
||||
[key: string]: boolean;
|
||||
}>({});
|
||||
const [supportsAudioOutputStates, setSupportsAudioOutputStates] = useState<{
|
||||
[key: string]: {
|
||||
supportsAudio: boolean;
|
||||
cameraName: string;
|
||||
};
|
||||
}>({});
|
||||
|
||||
useEffect(() => {
|
||||
if (!cameras) return;
|
||||
@@ -18,26 +31,56 @@ export default function useCameraLiveMode(
|
||||
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,
|
||||
);
|
||||
const newPreferredLiveModes: { [key: string]: LivePlayerMode } = {};
|
||||
const newIsRestreamedStates: { [key: string]: boolean } = {};
|
||||
const newSupportsAudioOutputStates: {
|
||||
[key: string]: { supportsAudio: boolean; cameraName: string };
|
||||
} = {};
|
||||
|
||||
if (!mseSupported) {
|
||||
acc[camera.name] = isRestreamed ? "webrtc" : "jsmpeg";
|
||||
} else {
|
||||
acc[camera.name] = isRestreamed ? "mse" : "jsmpeg";
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{} as { [key: string]: LivePlayerMode },
|
||||
);
|
||||
cameras.forEach((camera) => {
|
||||
const isRestreamed =
|
||||
config &&
|
||||
Object.keys(config.go2rtc.streams || {}).includes(
|
||||
Object.values(camera.live.streams)[0],
|
||||
);
|
||||
|
||||
newIsRestreamedStates[camera.name] = isRestreamed ?? false;
|
||||
|
||||
if (!mseSupported) {
|
||||
newPreferredLiveModes[camera.name] = isRestreamed ? "webrtc" : "jsmpeg";
|
||||
} else {
|
||||
newPreferredLiveModes[camera.name] = isRestreamed ? "mse" : "jsmpeg";
|
||||
}
|
||||
|
||||
// check each stream for audio support
|
||||
if (isRestreamed) {
|
||||
Object.values(camera.live.streams).forEach((streamName) => {
|
||||
const metadata = allStreamMetadata?.[streamName];
|
||||
newSupportsAudioOutputStates[streamName] = {
|
||||
supportsAudio: metadata
|
||||
? metadata.producers.find(
|
||||
(prod) =>
|
||||
prod.medias &&
|
||||
prod.medias.find((media) =>
|
||||
media.includes("audio, recvonly"),
|
||||
) !== undefined,
|
||||
) !== undefined
|
||||
: false,
|
||||
cameraName: camera.name,
|
||||
};
|
||||
});
|
||||
} else {
|
||||
newSupportsAudioOutputStates[camera.name] = {
|
||||
supportsAudio: false,
|
||||
cameraName: camera.name,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
setPreferredLiveModes(newPreferredLiveModes);
|
||||
}, [cameras, config, windowVisible]);
|
||||
setIsRestreamedStates(newIsRestreamedStates);
|
||||
setSupportsAudioOutputStates(newSupportsAudioOutputStates);
|
||||
}, [cameras, config, windowVisible, allStreamMetadata]);
|
||||
|
||||
const resetPreferredLiveMode = useCallback(
|
||||
(cameraName: string) => {
|
||||
@@ -61,5 +104,11 @@ export default function useCameraLiveMode(
|
||||
[config],
|
||||
);
|
||||
|
||||
return { preferredLiveModes, setPreferredLiveModes, resetPreferredLiveMode };
|
||||
return {
|
||||
preferredLiveModes,
|
||||
setPreferredLiveModes,
|
||||
resetPreferredLiveMode,
|
||||
isRestreamedStates,
|
||||
supportsAudioOutputStates,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user