Add autotracking enable/disable button to live view (#11396)

This commit is contained in:
Josh Hawkins 2024-05-16 09:32:39 -05:00 committed by GitHub
parent 16ead917ea
commit 525de1a467
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 48 additions and 3 deletions

View File

@ -42,13 +42,17 @@ function useValue(): useValueReturn {
const cameraStates: WsState = {}; const cameraStates: WsState = {};
Object.keys(config.cameras).forEach((camera) => { Object.keys(config.cameras).forEach((camera) => {
const { name, record, detect, snapshots, audio } = config.cameras[camera]; const { name, record, detect, snapshots, audio, onvif } =
config.cameras[camera];
cameraStates[`${name}/recordings/state`] = record.enabled ? "ON" : "OFF"; cameraStates[`${name}/recordings/state`] = record.enabled ? "ON" : "OFF";
cameraStates[`${name}/detect/state`] = detect.enabled ? "ON" : "OFF"; cameraStates[`${name}/detect/state`] = detect.enabled ? "ON" : "OFF";
cameraStates[`${name}/snapshots/state`] = snapshots.enabled cameraStates[`${name}/snapshots/state`] = snapshots.enabled
? "ON" ? "ON"
: "OFF"; : "OFF";
cameraStates[`${name}/audio/state`] = audio.enabled ? "ON" : "OFF"; cameraStates[`${name}/audio/state`] = audio.enabled ? "ON" : "OFF";
cameraStates[`${name}/ptz_autotracker/state`] = onvif.autotracking.enabled
? "ON"
: "OFF";
}); });
setWsState({ ...wsState, ...cameraStates }); setWsState({ ...wsState, ...cameraStates });
@ -161,6 +165,17 @@ export function useAudioState(camera: string): {
return { payload: payload as ToggleableSetting, send }; return { payload: payload as ToggleableSetting, send };
} }
export function useAutotrackingState(camera: string): {
payload: ToggleableSetting;
send: (payload: ToggleableSetting, retain?: boolean) => void;
} {
const {
value: { payload },
send,
} = useWs(`${camera}/ptz_autotracker/state`, `${camera}/ptz_autotracker/set`);
return { payload: payload as ToggleableSetting, send };
}
export function usePtzCommand(camera: string): { export function usePtzCommand(camera: string): {
payload: string; payload: string;
send: (payload: string, retain?: boolean) => void; send: (payload: string, retain?: boolean) => void;

View File

@ -305,6 +305,7 @@ function MSEPlayer({
onLoadedData={onPlaying} onLoadedData={onPlaying}
onLoadedMetadata={handleLoadedMetadata} onLoadedMetadata={handleLoadedMetadata}
muted={!audioEnabled} muted={!audioEnabled}
onError={onClose}
/> />
); );
} }

View File

@ -1,5 +1,6 @@
import { import {
useAudioState, useAudioState,
useAutotrackingState,
useDetectState, useDetectState,
usePtzCommand, usePtzCommand,
useRecordingsState, useRecordingsState,
@ -50,7 +51,7 @@ import {
FaMicrophoneSlash, FaMicrophoneSlash,
} from "react-icons/fa"; } from "react-icons/fa";
import { GiSpeaker, GiSpeakerOff } from "react-icons/gi"; import { GiSpeaker, GiSpeakerOff } from "react-icons/gi";
import { HiViewfinderCircle } from "react-icons/hi2"; import { TbViewfinder, TbViewfinderOff } from "react-icons/tb";
import { IoMdArrowRoundBack } from "react-icons/io"; import { IoMdArrowRoundBack } from "react-icons/io";
import { import {
LuEar, LuEar,
@ -326,6 +327,9 @@ export default function LiveCameraView({ camera }: LiveCameraViewProps) {
<FrigateCameraFeatures <FrigateCameraFeatures
camera={camera.name} camera={camera.name}
audioDetectEnabled={camera.audio.enabled_in_config} audioDetectEnabled={camera.audio.enabled_in_config}
autotrackingEnabled={
camera.onvif.autotracking.enabled_in_config
}
fullscreen={fullscreen} fullscreen={fullscreen}
/> />
</div> </div>
@ -534,7 +538,7 @@ function PtzControlPanel({
className={`${clickOverlay ? "text-selected" : "text-primary"}`} className={`${clickOverlay ? "text-selected" : "text-primary"}`}
onClick={() => setClickOverlay(!clickOverlay)} onClick={() => setClickOverlay(!clickOverlay)}
> >
<HiViewfinderCircle /> <TbViewfinder />
</Button> </Button>
</> </>
)} )}
@ -566,11 +570,13 @@ function PtzControlPanel({
type FrigateCameraFeaturesProps = { type FrigateCameraFeaturesProps = {
camera: string; camera: string;
audioDetectEnabled: boolean; audioDetectEnabled: boolean;
autotrackingEnabled: boolean;
fullscreen: boolean; fullscreen: boolean;
}; };
function FrigateCameraFeatures({ function FrigateCameraFeatures({
camera, camera,
audioDetectEnabled, audioDetectEnabled,
autotrackingEnabled,
fullscreen, fullscreen,
}: FrigateCameraFeaturesProps) { }: FrigateCameraFeaturesProps) {
const { payload: detectState, send: sendDetect } = useDetectState(camera); const { payload: detectState, send: sendDetect } = useDetectState(camera);
@ -578,6 +584,8 @@ function FrigateCameraFeatures({
const { payload: snapshotState, send: sendSnapshot } = const { payload: snapshotState, send: sendSnapshot } =
useSnapshotsState(camera); useSnapshotsState(camera);
const { payload: audioState, send: sendAudio } = useAudioState(camera); const { payload: audioState, send: sendAudio } = useAudioState(camera);
const { payload: autotrackingState, send: sendAutotracking } =
useAutotrackingState(camera);
// desktop shows icons part of row // desktop shows icons part of row
if (isDesktop) { if (isDesktop) {
@ -617,6 +625,18 @@ function FrigateCameraFeatures({
onClick={() => sendAudio(audioState == "ON" ? "OFF" : "ON")} onClick={() => sendAudio(audioState == "ON" ? "OFF" : "ON")}
/> />
)} )}
{autotrackingEnabled && (
<CameraFeatureToggle
className="p-2 md:p-0"
variant={fullscreen ? "overlay" : "primary"}
Icon={autotrackingState == "ON" ? TbViewfinder : TbViewfinderOff}
isActive={autotrackingState == "ON"}
title={`${autotrackingState == "ON" ? "Disable" : "Enable"} Autotracking`}
onClick={() =>
sendAutotracking(autotrackingState == "ON" ? "OFF" : "ON")
}
/>
)}
</> </>
); );
} }
@ -662,6 +682,15 @@ function FrigateCameraFeatures({
onCheckedChange={() => sendAudio(audioState == "ON" ? "OFF" : "ON")} onCheckedChange={() => sendAudio(audioState == "ON" ? "OFF" : "ON")}
/> />
)} )}
{autotrackingEnabled && (
<FilterSwitch
label="Autotracking"
isChecked={autotrackingState == "ON"}
onCheckedChange={() =>
sendAutotracking(autotrackingState == "ON" ? "OFF" : "ON")
}
/>
)}
</DrawerContent> </DrawerContent>
</Drawer> </Drawer>
); );