mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
Add ability to add legacy birdseye to camera groups (#10404)
* initial try * add birdseye * remove vite * cleanup * memoize * remove console * ensure birdseye is actually enabled in config * birdseye first in select list and fix jsmpeg player size
This commit is contained in:
parent
dce2e9b366
commit
9e10b914c9
@ -146,6 +146,8 @@ function NewGroupDialog({ open, setOpen, currentGroups }: NewGroupDialogProps) {
|
||||
const { data: config, mutate: updateConfig } =
|
||||
useSWR<FrigateConfig>("config");
|
||||
|
||||
const birdseyeConfig = useMemo(() => config?.birdseye, [config]);
|
||||
|
||||
// add fields
|
||||
|
||||
const [editState, setEditState] = useState<"none" | "add" | "edit">("none");
|
||||
@ -298,7 +300,10 @@ function NewGroupDialog({ open, setOpen, currentGroups }: NewGroupDialogProps) {
|
||||
</div>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
{Object.keys(config?.cameras ?? {}).map((camera) => (
|
||||
{[
|
||||
...(birdseyeConfig?.enabled ? ["birdseye"] : []),
|
||||
...Object.keys(config?.cameras ?? {}),
|
||||
].map((camera) => (
|
||||
<FilterCheckBox
|
||||
key={camera}
|
||||
isChecked={cameras.includes(camera)}
|
||||
|
@ -13,21 +13,18 @@ export default function BirdseyeLivePlayer({
|
||||
birdseyeConfig,
|
||||
liveMode,
|
||||
}: LivePlayerProps) {
|
||||
let player;
|
||||
if (liveMode == "webrtc") {
|
||||
return (
|
||||
<div className="max-w-5xl">
|
||||
<WebRtcPlayer camera="birdseye" />
|
||||
</div>
|
||||
player = (
|
||||
<WebRtcPlayer className={`rounded-2xl size-full`} camera="birdseye" />
|
||||
);
|
||||
} else if (liveMode == "mse") {
|
||||
if ("MediaSource" in window || "ManagedMediaSource" in window) {
|
||||
return (
|
||||
<div className="max-w-5xl">
|
||||
<MSEPlayer camera="birdseye" />
|
||||
</div>
|
||||
player = (
|
||||
<MSEPlayer className={`rounded-2xl size-full`} camera="birdseye" />
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
player = (
|
||||
<div className="w-5xl text-center text-sm">
|
||||
MSE is only supported on iOS 17.1+. You'll need to update if available
|
||||
or use jsmpeg / webRTC streams. See the docs for more info.
|
||||
@ -35,16 +32,23 @@ export default function BirdseyeLivePlayer({
|
||||
);
|
||||
}
|
||||
} else if (liveMode == "jsmpeg") {
|
||||
return (
|
||||
<div className={`max-w-[${birdseyeConfig.width}px]`}>
|
||||
<JSMpegPlayer
|
||||
camera="birdseye"
|
||||
width={birdseyeConfig.width}
|
||||
height={birdseyeConfig.height}
|
||||
/>
|
||||
</div>
|
||||
player = (
|
||||
<JSMpegPlayer
|
||||
className="size-full flex justify-center rounded-2xl overflow-hidden"
|
||||
camera="birdseye"
|
||||
width={birdseyeConfig.width}
|
||||
height={birdseyeConfig.height}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
<ActivityIndicator />;
|
||||
player = <ActivityIndicator />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`relative flex justify-center w-full cursor-pointer`}>
|
||||
<div className="absolute top-0 inset-x-0 rounded-2xl z-10 w-full h-[30%] bg-gradient-to-b from-black/20 to-transparent pointer-events-none"></div>
|
||||
<div className="absolute bottom-0 inset-x-0 rounded-2xl z-10 w-full h-[10%] bg-gradient-to-t from-black/20 to-transparent pointer-events-none"></div>
|
||||
<div className="size-full">{player}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -11,6 +11,14 @@ function Live() {
|
||||
const [selectedCameraName, setSelectedCameraName] = useOverlayState("camera");
|
||||
const [cameraGroup] = useOverlayState("cameraGroup");
|
||||
|
||||
const includesBirdseye = useMemo(() => {
|
||||
if (config && cameraGroup) {
|
||||
return config.camera_groups[cameraGroup].cameras.includes("birdseye");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}, [config, cameraGroup]);
|
||||
|
||||
const cameras = useMemo(() => {
|
||||
if (!config) {
|
||||
return [];
|
||||
@ -40,6 +48,7 @@ function Live() {
|
||||
return (
|
||||
<LiveDashboardView
|
||||
cameras={cameras}
|
||||
includeBirdseye={includesBirdseye}
|
||||
onSelectCamera={setSelectedCameraName}
|
||||
/>
|
||||
);
|
||||
|
@ -22,6 +22,7 @@ import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import BirdseyeLivePlayer from "@/components/player/BirdseyeLivePlayer";
|
||||
|
||||
// Color data
|
||||
const colors = [
|
||||
@ -184,6 +185,7 @@ function UIPlayground() {
|
||||
};
|
||||
|
||||
const [isEventsReviewTimeline, setIsEventsReviewTimeline] = useState(true);
|
||||
const birdseyeConfig = config?.birdseye;
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -243,6 +245,14 @@ function UIPlayground() {
|
||||
<div className="w-[40px] my-4">
|
||||
<CameraActivityIndicator />
|
||||
</div>
|
||||
<div className="">
|
||||
{birdseyeConfig && (
|
||||
<BirdseyeLivePlayer
|
||||
birdseyeConfig={birdseyeConfig}
|
||||
liveMode={birdseyeConfig.restream ? "mse" : "jsmpeg"}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<p>
|
||||
<Button onClick={handleZoomOut} disabled={zoomLevel === 0}>
|
||||
Zoom Out
|
||||
|
@ -2,12 +2,13 @@ import { useFrigateReviews } from "@/api/ws";
|
||||
import Logo from "@/components/Logo";
|
||||
import { CameraGroupSelector } from "@/components/filter/CameraGroupSelector";
|
||||
import { AnimatedEventThumbnail } from "@/components/image/AnimatedEventThumbnail";
|
||||
import BirdseyeLivePlayer from "@/components/player/BirdseyeLivePlayer";
|
||||
import LivePlayer from "@/components/player/LivePlayer";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area";
|
||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||
import { usePersistence } from "@/hooks/use-persistence";
|
||||
import { CameraConfig } from "@/types/frigateConfig";
|
||||
import { CameraConfig, FrigateConfig } from "@/types/frigateConfig";
|
||||
import { ReviewSegment } from "@/types/review";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { isDesktop, isMobile, isSafari } from "react-device-detect";
|
||||
@ -16,12 +17,16 @@ import useSWR from "swr";
|
||||
|
||||
type LiveDashboardViewProps = {
|
||||
cameras: CameraConfig[];
|
||||
includeBirdseye: boolean;
|
||||
onSelectCamera: (camera: string) => void;
|
||||
};
|
||||
export default function LiveDashboardView({
|
||||
cameras,
|
||||
includeBirdseye,
|
||||
onSelectCamera,
|
||||
}: LiveDashboardViewProps) {
|
||||
const { data: config } = useSWR<FrigateConfig>("config");
|
||||
|
||||
// layout
|
||||
|
||||
const [layout, setLayout] = usePersistence<"grid" | "list">(
|
||||
@ -74,6 +79,8 @@ export default function LiveDashboardView({
|
||||
};
|
||||
}, [visibilityListener]);
|
||||
|
||||
const birdseyeConfig = useMemo(() => config?.birdseye, [config]);
|
||||
|
||||
return (
|
||||
<div className="size-full overflow-y-auto px-2">
|
||||
{isMobile && (
|
||||
@ -123,6 +130,12 @@ export default function LiveDashboardView({
|
||||
<div
|
||||
className={`my-4 grid ${layout == "grid" ? "grid-cols-2 xl:grid-cols-3 3xl:grid-cols-4" : ""} gap-2 md:gap-4 *:rounded-2xl *:bg-black`}
|
||||
>
|
||||
{includeBirdseye && birdseyeConfig?.enabled && (
|
||||
<BirdseyeLivePlayer
|
||||
birdseyeConfig={birdseyeConfig}
|
||||
liveMode={birdseyeConfig.restream ? "mse" : "jsmpeg"}
|
||||
/>
|
||||
)}
|
||||
{cameras.map((camera) => {
|
||||
let grow;
|
||||
const aspectRatio = camera.detect.width / camera.detect.height;
|
||||
|
Loading…
Reference in New Issue
Block a user