import {
useAudioState,
useDetectState,
usePtzCommand,
useRecordingsState,
useSnapshotsState,
} from "@/api/ws";
import CameraFeatureToggle from "@/components/dynamic/CameraFeatureToggle";
import LivePlayer from "@/components/player/LivePlayer";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { TooltipProvider } from "@/components/ui/tooltip";
import useKeyboardListener from "@/hooks/use-keyboard-listener";
import { CameraConfig } from "@/types/frigateConfig";
import { CameraPtzInfo } from "@/types/ptz";
import React, { useCallback, useMemo } from "react";
import { isSafari } from "react-device-detect";
import { BsThreeDotsVertical } from "react-icons/bs";
import {
FaAngleDown,
FaAngleLeft,
FaAngleRight,
FaAngleUp,
} from "react-icons/fa";
import { IoMdArrowBack } from "react-icons/io";
import { LuEar, LuEarOff, LuVideo, LuVideoOff } from "react-icons/lu";
import {
MdNoPhotography,
MdPersonOff,
MdPersonSearch,
MdPhotoCamera,
MdZoomIn,
MdZoomOut,
} from "react-icons/md";
import { useNavigate } from "react-router-dom";
import useSWR from "swr";
type LiveCameraViewProps = {
camera: CameraConfig;
};
export default function LiveCameraView({ camera }: LiveCameraViewProps) {
const navigate = useNavigate();
// camera features
const { payload: detectState, send: sendDetect } = useDetectState(
camera.name,
);
const { payload: recordState, send: sendRecord } = useRecordingsState(
camera.name,
);
const { payload: snapshotState, send: sendSnapshot } = useSnapshotsState(
camera.name,
);
const { payload: audioState, send: sendAudio } = useAudioState(camera.name);
const growClassName = useMemo(() => {
if (camera.detect.width / camera.detect.height > 2) {
return "absolute left-2 right-2 top-[50%] -translate-y-[50%]";
} else {
return "absolute top-2 bottom-2 left-[50%] -translate-x-[50%]";
}
}, [camera]);
return (
sendDetect(detectState == "ON" ? "OFF" : "ON")}
/>
sendRecord(recordState == "ON" ? "OFF" : "ON")}
/>
sendSnapshot(snapshotState == "ON" ? "OFF" : "ON")}
/>
{camera.audio.enabled_in_config && (
sendAudio(audioState == "ON" ? "OFF" : "ON")}
/>
)}
{camera.onvif.host != "" &&
}
);
}
function PtzControlPanel({ camera }: { camera: string }) {
const { data: ptz } = useSWR(`${camera}/ptz/info`);
const { send: sendPtz } = usePtzCommand(camera);
const onStop = useCallback(
(e: React.SyntheticEvent) => {
e.preventDefault();
sendPtz("STOP");
},
[sendPtz],
);
useKeyboardListener(
["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "+", "-"],
(key, down, repeat) => {
if (repeat) {
return;
}
if (!down) {
sendPtz("STOP");
return;
}
switch (key) {
case "ArrowLeft":
sendPtz("MOVE_LEFT");
break;
case "ArrowRight":
sendPtz("MOVE_RIGHT");
break;
case "ArrowUp":
sendPtz("MOVE_UP");
break;
case "ArrowDown":
sendPtz("MOVE_DOWN");
break;
case "+":
sendPtz("ZOOM_IN");
break;
case "-":
sendPtz("ZOOM_OUT");
break;
}
},
);
return (
{ptz?.features?.includes("pt") && (
<>
>
)}
{ptz?.features?.includes("zoom") && (
<>
>
)}
{(ptz?.presets?.length ?? 0) > 0 && (
{ptz?.presets.map((preset) => {
return (
sendPtz(`preset_${preset}`)}>
{preset}
);
})}
)}
);
}