mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-27 19:57:54 -05:00
Compare commits
6 Commits
plus_docs_
...
birdseye-v
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cbdcda1536 | ||
|
|
22efd2c46b | ||
|
|
0310a9654d | ||
|
|
7df3622243 | ||
|
|
dd8282ff3c | ||
|
|
984d654c40 |
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
default_target: local
|
||||
|
||||
COMMIT_HASH := $(shell git log -1 --pretty=format:"%h"|tail -1)
|
||||
VERSION = 0.17.0
|
||||
VERSION = 0.17.1
|
||||
IMAGE_REPO ?= ghcr.io/blakeblackshear/frigate
|
||||
GITHUB_REF_NAME ?= $(shell git rev-parse --abbrev-ref HEAD)
|
||||
BOARDS= #Initialized empty
|
||||
|
||||
@@ -1571,12 +1571,12 @@ YOLOv9 model can be exported as ONNX using the command below. You can copy and p
|
||||
```sh
|
||||
docker build . --build-arg MODEL_SIZE=t --build-arg IMG_SIZE=320 --output . -f- <<'EOF'
|
||||
FROM python:3.11 AS build
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y libgl1 && rm -rf /var/lib/apt/lists/*
|
||||
COPY --from=ghcr.io/astral-sh/uv:0.8.0 /uv /bin/
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y cmake libgl1 && rm -rf /var/lib/apt/lists/*
|
||||
COPY --from=ghcr.io/astral-sh/uv:0.10.4 /uv /bin/
|
||||
WORKDIR /yolov9
|
||||
ADD https://github.com/WongKinYiu/yolov9.git .
|
||||
RUN uv pip install --system -r requirements.txt
|
||||
RUN uv pip install --system onnx==1.18.0 onnxruntime onnx-simplifier>=0.4.1 onnxscript
|
||||
RUN uv pip install --system onnx==1.18.0 onnxruntime onnx-simplifier==0.4.* onnxscript
|
||||
ARG MODEL_SIZE
|
||||
ARG IMG_SIZE
|
||||
ADD https://github.com/WongKinYiu/yolov9/releases/download/v0.1/yolov9-${MODEL_SIZE}-converted.pt yolov9-${MODEL_SIZE}.pt
|
||||
|
||||
@@ -37,18 +37,18 @@ The following diagram adds a lot more detail than the simple view explained befo
|
||||
%%{init: {"themeVariables": {"edgeLabelBackground": "transparent"}}}%%
|
||||
|
||||
flowchart TD
|
||||
RecStore[(Recording\nstore)]
|
||||
SnapStore[(Snapshot\nstore)]
|
||||
RecStore[(Recording<br>store)]
|
||||
SnapStore[(Snapshot<br>store)]
|
||||
|
||||
subgraph Acquisition
|
||||
Cam["Camera"] -->|FFmpeg supported| Stream
|
||||
Cam -->|"Other streaming\nprotocols"| go2rtc
|
||||
Cam -->|"Other streaming<br>protocols"| go2rtc
|
||||
go2rtc("go2rtc") --> Stream
|
||||
Stream[Capture main and\nsub streams] --> |detect stream|Decode(Decode and\ndownscale)
|
||||
Stream[Capture main and<br>sub streams] --> |detect stream|Decode(Decode and<br>downscale)
|
||||
end
|
||||
subgraph Motion
|
||||
Decode --> MotionM(Apply\nmotion masks)
|
||||
MotionM --> MotionD(Motion\ndetection)
|
||||
Decode --> MotionM(Apply<br>motion masks)
|
||||
MotionM --> MotionD(Motion<br>detection)
|
||||
end
|
||||
subgraph Detection
|
||||
MotionD --> |motion regions| ObjectD(Object detection)
|
||||
@@ -60,8 +60,8 @@ flowchart TD
|
||||
MotionD --> |motion event|Birdseye
|
||||
ObjectZ --> |object event|Birdseye
|
||||
|
||||
MotionD --> |"video segments\n(retain motion)"|RecStore
|
||||
MotionD --> |"video segments<br>(retain motion)"|RecStore
|
||||
ObjectZ --> |detection clip|RecStore
|
||||
Stream -->|"video segments\n(retain all)"| RecStore
|
||||
Stream -->|"video segments<br>(retain all)"| RecStore
|
||||
ObjectZ --> |detection snapshot|SnapStore
|
||||
```
|
||||
|
||||
@@ -77,6 +77,7 @@ import { useStreamingSettings } from "@/context/streaming-settings-provider";
|
||||
import { Trans, useTranslation } from "react-i18next";
|
||||
import { CameraNameLabel } from "../camera/FriendlyNameLabel";
|
||||
import { useAllowedCameras } from "@/hooks/use-allowed-cameras";
|
||||
import { useHasFullCameraAccess } from "@/hooks/use-has-full-camera-access";
|
||||
import { useIsAdmin } from "@/hooks/use-is-admin";
|
||||
import { useUserPersistedOverlayState } from "@/hooks/use-overlay-state";
|
||||
|
||||
@@ -677,7 +678,7 @@ export function CameraGroupEdit({
|
||||
);
|
||||
|
||||
const allowedCameras = useAllowedCameras();
|
||||
const isAdmin = useIsAdmin();
|
||||
const hasFullCameraAccess = useHasFullCameraAccess();
|
||||
|
||||
const [openCamera, setOpenCamera] = useState<string | null>();
|
||||
|
||||
@@ -866,8 +867,7 @@ export function CameraGroupEdit({
|
||||
<FormDescription>{t("group.cameras.desc")}</FormDescription>
|
||||
<FormMessage />
|
||||
{[
|
||||
...(birdseyeConfig?.enabled &&
|
||||
(isAdmin || "birdseye" in allowedCameras)
|
||||
...(birdseyeConfig?.enabled && hasFullCameraAccess
|
||||
? ["birdseye"]
|
||||
: []),
|
||||
...Object.keys(config?.cameras ?? {})
|
||||
|
||||
26
web/src/hooks/use-has-full-camera-access.ts
Normal file
26
web/src/hooks/use-has-full-camera-access.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { useAllowedCameras } from "@/hooks/use-allowed-cameras";
|
||||
import useSWR from "swr";
|
||||
import { FrigateConfig } from "@/types/frigateConfig";
|
||||
|
||||
/**
|
||||
* Returns true if the current user has access to all cameras.
|
||||
* This is used to determine birdseye access — users who can see
|
||||
* all cameras should also be able to see the birdseye view.
|
||||
*/
|
||||
export function useHasFullCameraAccess() {
|
||||
const allowedCameras = useAllowedCameras();
|
||||
const { data: config } = useSWR<FrigateConfig>("config", {
|
||||
revalidateOnFocus: false,
|
||||
});
|
||||
|
||||
if (!config?.cameras) return false;
|
||||
|
||||
const enabledCameraNames = Object.entries(config.cameras)
|
||||
.filter(([, cam]) => cam.enabled_in_config)
|
||||
.map(([name]) => name);
|
||||
|
||||
return (
|
||||
enabledCameraNames.length > 0 &&
|
||||
enabledCameraNames.every((name) => allowedCameras.includes(name))
|
||||
);
|
||||
}
|
||||
@@ -11,12 +11,12 @@ import { useTranslation } from "react-i18next";
|
||||
import { useEffect, useMemo, useRef } from "react";
|
||||
import useSWR from "swr";
|
||||
import { useAllowedCameras } from "@/hooks/use-allowed-cameras";
|
||||
import { useIsAdmin } from "@/hooks/use-is-admin";
|
||||
import { useHasFullCameraAccess } from "@/hooks/use-has-full-camera-access";
|
||||
|
||||
function Live() {
|
||||
const { t } = useTranslation(["views/live"]);
|
||||
const { data: config } = useSWR<FrigateConfig>("config");
|
||||
const isAdmin = useIsAdmin();
|
||||
const hasFullCameraAccess = useHasFullCameraAccess();
|
||||
|
||||
// selection
|
||||
|
||||
@@ -90,8 +90,8 @@ function Live() {
|
||||
const allowedCameras = useAllowedCameras();
|
||||
|
||||
const includesBirdseye = useMemo(() => {
|
||||
// Restricted users should never have access to birdseye
|
||||
if (!isAdmin) {
|
||||
// Users without access to all cameras should not have access to birdseye
|
||||
if (!hasFullCameraAccess) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ function Live() {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}, [config, cameraGroup, isAdmin]);
|
||||
}, [config, cameraGroup, hasFullCameraAccess]);
|
||||
|
||||
const cameras = useMemo(() => {
|
||||
if (!config) {
|
||||
@@ -151,7 +151,9 @@ function Live() {
|
||||
|
||||
return (
|
||||
<div className="size-full" ref={mainRef}>
|
||||
{selectedCameraName === "birdseye" ? (
|
||||
{selectedCameraName === "birdseye" &&
|
||||
hasFullCameraAccess &&
|
||||
config?.birdseye?.enabled ? (
|
||||
<LiveBirdseyeView
|
||||
supportsFullscreen={supportsFullScreen}
|
||||
fullscreen={fullscreen}
|
||||
|
||||
Reference in New Issue
Block a user