mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-07-30 15:49:00 +03:00
Dynamically enable/disable cameras (#16894)
* config options * metrics * stop and restart ffmpeg processes * dispatcher * frontend websocket * buttons for testing * don't recreate log pipe * add/remove cam from birdseye when enabling/disabling * end all objects and send empty camera activity * enable/disable switch in ui * disable buttons when camera is disabled * use enabled_in_config for some frontend checks * tweaks * handle settings pane with disabled cameras * frontend tweaks * change to debug log * mqtt docs * tweak * ensure all ffmpeg processes are initially started * clean up * use zmq * remove camera metrics * remove camera metrics * tweaks * frontend tweaks
This commit is contained in:
@@ -2,6 +2,7 @@ import {
|
||||
useAudioState,
|
||||
useAutotrackingState,
|
||||
useDetectState,
|
||||
useEnabledState,
|
||||
usePtzCommand,
|
||||
useRecordingsState,
|
||||
useSnapshotsState,
|
||||
@@ -82,6 +83,8 @@ import {
|
||||
LuHistory,
|
||||
LuInfo,
|
||||
LuPictureInPicture,
|
||||
LuPower,
|
||||
LuPowerOff,
|
||||
LuVideo,
|
||||
LuVideoOff,
|
||||
LuX,
|
||||
@@ -185,6 +188,10 @@ export default function LiveCameraView({
|
||||
);
|
||||
}, [cameraMetadata]);
|
||||
|
||||
// camera enabled state
|
||||
const { payload: enabledState } = useEnabledState(camera.name);
|
||||
const cameraEnabled = enabledState === "ON";
|
||||
|
||||
// click overlay for ptzs
|
||||
|
||||
const [clickOverlay, setClickOverlay] = useState(false);
|
||||
@@ -470,6 +477,7 @@ export default function LiveCameraView({
|
||||
setPip(false);
|
||||
}
|
||||
}}
|
||||
disabled={!cameraEnabled}
|
||||
/>
|
||||
)}
|
||||
{supports2WayTalk && (
|
||||
@@ -481,11 +489,11 @@ export default function LiveCameraView({
|
||||
title={`${mic ? "Disable" : "Enable"} Two Way Talk`}
|
||||
onClick={() => {
|
||||
setMic(!mic);
|
||||
// Turn on audio when enabling the mic if audio is currently off
|
||||
if (!mic && !audio) {
|
||||
setAudio(true);
|
||||
}
|
||||
}}
|
||||
disabled={!cameraEnabled}
|
||||
/>
|
||||
)}
|
||||
{supportsAudioOutput && preferredLiveMode != "jsmpeg" && (
|
||||
@@ -496,6 +504,7 @@ export default function LiveCameraView({
|
||||
isActive={audio ?? false}
|
||||
title={`${audio ? "Disable" : "Enable"} Camera Audio`}
|
||||
onClick={() => setAudio(!audio)}
|
||||
disabled={!cameraEnabled}
|
||||
/>
|
||||
)}
|
||||
<FrigateCameraFeatures
|
||||
@@ -517,6 +526,7 @@ export default function LiveCameraView({
|
||||
setLowBandwidth={setLowBandwidth}
|
||||
supportsAudioOutput={supportsAudioOutput}
|
||||
supports2WayTalk={supports2WayTalk}
|
||||
cameraEnabled={cameraEnabled}
|
||||
/>
|
||||
</div>
|
||||
</TooltipProvider>
|
||||
@@ -913,6 +923,7 @@ type FrigateCameraFeaturesProps = {
|
||||
setLowBandwidth: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
supportsAudioOutput: boolean;
|
||||
supports2WayTalk: boolean;
|
||||
cameraEnabled: boolean;
|
||||
};
|
||||
function FrigateCameraFeatures({
|
||||
camera,
|
||||
@@ -931,10 +942,14 @@ function FrigateCameraFeatures({
|
||||
setLowBandwidth,
|
||||
supportsAudioOutput,
|
||||
supports2WayTalk,
|
||||
cameraEnabled,
|
||||
}: FrigateCameraFeaturesProps) {
|
||||
const { payload: detectState, send: sendDetect } = useDetectState(
|
||||
camera.name,
|
||||
);
|
||||
const { payload: enabledState, send: sendEnabled } = useEnabledState(
|
||||
camera.name,
|
||||
);
|
||||
const { payload: recordState, send: sendRecord } = useRecordingsState(
|
||||
camera.name,
|
||||
);
|
||||
@@ -1043,6 +1058,15 @@ function FrigateCameraFeatures({
|
||||
if (isDesktop || isTablet) {
|
||||
return (
|
||||
<>
|
||||
<CameraFeatureToggle
|
||||
className="p-2 md:p-0"
|
||||
variant={fullscreen ? "overlay" : "primary"}
|
||||
Icon={enabledState == "ON" ? LuPower : LuPowerOff}
|
||||
isActive={enabledState == "ON"}
|
||||
title={`${enabledState == "ON" ? "Disable" : "Enable"} Camera`}
|
||||
onClick={() => sendEnabled(enabledState == "ON" ? "OFF" : "ON")}
|
||||
disabled={false}
|
||||
/>
|
||||
<CameraFeatureToggle
|
||||
className="p-2 md:p-0"
|
||||
variant={fullscreen ? "overlay" : "primary"}
|
||||
@@ -1050,6 +1074,7 @@ function FrigateCameraFeatures({
|
||||
isActive={detectState == "ON"}
|
||||
title={`${detectState == "ON" ? "Disable" : "Enable"} Detect`}
|
||||
onClick={() => sendDetect(detectState == "ON" ? "OFF" : "ON")}
|
||||
disabled={!cameraEnabled}
|
||||
/>
|
||||
<CameraFeatureToggle
|
||||
className="p-2 md:p-0"
|
||||
@@ -1058,6 +1083,7 @@ function FrigateCameraFeatures({
|
||||
isActive={recordState == "ON"}
|
||||
title={`${recordState == "ON" ? "Disable" : "Enable"} Recording`}
|
||||
onClick={() => sendRecord(recordState == "ON" ? "OFF" : "ON")}
|
||||
disabled={!cameraEnabled}
|
||||
/>
|
||||
<CameraFeatureToggle
|
||||
className="p-2 md:p-0"
|
||||
@@ -1066,6 +1092,7 @@ function FrigateCameraFeatures({
|
||||
isActive={snapshotState == "ON"}
|
||||
title={`${snapshotState == "ON" ? "Disable" : "Enable"} Snapshots`}
|
||||
onClick={() => sendSnapshot(snapshotState == "ON" ? "OFF" : "ON")}
|
||||
disabled={!cameraEnabled}
|
||||
/>
|
||||
{audioDetectEnabled && (
|
||||
<CameraFeatureToggle
|
||||
@@ -1075,6 +1102,7 @@ function FrigateCameraFeatures({
|
||||
isActive={audioState == "ON"}
|
||||
title={`${audioState == "ON" ? "Disable" : "Enable"} Audio Detect`}
|
||||
onClick={() => sendAudio(audioState == "ON" ? "OFF" : "ON")}
|
||||
disabled={!cameraEnabled}
|
||||
/>
|
||||
)}
|
||||
{autotrackingEnabled && (
|
||||
@@ -1087,6 +1115,7 @@ function FrigateCameraFeatures({
|
||||
onClick={() =>
|
||||
sendAutotracking(autotrackingState == "ON" ? "OFF" : "ON")
|
||||
}
|
||||
disabled={!cameraEnabled}
|
||||
/>
|
||||
)}
|
||||
<CameraFeatureToggle
|
||||
@@ -1099,6 +1128,7 @@ function FrigateCameraFeatures({
|
||||
isActive={isRecording}
|
||||
title={`${isRecording ? "Stop" : "Start"} on-demand recording`}
|
||||
onClick={handleEventButtonClick}
|
||||
disabled={!cameraEnabled}
|
||||
/>
|
||||
|
||||
<DropdownMenu modal={false}>
|
||||
|
||||
Reference in New Issue
Block a user