From 74047453ef08f6d4b81da6173fb164016990843e Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Mon, 7 Oct 2024 07:18:09 -0600 Subject: [PATCH 01/11] Bug Fixes (#14193) * fix getting device from empty list * Overwrite all fields * Fix header too low --- frigate/app.py | 7 ++++++- frigate/ffmpeg_presets.py | 3 +++ web/src/components/mobile/MobilePage.tsx | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/frigate/app.py b/frigate/app.py index 1d1ee10f37..992452d601 100644 --- a/frigate/app.py +++ b/frigate/app.py @@ -533,6 +533,7 @@ def init_auth(self) -> None: { User.username: "admin", User.password_hash: password_hash, + User.notification_tokens: [], } ).execute() @@ -549,7 +550,11 @@ def init_auth(self) -> None: password_hash = hash_password( password, iterations=self.config.auth.hash_iterations ) - User.replace(username="admin", password_hash=password_hash).execute() + User.replace( + username="admin", + password_hash=password_hash, + notification_tokens=[], + ).execute() logger.info("********************************************************") logger.info("********************************************************") diff --git a/frigate/ffmpeg_presets.py b/frigate/ffmpeg_presets.py index 875357de55..1a3d4408f9 100644 --- a/frigate/ffmpeg_presets.py +++ b/frigate/ffmpeg_presets.py @@ -31,6 +31,9 @@ def get_selected_gpu(self) -> str: devices = list(filter(lambda d: d.startswith("render"), os.listdir("/dev/dri"))) + if not devices: + return "/dev/dri/renderD128" + if len(devices) < 2: self._selected_gpu = f"/dev/dri/{devices[0]}" return self._selected_gpu diff --git a/web/src/components/mobile/MobilePage.tsx b/web/src/components/mobile/MobilePage.tsx index dfd221ea2c..cd1b274935 100644 --- a/web/src/components/mobile/MobilePage.tsx +++ b/web/src/components/mobile/MobilePage.tsx @@ -91,7 +91,7 @@ export function MobilePageHeader({ return (
Date: Mon, 7 Oct 2024 08:19:22 -0500 Subject: [PATCH 02/11] Explicitly set video tag dimensions to fit inside dialog (#14184) --- .../overlay/detail/SearchDetailDialog.tsx | 140 ++++++++---------- 1 file changed, 64 insertions(+), 76 deletions(-) diff --git a/web/src/components/overlay/detail/SearchDetailDialog.tsx b/web/src/components/overlay/detail/SearchDetailDialog.tsx index f27023f025..843f2de597 100644 --- a/web/src/components/overlay/detail/SearchDetailDialog.tsx +++ b/web/src/components/overlay/detail/SearchDetailDialog.tsx @@ -25,7 +25,6 @@ import HlsVideoPlayer from "@/components/player/HlsVideoPlayer"; import { baseUrl } from "@/api/baseUrl"; import { cn } from "@/lib/utils"; import ActivityIndicator from "@/components/indicators/activity-indicator"; -import { ASPECT_VERTICAL_LAYOUT, ASPECT_WIDE_LAYOUT } from "@/types/record"; import { FaCheckCircle, FaChevronDown, @@ -63,6 +62,8 @@ import { TransformComponent, TransformWrapper } from "react-zoom-pan-pinch"; import { Card, CardContent } from "@/components/ui/card"; import useImageLoaded from "@/hooks/use-image-loaded"; import ImageLoadingIndicator from "@/components/indicators/ImageLoadingIndicator"; +import { useResizeObserver } from "@/hooks/resize-observer"; +import { VideoResolutionType } from "@/types/live"; const SEARCH_TABS = [ "details", @@ -225,7 +226,7 @@ export default function SearchDetailDialog({ }} /> )} - {page == "video" && } + {page == "video" && } {page == "object lifecycle" && ( (null); @@ -608,61 +608,48 @@ function VideoTab({ search, config }: VideoTabProps) { `review/event/${search.id}`, ]); - const mainCameraAspect = useMemo(() => { - const camera = config?.cameras?.[search.camera]; + const containerRef = useRef(null); - if (!camera) { - return "normal"; - } + const [{ width: containerWidth, height: containerHeight }] = + useResizeObserver(containerRef); + const [videoResolution, setVideoResolution] = useState({ + width: 0, + height: 0, + }); - const aspectRatio = camera.detect.width / camera.detect.height; + const videoAspectRatio = useMemo(() => { + return videoResolution.width / videoResolution.height || 16 / 9; + }, [videoResolution]); - if (!aspectRatio) { - return "normal"; - } else if (aspectRatio > ASPECT_WIDE_LAYOUT) { - return "wide"; - } else if (aspectRatio < ASPECT_VERTICAL_LAYOUT) { - return "tall"; - } else { - return "normal"; - } - }, [config, search]); + const containerAspectRatio = useMemo(() => { + return containerWidth / containerHeight || 16 / 9; + }, [containerWidth, containerHeight]); - const containerClassName = useMemo(() => { - if (mainCameraAspect == "wide") { - return "flex justify-center items-center"; - } else if (mainCameraAspect == "tall") { - if (isDesktop) { - return "size-full flex flex-col justify-center items-center"; - } else { - return "size-full"; - } - } else { - return ""; - } - }, [mainCameraAspect]); - - const videoClassName = useMemo(() => { - if (mainCameraAspect == "wide") { - return "w-full aspect-wide"; - } else if (mainCameraAspect == "tall") { - if (isDesktop) { - return "w-[50%] aspect-tall flex justify-center"; - } else { - return "size-full"; - } + const videoDimensions = useMemo(() => { + if (!containerWidth || !containerHeight) + return { width: "100%", height: "100%" }; + + if (containerAspectRatio > videoAspectRatio) { + const height = containerHeight; + const width = height * videoAspectRatio; + return { width: `${width}px`, height: `${height}px` }; } else { - return "w-full aspect-video"; + const width = containerWidth; + const height = width / videoAspectRatio; + return { width: `${width}px`, height: `${height}px` }; } - }, [mainCameraAspect]); + }, [containerWidth, containerHeight, videoAspectRatio, containerAspectRatio]); return ( -
-
+
+
{(isLoading || !reviewItem) && ( - + )} -
+
setIsLoading(false)} + setFullResolution={setVideoResolution} /> -
-
- {!isLoading && reviewItem && ( -
+ + + { + if (reviewItem?.id) { + const params = new URLSearchParams({ + id: reviewItem.id, + }).toString(); + navigate(`/review?${params}`); + } + }} + > + + + + View in History + +
)} - > - - - { - if (reviewItem?.id) { - const params = new URLSearchParams({ - id: reviewItem.id, - }).toString(); - navigate(`/review?${params}`); - } - }} - > - - - - View in History -
- )} +
); } From 757150dec1703c7805486eefbfa6ad3d77ebe0e7 Mon Sep 17 00:00:00 2001 From: Rui Alves Date: Mon, 7 Oct 2024 21:27:35 +0100 Subject: [PATCH 03/11] Use Swagger documentation for Frigate HTTP API (#14178) * Updated documentation * docusaurus.config and sidebars converted to Typescript to allow for typings * Added type for sidebars.ts * Replaced integrations/api.md with automatically generated openAPI specification. Make sidebar collapsible to increase readability * Fix HTTP API links in the documentation * Added rust as language in the openapi sidebar * Make sure configuration/pwa is present * Fix API slug * Fix links * Revert sidebarCollapsible configuration * Make HTTP API sidebar collapsed by default. Added CSS for OpenAPI methods * Proper localhost server path * Proper localhost server path * No introduction page * Lint --- docs/README.md | 7 +- docs/docs/configuration/record.md | 2 +- docs/docs/configuration/snapshots.md | 2 +- docs/docs/development/contributing.md | 2 +- docs/docs/integrations/api.md | 542 - docs/docs/integrations/home-assistant.md | 2 +- docs/docusaurus.config.js | 102 - docs/docusaurus.config.ts | 158 + docs/package-lock.json | 15677 +++++++++++++-------- docs/package.json | 14 +- docs/sidebars.js | 88 - docs/sidebars.ts | 105 + docs/src/css/custom.css | 211 + docs/static/frigate-api.yaml | 3318 +++++ 14 files changed, 13932 insertions(+), 6298 deletions(-) delete mode 100644 docs/docusaurus.config.js create mode 100644 docs/docusaurus.config.ts delete mode 100644 docs/sidebars.js create mode 100644 docs/sidebars.ts create mode 100644 docs/static/frigate-api.yaml diff --git a/docs/README.md b/docs/README.md index bd4aded51f..68b27e15a9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,5 +1,10 @@ # Website -This website is built using [Docusaurus 2](https://v2.docusaurus.io/), a modern static website generator. +This website is built using [Docusaurus 3.5](https://docusaurus.io/docs), a modern static website generator. For installation and contributing instructions, please follow the [Contributing Docs](https://docs.frigate.video/development/contributing). + +# Development + +1. Run `npm i` to install dependencies +2. Run `npm run start` to start the website diff --git a/docs/docs/configuration/record.md b/docs/docs/configuration/record.md index e0e42f22ff..fd7de42d09 100644 --- a/docs/docs/configuration/record.md +++ b/docs/docs/configuration/record.md @@ -154,7 +154,7 @@ Footage can be exported from Frigate by right-clicking (desktop) or long pressin ### Time-lapse export -Time lapse exporting is available only via the [HTTP API](../integrations/api.md#post-apiexportcamerastartstart-timestampendend-timestamp). +Time lapse exporting is available only via the [HTTP API](../integrations/api/export-recording-export-camera-name-start-start-time-end-end-time-post.api.mdx). When exporting a time-lapse the default speed-up is 25x with 30 FPS. This means that every 25 seconds of (real-time) recording is condensed into 1 second of time-lapse video (always without audio) with a smoothness of 30 FPS. diff --git a/docs/docs/configuration/snapshots.md b/docs/docs/configuration/snapshots.md index 50a6c56526..e6c2609135 100644 --- a/docs/docs/configuration/snapshots.md +++ b/docs/docs/configuration/snapshots.md @@ -3,7 +3,7 @@ id: snapshots title: Snapshots --- -Frigate can save a snapshot image to `/media/frigate/clips` for each object that is detected named as `-.jpg`. They are also accessible [via the api](../integrations/api.md#get-apieventsidsnapshotjpg) +Frigate can save a snapshot image to `/media/frigate/clips` for each object that is detected named as `-.jpg`. They are also accessible [via the api](../integrations/api/event-snapshot-events-event-id-snapshot-jpg-get.api.mdx) For users with Frigate+ enabled, snapshots are accessible in the UI in the Frigate+ pane to allow for quick submission to the Frigate+ service. diff --git a/docs/docs/development/contributing.md b/docs/docs/development/contributing.md index a86b768ff9..32fc13e1f0 100644 --- a/docs/docs/development/contributing.md +++ b/docs/docs/development/contributing.md @@ -193,7 +193,7 @@ npm run test #### 1. Installation ```console -npm install +cd docs && npm install ``` #### 2. Local Development diff --git a/docs/docs/integrations/api.md b/docs/docs/integrations/api.md index db32af5749..e69de29bb2 100644 --- a/docs/docs/integrations/api.md +++ b/docs/docs/integrations/api.md @@ -1,542 +0,0 @@ ---- -id: api -title: HTTP API ---- - -A web server is available on port 5000 with the following endpoints. - -## Management & Information - -### `GET /api/config` - -A json representation of your configuration - -### `POST /api/restart` - -Restarts Frigate process. - -### `GET /api/stats` - -Contains some granular debug info that can be used for sensors in Home Assistant. - -Sample response: - -```json -{ - /* Per Camera Stats */ - "cameras": { - "back": { - /*************** - * Frames per second being consumed from your camera. If this is higher - * than it is supposed to be, you should set -r FPS in your input_args. - * camera_fps = process_fps + skipped_fps - ***************/ - "camera_fps": 5.0, - /*************** - * Number of times detection is run per second. This can be higher than - * your camera FPS because Frigate often looks at the same frame multiple times - * or in multiple locations - ***************/ - "detection_fps": 1.5, - /*************** - * PID for the ffmpeg process that consumes this camera - ***************/ - "capture_pid": 27, - /*************** - * PID for the process that runs detection for this camera - ***************/ - "pid": 34, - /*************** - * Frames per second being processed by Frigate. - ***************/ - "process_fps": 5.1, - /*************** - * Frames per second skip for processing by Frigate. - ***************/ - "skipped_fps": 0.0 - } - }, - /*************** - * Sum of detection_fps across all cameras and detectors. - * This should be the sum of all detection_fps values from cameras. - ***************/ - "detection_fps": 5.0, - /* Detectors Stats */ - "detectors": { - "coral": { - /*************** - * Timestamp when object detection started. If this value stays non-zero and constant - * for a long time, that means the detection process is stuck. - ***************/ - "detection_start": 0.0, - /*************** - * Time spent running object detection in milliseconds. - ***************/ - "inference_speed": 10.48, - /*************** - * PID for the shared process that runs object detection on the Coral. - ***************/ - "pid": 25321 - } - }, - "service": { - /* Uptime in seconds */ - "uptime": 10, - "version": "0.10.1-8883709", - "latest_version": "0.10.1", - /* Storage data in MB for important locations */ - "storage": { - "/media/frigate/clips": { - "total": 1000, - "used": 700, - "free": 300, - "mnt_type": "ext4" - }, - "/media/frigate/recordings": { - "total": 1000, - "used": 700, - "free": 300, - "mnt_type": "ext4" - }, - "/tmp/cache": { - "total": 256, - "used": 100, - "free": 156, - "mnt_type": "tmpfs" - }, - "/dev/shm": { - "total": 256, - "used": 100, - "free": 156, - "mnt_type": "tmpfs" - } - } - }, - "cpu_usages": { - "pid": { - "cmdline": "ffmpeg...", - "cpu": "5.0", - "cpu_average": "3.0", - "mem": "0.5" - } - }, - "gpu_usages": { - "gpu-type": { - "gpu": "17%", - "mem": "18%" - } - } -} -``` - -### `GET /api/version` - -Version info - -### `GET /api/ffprobe` - -Get ffprobe output for camera feed paths. - -| param | Type | Description | -| ------- | ------ | ---------------------------------- | -| `paths` | string | `,` separated list of camera paths | - -### `GET /api//ptz/info` - -Get PTZ info for the camera. - -## Camera Media - -### `GET /api/` - -An mjpeg stream for debugging. Keep in mind the mjpeg endpoint is for debugging only and will put additional load on the system when in use. - -Accepts the following query string parameters: - -| param | Type | Description | -| ----------- | ---- | ------------------------------------------------------------------ | -| `fps` | int | Frame rate | -| `h` | int | Height in pixels | -| `bbox` | int | Show bounding boxes for detected objects (0 or 1) | -| `timestamp` | int | Print the timestamp in the upper left (0 or 1) | -| `zones` | int | Draw the zones on the image (0 or 1) | -| `mask` | int | Overlay the mask on the image (0 or 1) | -| `motion` | int | Draw blue boxes for areas with detected motion (0 or 1) | -| `regions` | int | Draw green boxes for areas where object detection was run (0 or 1) | - -You can access a higher resolution mjpeg stream by appending `h=height-in-pixels` to the endpoint. For example `/api/back?h=1080`. You can also increase the FPS by appending `fps=frame-rate` to the URL such as `/api/back?fps=10` or both with `?fps=10&h=1000`. - -### `GET /api//latest.jpg[?h=300]` - -The most recent frame that Frigate has finished processing. It is a full resolution image by default. - -Accepts the following query string parameters: - -| param | Type | Description | -| ----------- | ---- | ------------------------------------------------------------------ | -| `h` | int | Height in pixels | -| `bbox` | int | Show bounding boxes for detected objects (0 or 1) | -| `timestamp` | int | Print the timestamp in the upper left (0 or 1) | -| `zones` | int | Draw the zones on the image (0 or 1) | -| `mask` | int | Overlay the mask on the image (0 or 1) | -| `motion` | int | Draw blue boxes for areas with detected motion (0 or 1) | -| `regions` | int | Draw green boxes for areas where object detection was run (0 or 1) | -| `quality` | int | Jpeg encoding quality (0-100). Defaults to 70. | - -Example parameters: - -- `h=300`: resizes the image to 300 pixels tall - -### `GET /api//