Compare commits
28 Commits
0e9eef7480
...
98918b1583
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98918b1583 | ||
|
|
1d37ce8915 | ||
|
|
c37c327bbd | ||
|
|
4d99bff20a | ||
|
|
7d4ae1f030 | ||
|
|
5a3e1f12cd | ||
|
|
fb328c0529 | ||
|
|
0a0e320939 | ||
|
|
61e8d80117 | ||
|
|
c858aa94ae | ||
|
|
1546acae11 | ||
|
|
9ca68a247a | ||
|
|
34415f95a2 | ||
|
|
e96ea54a66 | ||
|
|
951a07d5a8 | ||
|
|
7961acf09d | ||
|
|
a0b9dd661c | ||
|
|
5559519fb3 | ||
|
|
3fd0547881 | ||
|
|
e5aaf3cc1b | ||
|
|
ab41a56856 | ||
|
|
f8474f9c4a | ||
|
|
5115026a4e | ||
|
|
af7f9e39c9 | ||
|
|
2d8b6c8301 | ||
|
|
84c3f98a09 | ||
|
|
c87f89fcc1 | ||
|
|
815303922d |
4
LICENSE
@ -1,6 +1,6 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2020 Blake Blackshear
|
||||
Copyright (c) 2025 Frigate LLC (Frigate™)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
SOFTWARE.
|
||||
|
||||
19
README.md
@ -1,8 +1,10 @@
|
||||
<p align="center">
|
||||
<img align="center" alt="logo" src="docs/static/img/frigate.png">
|
||||
<img align="center" alt="logo" src="docs/static/img/branding/frigate.png">
|
||||
</p>
|
||||
|
||||
# Frigate - NVR With Realtime Object Detection for IP Cameras
|
||||
# Frigate NVR™ - Realtime Object Detection for IP Cameras
|
||||
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
|
||||
<a href="https://hosted.weblate.org/engage/frigate-nvr/">
|
||||
<img src="https://hosted.weblate.org/widget/frigate-nvr/language-badge.svg" alt="Translation status" />
|
||||
@ -33,6 +35,15 @@ View the documentation at https://docs.frigate.video
|
||||
|
||||
If you would like to make a donation to support development, please use [Github Sponsors](https://github.com/sponsors/blakeblackshear).
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the **MIT License**.
|
||||
|
||||
- **Code:** The source code, configuration files, and documentation in this repository are available under the [MIT License](LICENSE). You are free to use, modify, and distribute the code as long as you include the original copyright notice.
|
||||
- **Trademarks:** The "Frigate" name, the "Frigate NVR" brand, and the Frigate logo are **trademarks of Frigate LLC** and are **not** covered by the MIT License.
|
||||
|
||||
Please see our [Trademark Policy](TRADEMARK.md) for details on acceptable use of our brand assets.
|
||||
|
||||
## Screenshots
|
||||
|
||||
### Live dashboard
|
||||
@ -66,3 +77,7 @@ We use [Weblate](https://hosted.weblate.org/projects/frigate-nvr/) to support la
|
||||
<a href="https://hosted.weblate.org/engage/frigate-nvr/">
|
||||
<img src="https://hosted.weblate.org/widget/frigate-nvr/multi-auto.svg" alt="Translation status" />
|
||||
</a>
|
||||
|
||||
---
|
||||
|
||||
**Copyright © 2025 Frigate LLC.**
|
||||
|
||||
58
TRADEMARK.md
Normal file
@ -0,0 +1,58 @@
|
||||
# Trademark Policy
|
||||
|
||||
**Last Updated:** November 2025
|
||||
|
||||
This document outlines the policy regarding the use of the trademarks associated with the Frigate NVR project.
|
||||
|
||||
## 1. Our Trademarks
|
||||
|
||||
The following terms and visual assets are trademarks (the "Marks") of **Frigate LLC**:
|
||||
|
||||
- **Frigate™**
|
||||
- **Frigate NVR™**
|
||||
- **Frigate+™**
|
||||
- **The Frigate Logo**
|
||||
|
||||
**Note on Common Law Rights:**
|
||||
Frigate LLC asserts all common law rights in these Marks. The absence of a federal registration symbol (®) does not constitute a waiver of our intellectual property rights.
|
||||
|
||||
## 2. Interaction with the MIT License
|
||||
|
||||
The software in this repository is licensed under the [MIT License](LICENSE).
|
||||
|
||||
**Crucial Distinction:**
|
||||
|
||||
- The **Code** is free to use, modify, and distribute under the MIT terms.
|
||||
- The **Brand (Trademarks)** is **NOT** licensed under MIT.
|
||||
|
||||
You may not use the Marks in any way that is not explicitly permitted by this policy or by written agreement with Frigate LLC.
|
||||
|
||||
## 3. Acceptable Use
|
||||
|
||||
You may use the Marks without prior written permission in the following specific contexts:
|
||||
|
||||
- **Referential Use:** To truthfully refer to the software (e.g., _"I use Frigate NVR for my home security"_).
|
||||
- **Compatibility:** To indicate that your product or project works with the software (e.g., _"MyPlugin for Frigate NVR"_ or _"Compatible with Frigate"_).
|
||||
- **Commentary:** In news articles, blog posts, or tutorials discussing the software.
|
||||
|
||||
## 4. Prohibited Use
|
||||
|
||||
You may **NOT** use the Marks in the following ways:
|
||||
|
||||
- **Commercial Products:** You may not use "Frigate" in the name of a commercial product, service, or app (e.g., selling an app named _"Frigate Viewer"_ is prohibited).
|
||||
- **Implying Affiliation:** You may not use the Marks in a way that suggests your project is official, sponsored by, or endorsed by Frigate LLC.
|
||||
- **Confusing Forks:** If you fork this repository to create a derivative work, you **must** remove the Frigate logo and rename your project to avoid user confusion. You cannot distribute a modified version of the software under the name "Frigate".
|
||||
- **Domain Names:** You may not register domain names containing "Frigate" that are likely to confuse users (e.g., `frigate-official-support.com`).
|
||||
|
||||
## 5. The Logo
|
||||
|
||||
The Frigate logo (the bird icon) is a visual trademark.
|
||||
|
||||
- You generally **cannot** use the logo on your own website or product packaging without permission.
|
||||
- If you are building a dashboard or integration that interfaces with Frigate, you may use the logo only to represent the Frigate node/service, provided it does not imply you _are_ Frigate.
|
||||
|
||||
## 6. Questions & Permissions
|
||||
|
||||
If you are unsure if your intended use violates this policy, or if you wish to request a specific license to use the Marks (e.g., for a partnership), please contact us at:
|
||||
|
||||
**help@frigate.video**
|
||||
@ -145,6 +145,6 @@ rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install yq, for frigate-prepare and go2rtc echo source
|
||||
curl -fsSL \
|
||||
"https://github.com/mikefarah/yq/releases/download/v4.33.3/yq_linux_$(dpkg --print-architecture)" \
|
||||
"https://github.com/mikefarah/yq/releases/download/v4.48.2/yq_linux_$(dpkg --print-architecture)" \
|
||||
--output /usr/local/bin/yq
|
||||
chmod +x /usr/local/bin/yq
|
||||
|
||||
@ -53,6 +53,17 @@ environment_vars:
|
||||
VARIABLE_NAME: variable_value
|
||||
```
|
||||
|
||||
#### TensorFlow Thread Configuration
|
||||
|
||||
If you encounter thread creation errors during classification model training, you can limit TensorFlow's thread usage:
|
||||
|
||||
```yaml
|
||||
environment_vars:
|
||||
TF_INTRA_OP_PARALLELISM_THREADS: "2" # Threads within operations (0 = use default)
|
||||
TF_INTER_OP_PARALLELISM_THREADS: "2" # Threads between operations (0 = use default)
|
||||
TF_DATASET_THREAD_POOL_SIZE: "2" # Data pipeline threads (0 = use default)
|
||||
```
|
||||
|
||||
### `database`
|
||||
|
||||
Tracked object and recording information is managed in a sqlite database at `/config/frigate.db`. If that database is deleted, recordings will be orphaned and will need to be cleaned up manually. They also won't show up in the Media Browser within Home Assistant.
|
||||
@ -247,7 +258,7 @@ curl -X POST http://frigate_host:5000/api/config/save -d @config.json
|
||||
if you'd like you can use your yaml config directly by using [`yq`](https://github.com/mikefarah/yq) to convert it to json:
|
||||
|
||||
```bash
|
||||
yq r -j config.yml | curl -X POST http://frigate_host:5000/api/config/save -d @-
|
||||
yq -o=json '.' config.yaml | curl -X POST 'http://frigate_host:5000/api/config/save?save_option=saveonly' --data-binary @-
|
||||
```
|
||||
|
||||
### Via Command Line
|
||||
|
||||
@ -214,6 +214,42 @@ For restreamed cameras, go2rtc remains active but does not use system resources
|
||||
|
||||
Note that disabling a camera through the config file (`enabled: False`) removes all related UI elements, including historical footage access. To retain access while disabling the camera, keep it enabled in the config and use the UI or MQTT to disable it temporarily.
|
||||
|
||||
### Live player error messages
|
||||
|
||||
When your browser runs into problems playing back your camera streams, it will log short error messages to the browser console. They indicate playback, codec, or network issues on the client/browser side, not something server side with Frigate itself. Below are the common messages you may see and simple actions you can take to try to resolve them.
|
||||
|
||||
- **startup**
|
||||
|
||||
- What it means: The player failed to initialize or connect to the live stream (network or startup error).
|
||||
- What to try: Reload the Live view or click _Reset_. Verify `go2rtc` is running and the camera stream is reachable. Try switching to a different stream from the Live UI dropdown (if available) or use a different browser.
|
||||
|
||||
- Possible console messages from the player code:
|
||||
|
||||
- `Error opening MediaSource.`
|
||||
- `Browser reported a network error.`
|
||||
- `Max error count ${errorCount} exceeded.` (the numeric value will vary)
|
||||
|
||||
- **mse-decode**
|
||||
|
||||
- What it means: The browser reported a decoding error while trying to play the stream, which usually is a result of a codec incompatibility or corrupted frames.
|
||||
- What to try: Ensure your camera/restream is using H.264 video and AAC audio (these are the most compatible). If your camera uses a non-standard audio codec, configure `go2rtc` to transcode the stream to AAC. Try another browser (some browsers have stricter MSE/codec support) and, for iPhone, ensure you're on iOS 17.1 or newer.
|
||||
|
||||
- Possible console messages from the player code:
|
||||
|
||||
- `Safari cannot open MediaSource.`
|
||||
- `Safari reported InvalidStateError.`
|
||||
- `Safari reported decoding errors.`
|
||||
|
||||
- **stalled**
|
||||
|
||||
- What it means: Playback has stalled because the player has fallen too far behind live (extended buffering or no data arriving).
|
||||
- What to try: This is usually indicative of the browser struggling to decode too many high-resolution streams at once. Try selecting a lower-bandwidth stream (substream), reduce the number of live streams open, improve the network connection, or lower the camera resolution. Also check your camera's keyframe (I-frame) interval — shorter intervals make playback start and recover faster. You can also try increasing the timeout value in the UI pane of Frigate's settings.
|
||||
|
||||
- Possible console messages from the player code:
|
||||
|
||||
- `Buffer time (10 seconds) exceeded, browser may not be playing media correctly.`
|
||||
- `Media playback has stalled after <n> seconds due to insufficient buffering or a network interruption.` (the seconds value will vary)
|
||||
|
||||
## Live view FAQ
|
||||
|
||||
1. **Why don't I have audio in my Live view?**
|
||||
@ -277,3 +313,38 @@ Note that disabling a camera through the config file (`enabled: False`) removes
|
||||
7. **My camera streams have lots of visual artifacts / distortion.**
|
||||
|
||||
Some cameras don't include the hardware to support multiple connections to the high resolution stream, and this can cause unexpected behavior. In this case it is recommended to [restream](./restream.md) the high resolution stream so that it can be used for live view and recordings.
|
||||
|
||||
8. **Why does my camera stream switch aspect ratios on the Live dashboard?**
|
||||
|
||||
Your camera may change aspect ratios on the dashboard because Frigate uses different streams for different purposes. With go2rtc and Smart Streaming, Frigate shows a static image from the `detect` stream when no activity is present, and switches to the live stream when motion is detected. The camera image will change size if your streams use different aspect ratios.
|
||||
|
||||
To prevent this, make the `detect` stream match the go2rtc live stream's aspect ratio (resolution does not need to match, just the aspect ratio). You can either adjust the camera's output resolution or set the `width` and `height` values in your config's `detect` section to a resolution with an aspect ratio that matches.
|
||||
|
||||
Example: Resolutions from two streams
|
||||
|
||||
- Mismatched (may cause aspect ratio switching on the dashboard):
|
||||
|
||||
- Live/go2rtc stream: 1920x1080 (16:9)
|
||||
- Detect stream: 640x352 (~1.82:1, not 16:9)
|
||||
|
||||
- Matched (prevents switching):
|
||||
- Live/go2rtc stream: 1920x1080 (16:9)
|
||||
- Detect stream: 640x360 (16:9)
|
||||
|
||||
You can update the detect settings in your camera config to match the aspect ratio of your go2rtc live stream. For example:
|
||||
|
||||
```yaml
|
||||
cameras:
|
||||
front_door:
|
||||
detect:
|
||||
width: 640
|
||||
height: 360 # set this to 360 instead of 352
|
||||
ffmpeg:
|
||||
inputs:
|
||||
- path: rtsp://127.0.0.1:8554/front_door # main stream 1920x1080
|
||||
roles:
|
||||
- record
|
||||
- path: rtsp://127.0.0.1:8554/front_door_sub # sub stream 640x352
|
||||
roles:
|
||||
- detect
|
||||
```
|
||||
|
||||
@ -3,6 +3,8 @@ id: object_detectors
|
||||
title: Object Detectors
|
||||
---
|
||||
|
||||
import CommunityBadge from '@site/src/components/CommunityBadge';
|
||||
|
||||
# Supported Hardware
|
||||
|
||||
:::info
|
||||
@ -13,8 +15,8 @@ Frigate supports multiple different detectors that work on different types of ha
|
||||
|
||||
- [Coral EdgeTPU](#edge-tpu-detector): The Google Coral EdgeTPU is available in USB and m.2 format allowing for a wide range of compatibility with devices.
|
||||
- [Hailo](#hailo-8): The Hailo8 and Hailo8L AI Acceleration module is available in m.2 format with a HAT for RPi devices, offering a wide range of compatibility with devices.
|
||||
- [MemryX](#memryx-mx3): The MX3 Acceleration module is available in m.2 format, offering broad compatibility across various platforms.
|
||||
- [DeGirum](#degirum): Service for using hardware devices in the cloud or locally. Hardware and models provided on the cloud on [their website](https://hub.degirum.com).
|
||||
- <CommunityBadge /> [MemryX](#memryx-mx3): The MX3 Acceleration module is available in m.2 format, offering broad compatibility across various platforms.
|
||||
- <CommunityBadge /> [DeGirum](#degirum): Service for using hardware devices in the cloud or locally. Hardware and models provided on the cloud on [their website](https://hub.degirum.com).
|
||||
|
||||
**AMD**
|
||||
|
||||
@ -34,16 +36,16 @@ Frigate supports multiple different detectors that work on different types of ha
|
||||
|
||||
- [ONNX](#onnx): TensorRT will automatically be detected and used as a detector in the `-tensorrt` Frigate image when a supported ONNX model is configured.
|
||||
|
||||
**Nvidia Jetson**
|
||||
**Nvidia Jetson** <CommunityBadge />
|
||||
|
||||
- [TensortRT](#nvidia-tensorrt-detector): TensorRT can run on Jetson devices, using one of many default models.
|
||||
- [ONNX](#onnx): TensorRT will automatically be detected and used as a detector in the `-tensorrt-jp6` Frigate image when a supported ONNX model is configured.
|
||||
|
||||
**Rockchip**
|
||||
**Rockchip** <CommunityBadge />
|
||||
|
||||
- [RKNN](#rockchip-platform): RKNN models can run on Rockchip devices with included NPUs.
|
||||
|
||||
**Synaptics**
|
||||
**Synaptics** <CommunityBadge />
|
||||
|
||||
- [Synaptics](#synaptics): synap models can run on Synaptics devices(e.g astra machina) with included NPUs.
|
||||
|
||||
@ -988,7 +990,7 @@ model:
|
||||
# Optional: The model is normally fetched through the runtime, so 'path' can be omitted unless you want to use a custom or local model.
|
||||
# path: /config/yolox.zip
|
||||
# The .zip file must contain:
|
||||
# ├── yolox.dfp (a file ending with .dfp)
|
||||
# ├── yolox.dfp (a file ending with .dfp)
|
||||
```
|
||||
|
||||
#### SSDLite MobileNet v2
|
||||
|
||||
@ -246,7 +246,7 @@ birdseye:
|
||||
# Optional: ffmpeg configuration
|
||||
# More information about presets at https://docs.frigate.video/configuration/ffmpeg_presets
|
||||
ffmpeg:
|
||||
# Optional: ffmpeg binry path (default: shown below)
|
||||
# Optional: ffmpeg binary path (default: shown below)
|
||||
# can also be set to `7.0` or `5.0` to specify one of the included versions
|
||||
# or can be set to any path that holds `bin/ffmpeg` & `bin/ffprobe`
|
||||
path: "default"
|
||||
|
||||
@ -3,6 +3,8 @@ id: hardware
|
||||
title: Recommended hardware
|
||||
---
|
||||
|
||||
import CommunityBadge from '@site/src/components/CommunityBadge';
|
||||
|
||||
## Cameras
|
||||
|
||||
Cameras that output H.264 video and AAC audio will offer the most compatibility with all features of Frigate and Home Assistant. It is also helpful if your camera supports multiple substreams to allow different resolutions to be used for detection, streaming, and recordings without re-encoding.
|
||||
@ -59,7 +61,7 @@ Frigate supports multiple different detectors that work on different types of ha
|
||||
|
||||
- [Supports primarily ssdlite and mobilenet model architectures](../../configuration/object_detectors#edge-tpu-detector)
|
||||
|
||||
- [MemryX](#memryx-mx3): The MX3 M.2 accelerator module is available in m.2 format allowing for a wide range of compatibility with devices.
|
||||
- <CommunityBadge /> [MemryX](#memryx-mx3): The MX3 M.2 accelerator module is available in m.2 format allowing for a wide range of compatibility with devices.
|
||||
- [Supports many model architectures](../../configuration/object_detectors#memryx-mx3)
|
||||
- Runs best with tiny, small, or medium-size models
|
||||
|
||||
@ -84,32 +86,26 @@ Frigate supports multiple different detectors that work on different types of ha
|
||||
|
||||
**Nvidia**
|
||||
|
||||
- [TensortRT](#tensorrt---nvidia-gpu): TensorRT can run on Nvidia GPUs and Jetson devices.
|
||||
- [TensortRT](#tensorrt---nvidia-gpu): TensorRT can run on Nvidia GPUs to provide efficient object detection.
|
||||
|
||||
- [Supports majority of model architectures via ONNX](../../configuration/object_detectors#onnx-supported-models)
|
||||
- Runs well with any size models including large
|
||||
|
||||
**Rockchip**
|
||||
- <CommunityBadge /> [Jetson](#nvidia-jetson): Jetson devices are supported via the TensorRT or ONNX detectors when running Jetpack 6.
|
||||
|
||||
**Rockchip** <CommunityBadge />
|
||||
|
||||
- [RKNN](#rockchip-platform): RKNN models can run on Rockchip devices with included NPUs to provide efficient object detection.
|
||||
- [Supports limited model architectures](../../configuration/object_detectors#choosing-a-model)
|
||||
- Runs best with tiny or small size models
|
||||
- Runs efficiently on low power hardware
|
||||
|
||||
**Synaptics**
|
||||
**Synaptics** <CommunityBadge />
|
||||
|
||||
- [Synaptics](#synaptics): synap models can run on Synaptics devices(e.g astra machina) with included NPUs to provide efficient object detection.
|
||||
|
||||
:::
|
||||
|
||||
### Synaptics
|
||||
|
||||
- **Synaptics** Default model is **mobilenet**
|
||||
|
||||
| Name | Synaptics SL1680 Inference Time |
|
||||
| ---------------- | ------------------------------- |
|
||||
| ssd mobilenet | ~ 25 ms |
|
||||
| yolov5m | ~ 118 ms |
|
||||
|
||||
### Hailo-8
|
||||
|
||||
Frigate supports both the Hailo-8 and Hailo-8L AI Acceleration Modules on compatible hardware platforms—including the Raspberry Pi 5 with the PCIe hat from the AI kit. The Hailo detector integration in Frigate automatically identifies your hardware type and selects the appropriate default model when a custom model isn’t provided.
|
||||
@ -261,7 +257,7 @@ Inference speeds may vary depending on the host platform. The above data was mea
|
||||
|
||||
### Nvidia Jetson
|
||||
|
||||
Frigate supports all Jetson boards, from the inexpensive Jetson Nano to the powerful Jetson Orin AGX. It will [make use of the Jetson's hardware media engine](/configuration/hardware_acceleration_video#nvidia-jetson-orin-agx-orin-nx-orin-nano-xavier-agx-xavier-nx-tx2-tx1-nano) when configured with the [appropriate presets](/configuration/ffmpeg_presets#hwaccel-presets), and will make use of the Jetson's GPU and DLA for object detection when configured with the [TensorRT detector](/configuration/object_detectors#nvidia-tensorrt-detector).
|
||||
Jetson devices are supported via the TensorRT or ONNX detectors when running Jetpack 6. It will [make use of the Jetson's hardware media engine](/configuration/hardware_acceleration_video#nvidia-jetson-orin-agx-orin-nx-orin-nano-xavier-agx-xavier-nx-tx2-tx1-nano) when configured with the [appropriate presets](/configuration/ffmpeg_presets#hwaccel-presets), and will make use of the Jetson's GPU and DLA for object detection when configured with the [TensorRT detector](/configuration/object_detectors#nvidia-tensorrt-detector).
|
||||
|
||||
Inference speed will vary depending on the YOLO model, jetson platform and jetson nvpmodel (GPU/DLA/EMC clock speed). It is typically 20-40 ms for most models. The DLA is more efficient than the GPU, but not faster, so using the DLA will reduce power consumption but will slightly increase inference time.
|
||||
|
||||
@ -282,6 +278,15 @@ Frigate supports hardware video processing on all Rockchip boards. However, hard
|
||||
|
||||
The inference time of a rk3588 with all 3 cores enabled is typically 25-30 ms for yolo-nas s.
|
||||
|
||||
### Synaptics
|
||||
|
||||
- **Synaptics** Default model is **mobilenet**
|
||||
|
||||
| Name | Synaptics SL1680 Inference Time |
|
||||
| ------------- | ------------------------------- |
|
||||
| ssd mobilenet | ~ 25 ms |
|
||||
| yolov5m | ~ 118 ms |
|
||||
|
||||
## What does Frigate use the CPU for and what does it use a detector for? (ELI5 Version)
|
||||
|
||||
This is taken from a [user question on reddit](https://www.reddit.com/r/homeassistant/comments/q8mgau/comment/hgqbxh5/?utm_source=share&utm_medium=web2x&context=3). Modified slightly for clarity.
|
||||
|
||||
@ -159,11 +159,44 @@ Message published for updates to tracked object metadata, for example:
|
||||
}
|
||||
```
|
||||
|
||||
#### Object Classification Update
|
||||
|
||||
Message published when [object classification](/configuration/custom_classification/object_classification) reaches consensus on a classification result.
|
||||
|
||||
**Sub label type:**
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "classification",
|
||||
"id": "1607123955.475377-mxklsc",
|
||||
"camera": "front_door_cam",
|
||||
"timestamp": 1607123958.748393,
|
||||
"model": "person_classifier",
|
||||
"sub_label": "delivery_person",
|
||||
"score": 0.87
|
||||
}
|
||||
```
|
||||
|
||||
**Attribute type:**
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "classification",
|
||||
"id": "1607123955.475377-mxklsc",
|
||||
"camera": "front_door_cam",
|
||||
"timestamp": 1607123958.748393,
|
||||
"model": "helmet_detector",
|
||||
"attribute": "yes",
|
||||
"score": 0.92
|
||||
}
|
||||
```
|
||||
|
||||
### `frigate/reviews`
|
||||
|
||||
Message published for each changed review item. The first message is published when the `detection` or `alert` is initiated.
|
||||
Message published for each changed review item. The first message is published when the `detection` or `alert` is initiated.
|
||||
|
||||
An `update` with the same ID will be published when:
|
||||
|
||||
- The severity changes from `detection` to `alert`
|
||||
- Additional objects are detected
|
||||
- An object is recognized via face, lpr, etc.
|
||||
@ -308,6 +341,11 @@ Publishes transcribed text for audio detected on this camera.
|
||||
|
||||
**NOTE:** Requires audio detection and transcription to be enabled
|
||||
|
||||
### `frigate/<camera_name>/classification/<model_name>`
|
||||
|
||||
Publishes the current state detected by a state classification model for the camera. The topic name includes the model name as configured in your classification settings.
|
||||
The published value is the detected state class name (e.g., `open`, `closed`, `on`, `off`). The state is only published when it changes, helping to reduce unnecessary MQTT traffic.
|
||||
|
||||
### `frigate/<camera_name>/enabled/set`
|
||||
|
||||
Topic to turn Frigate's processing of a camera on and off. Expected values are `ON` and `OFF`.
|
||||
|
||||
@ -10,7 +10,7 @@ const config: Config = {
|
||||
baseUrl: "/",
|
||||
onBrokenLinks: "throw",
|
||||
onBrokenMarkdownLinks: "warn",
|
||||
favicon: "img/favicon.ico",
|
||||
favicon: "img/branding/favicon.ico",
|
||||
organizationName: "blakeblackshear",
|
||||
projectName: "frigate",
|
||||
themes: [
|
||||
@ -116,8 +116,8 @@ const config: Config = {
|
||||
title: "Frigate",
|
||||
logo: {
|
||||
alt: "Frigate",
|
||||
src: "img/logo.svg",
|
||||
srcDark: "img/logo-dark.svg",
|
||||
src: "img/branding/logo.svg",
|
||||
srcDark: "img/branding/logo-dark.svg",
|
||||
},
|
||||
items: [
|
||||
{
|
||||
@ -170,7 +170,7 @@ const config: Config = {
|
||||
],
|
||||
},
|
||||
],
|
||||
copyright: `Copyright © ${new Date().getFullYear()} Blake Blackshear`,
|
||||
copyright: `Copyright © ${new Date().getFullYear()} Frigate LLC`,
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
|
||||
23
docs/src/components/CommunityBadge/index.jsx
Normal file
@ -0,0 +1,23 @@
|
||||
import React from "react";
|
||||
|
||||
export default function CommunityBadge() {
|
||||
return (
|
||||
<span
|
||||
title="This detector is maintained by community members who provide code, maintenance, and support. See the contributing boards documentation for more information."
|
||||
style={{
|
||||
display: "inline-block",
|
||||
backgroundColor: "#f1f3f5",
|
||||
color: "#24292f",
|
||||
fontSize: "11px",
|
||||
fontWeight: 600,
|
||||
padding: "2px 6px",
|
||||
borderRadius: "3px",
|
||||
border: "1px solid #d1d9e0",
|
||||
marginLeft: "4px",
|
||||
cursor: "help",
|
||||
}}
|
||||
>
|
||||
Community Supported
|
||||
</span>
|
||||
);
|
||||
}
|
||||
30
docs/static/img/branding/LICENSE.md
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
# COPYRIGHT AND TRADEMARK NOTICE
|
||||
|
||||
The images, logos, and icons contained in this directory (the "Brand Assets") are
|
||||
proprietary to Frigate LLC and are NOT covered by the MIT License governing the
|
||||
rest of this repository.
|
||||
|
||||
1. TRADEMARK STATUS
|
||||
The "Frigate" name and the accompanying logo are common law trademarks™ of
|
||||
Frigate LLC. Frigate LLC reserves all rights to these marks.
|
||||
|
||||
2. LIMITED PERMISSION FOR USE
|
||||
Permission is hereby granted to display these Brand Assets strictly for the
|
||||
following purposes:
|
||||
a. To execute the software interface on a local machine.
|
||||
b. To identify the software in documentation or reviews (nominative use).
|
||||
|
||||
3. RESTRICTIONS
|
||||
You may NOT:
|
||||
a. Use these Brand Assets to represent a derivative work (fork) as an official
|
||||
product of Frigate LLC.
|
||||
b. Use these Brand Assets in a way that implies endorsement, sponsorship, or
|
||||
commercial affiliation with Frigate LLC.
|
||||
c. Modify or alter the Brand Assets.
|
||||
|
||||
If you fork this repository with the intent to distribute a modified or competing
|
||||
version of the software, you must replace these Brand Assets with your own
|
||||
original content.
|
||||
|
||||
ALL RIGHTS RESERVED.
|
||||
Copyright (c) 2025 Frigate LLC.
|
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 936 B After Width: | Height: | Size: 936 B |
|
Before Width: | Height: | Size: 933 B After Width: | Height: | Size: 933 B |
@ -1,6 +1,7 @@
|
||||
"""Real time processor that works with classification tflite models."""
|
||||
|
||||
import datetime
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from typing import Any
|
||||
@ -21,6 +22,7 @@ from frigate.config.classification import (
|
||||
)
|
||||
from frigate.const import CLIPS_DIR, MODEL_CACHE_DIR
|
||||
from frigate.log import redirect_output_to_logger
|
||||
from frigate.types import TrackedObjectUpdateTypesEnum
|
||||
from frigate.util.builtin import EventsPerSecond, InferenceSpeed, load_labels
|
||||
from frigate.util.object import box_overlaps, calculate_region
|
||||
|
||||
@ -284,6 +286,7 @@ class CustomObjectClassificationProcessor(RealTimeProcessorApi):
|
||||
config: FrigateConfig,
|
||||
model_config: CustomClassificationConfig,
|
||||
sub_label_publisher: EventMetadataPublisher,
|
||||
requestor: InterProcessRequestor,
|
||||
metrics: DataProcessorMetrics,
|
||||
):
|
||||
super().__init__(config, metrics)
|
||||
@ -292,6 +295,7 @@ class CustomObjectClassificationProcessor(RealTimeProcessorApi):
|
||||
self.train_dir = os.path.join(CLIPS_DIR, self.model_config.name, "train")
|
||||
self.interpreter: Interpreter | None = None
|
||||
self.sub_label_publisher = sub_label_publisher
|
||||
self.requestor = requestor
|
||||
self.tensor_input_details: dict[str, Any] | None = None
|
||||
self.tensor_output_details: dict[str, Any] | None = None
|
||||
self.classification_history: dict[str, list[tuple[str, float, float]]] = {}
|
||||
@ -486,6 +490,8 @@ class CustomObjectClassificationProcessor(RealTimeProcessorApi):
|
||||
)
|
||||
|
||||
if consensus_label is not None:
|
||||
camera = obj_data["camera"]
|
||||
|
||||
if (
|
||||
self.model_config.object_config.classification_type
|
||||
== ObjectClassificationType.sub_label
|
||||
@ -494,6 +500,20 @@ class CustomObjectClassificationProcessor(RealTimeProcessorApi):
|
||||
(object_id, consensus_label, consensus_score),
|
||||
EventMetadataTypeEnum.sub_label,
|
||||
)
|
||||
self.requestor.send_data(
|
||||
"tracked_object_update",
|
||||
json.dumps(
|
||||
{
|
||||
"type": TrackedObjectUpdateTypesEnum.classification,
|
||||
"id": object_id,
|
||||
"camera": camera,
|
||||
"timestamp": now,
|
||||
"model": self.model_config.name,
|
||||
"sub_label": consensus_label,
|
||||
"score": consensus_score,
|
||||
}
|
||||
),
|
||||
)
|
||||
elif (
|
||||
self.model_config.object_config.classification_type
|
||||
== ObjectClassificationType.attribute
|
||||
@ -507,6 +527,20 @@ class CustomObjectClassificationProcessor(RealTimeProcessorApi):
|
||||
),
|
||||
EventMetadataTypeEnum.attribute.value,
|
||||
)
|
||||
self.requestor.send_data(
|
||||
"tracked_object_update",
|
||||
json.dumps(
|
||||
{
|
||||
"type": TrackedObjectUpdateTypesEnum.classification,
|
||||
"id": object_id,
|
||||
"camera": camera,
|
||||
"timestamp": now,
|
||||
"model": self.model_config.name,
|
||||
"attribute": consensus_label,
|
||||
"score": consensus_score,
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
def handle_request(self, topic, request_data):
|
||||
if topic == EmbeddingsRequestEnum.reload_classification_model.value:
|
||||
|
||||
@ -195,6 +195,7 @@ class EmbeddingMaintainer(threading.Thread):
|
||||
self.config,
|
||||
model_config,
|
||||
self.event_metadata_publisher,
|
||||
self.requestor,
|
||||
self.metrics,
|
||||
)
|
||||
)
|
||||
@ -339,6 +340,7 @@ class EmbeddingMaintainer(threading.Thread):
|
||||
self.config,
|
||||
model_config,
|
||||
self.event_metadata_publisher,
|
||||
self.requestor,
|
||||
self.metrics,
|
||||
)
|
||||
|
||||
|
||||
@ -30,3 +30,4 @@ class TrackedObjectUpdateTypesEnum(str, Enum):
|
||||
description = "description"
|
||||
face = "face"
|
||||
lpr = "lpr"
|
||||
classification = "classification"
|
||||
|
||||
@ -130,8 +130,13 @@ def get_soc_type() -> Optional[str]:
|
||||
"""Get the SoC type from device tree."""
|
||||
try:
|
||||
with open("/proc/device-tree/compatible") as file:
|
||||
soc = file.read().split(",")[-1].strip("\x00")
|
||||
return soc
|
||||
content = file.read()
|
||||
|
||||
# Check for Jetson devices
|
||||
if "nvidia" in content:
|
||||
return None
|
||||
|
||||
return content.split(",")[-1].strip("\x00")
|
||||
except FileNotFoundError:
|
||||
logger.debug("Could not determine SoC type from device tree")
|
||||
return None
|
||||
|
||||
33
web/images/branding/LICENSE
Normal file
@ -0,0 +1,33 @@
|
||||
# COPYRIGHT AND TRADEMARK NOTICE
|
||||
|
||||
The images, logos, and icons contained in this directory (the "Brand Assets") are
|
||||
proprietary to Frigate LLC and are NOT covered by the MIT License governing the
|
||||
rest of this repository.
|
||||
|
||||
1. TRADEMARK STATUS
|
||||
The "Frigate" name and the accompanying logo are common law trademarks™ of
|
||||
Frigate LLC. Frigate LLC reserves all rights to these marks.
|
||||
|
||||
2. LIMITED PERMISSION FOR USE
|
||||
Permission is hereby granted to display these Brand Assets strictly for the
|
||||
following purposes:
|
||||
a. To execute the software interface on a local machine.
|
||||
b. To identify the software in documentation or reviews (nominative use).
|
||||
|
||||
3. RESTRICTIONS
|
||||
You may NOT:
|
||||
a. Use these Brand Assets to represent a derivative work (fork) as an official
|
||||
product of Frigate LLC.
|
||||
b. Use these Brand Assets in a way that implies endorsement, sponsorship, or
|
||||
commercial affiliation with Frigate LLC.
|
||||
c. Modify or alter the Brand Assets.
|
||||
|
||||
If you fork this repository with the intent to distribute a modified or competing
|
||||
version of the software, you must replace these Brand Assets with your own
|
||||
original content.
|
||||
|
||||
For full usage guidelines, strictly see the TRADEMARK.md file in the
|
||||
repository root.
|
||||
|
||||
ALL RIGHTS RESERVED.
|
||||
Copyright (c) 2025 Frigate LLC.
|
||||
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 558 B After Width: | Height: | Size: 558 B |
|
Before Width: | Height: | Size: 800 B After Width: | Height: | Size: 800 B |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
@ -2,29 +2,29 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/images/favicon.ico" />
|
||||
<link rel="icon" href="/images/branding/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Frigate</title>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="180x180"
|
||||
href="/images/apple-touch-icon.png"
|
||||
href="/images/branding/apple-touch-icon.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="32x32"
|
||||
href="/images/favicon-32x32.png"
|
||||
href="/images/branding/favicon-32x32.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="16x16"
|
||||
href="/images/favicon-16x16.png"
|
||||
href="/images/branding/favicon-16x16.png"
|
||||
/>
|
||||
<link rel="icon" type="image/svg+xml" href="/images/favicon.svg" />
|
||||
<link rel="icon" type="image/svg+xml" href="/images/branding/favicon.svg" />
|
||||
<link rel="manifest" href="/site.webmanifest" crossorigin="use-credentials" />
|
||||
<link rel="mask-icon" href="/images/favicon.svg" color="#3b82f7" />
|
||||
<link rel="mask-icon" href="/images/branding/favicon.svg" color="#3b82f7" />
|
||||
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)" />
|
||||
<meta name="theme-color" content="#000000" media="(prefers-color-scheme: dark)" />
|
||||
</head>
|
||||
|
||||
@ -2,29 +2,29 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/images/favicon.ico" />
|
||||
<link rel="icon" href="/images/branding/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Frigate</title>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="180x180"
|
||||
href="/images/apple-touch-icon.png"
|
||||
href="/images/branding/apple-touch-icon.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="32x32"
|
||||
href="/images/favicon-32x32.png"
|
||||
href="/images/branding/favicon-32x32.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="16x16"
|
||||
href="/images/favicon-16x16.png"
|
||||
href="/images/branding/favicon-16x16.png"
|
||||
/>
|
||||
<link rel="icon" type="image/svg+xml" href="/images/favicon.svg" />
|
||||
<link rel="icon" type="image/svg+xml" href="/images/branding/favicon.svg" />
|
||||
<link rel="manifest" href="/site.webmanifest" crossorigin="use-credentials" />
|
||||
<link rel="mask-icon" href="/images/favicon.svg" color="#3b82f7" />
|
||||
<link rel="mask-icon" href="/images/branding/favicon.svg" color="#3b82f7" />
|
||||
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)" />
|
||||
<meta name="theme-color" content="#000000" media="(prefers-color-scheme: dark)" />
|
||||
</head>
|
||||
|
||||
@ -76,7 +76,12 @@
|
||||
}
|
||||
},
|
||||
"npuUsage": "Ús de NPU",
|
||||
"npuMemory": "Memòria de NPU"
|
||||
"npuMemory": "Memòria de NPU",
|
||||
"intelGpuWarning": {
|
||||
"title": "Avís d'estadístiques de la GPU d'Intel",
|
||||
"message": "Estadístiques de GPU no disponibles",
|
||||
"description": "Aquest és un error conegut en les eines d'informació de les estadístiques de GPU d'Intel (intel.gpu.top) on es trencarà i retornarà repetidament un ús de GPU del 0% fins i tot en els casos en què l'acceleració del maquinari i la detecció d'objectes s'executen correctament a la (i)GPU. Això no és un error de fragata. Podeu reiniciar l'amfitrió per a corregir temporalment el problema i confirmar que la GPU funciona correctament. Això no afecta el rendiment."
|
||||
}
|
||||
},
|
||||
"otherProcesses": {
|
||||
"title": "Altres processos",
|
||||
|
||||
@ -1,30 +1,31 @@
|
||||
{
|
||||
"documentTitle": "Klasifikační modely",
|
||||
"button": {
|
||||
"deleteClassificationAttempts": "Odstranit Klasifikační obrazy",
|
||||
"renameCategory": "Přejmenovat třídu",
|
||||
"deleteCategory": "Smazat třídu",
|
||||
"deleteImages": "Smazat obraz",
|
||||
"trainModel": "Trénovací model",
|
||||
"addClassification": "Přidat klasifikaci",
|
||||
"deleteModels": "Smazat modely",
|
||||
"editModel": "Upravit model"
|
||||
"deleteClassificationAttempts": "Odstrániť Klasifikačné obrazy",
|
||||
"renameCategory": "Premenovať triedu",
|
||||
"deleteCategory": "Zmazať triedu",
|
||||
"deleteImages": "Zmazať obrázok",
|
||||
"trainModel": "Trenovací model",
|
||||
"addClassification": "Pridať klasifikáciu",
|
||||
"deleteModels": "Zmazať modeli",
|
||||
"editModel": "Upraviť model"
|
||||
},
|
||||
"details": {
|
||||
"scoreInfo": "Skóre představuje průměrnou jistotu klasifikace napříč všemi detekcemi tohoto objektu."
|
||||
"scoreInfo": "Skóre predstavuje priemernú istotu klasifikácie naprieč detekciami tohoto objektu."
|
||||
},
|
||||
"tooltip": {
|
||||
"trainingInProgress": "Model se právě trénuje",
|
||||
"noNewImages": "Žádné nové obrázky k trénování. Nejdříve klasifikujte více obrázků v datasetu.",
|
||||
"noChanges": "Od posledního trénování nedošlo k žádným změnám v datasetu.",
|
||||
"modelNotReady": "Model není připraven k trénování"
|
||||
"trainingInProgress": "Model se práve trénuje",
|
||||
"noNewImages": "Žiadne nové obrázky na trénovanie. Najskôr klasifikujte viac obrazkov v datasete.",
|
||||
"noChanges": "Od posledného treningu nedošlo k žiadnym zmenám v datasete.",
|
||||
"modelNotReady": "Model nieje pripravený na trénovanie."
|
||||
},
|
||||
"toast": {
|
||||
"success": {
|
||||
"deletedImage": "Smazané obrázky",
|
||||
"deletedModel_one": "Úspěšně odstraněn {{count}} model",
|
||||
"deletedModel_few": "Úspěšně odstraněny {{count}} modely",
|
||||
"deletedModel_other": "Úspěšně odstraněno {{count}} modelů"
|
||||
"deletedImage": "Zmazať obrazky",
|
||||
"deletedModel_one": "Úspešne odstranený {{count}} model",
|
||||
"deletedModel_few": "Úspešne odstranené {{count}} modely",
|
||||
"deletedModel_other": "Úspěšne ostranených {{count}} modelov",
|
||||
"deletedCategory": "Zmazať triedu"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,7 +103,7 @@
|
||||
"regenerate": "A new description has been requested from {{provider}}. Depending on the speed of your provider, the new description may take some time to regenerate.",
|
||||
"updatedSublabel": "Successfully updated sub label.",
|
||||
"updatedLPR": "Successfully updated license plate.",
|
||||
"audioTranscription": "Successfully requested audio transcription."
|
||||
"audioTranscription": "Successfully requested audio transcription. Depending on the speed of your Frigate server, the transcription may take some time to complete."
|
||||
},
|
||||
"error": {
|
||||
"regenerate": "Failed to call {{provider}} for a new description: {{errorMessage}}",
|
||||
|
||||
@ -76,7 +76,12 @@
|
||||
}
|
||||
},
|
||||
"npuUsage": "Utilisation NPU",
|
||||
"npuMemory": "Mémoire NPU"
|
||||
"npuMemory": "Mémoire NPU",
|
||||
"intelGpuWarning": {
|
||||
"title": "Avertissement relatif aux statistiques du GPU Intel",
|
||||
"message": "Statistiques du GPU non disponibles",
|
||||
"description": "Il s'agit d'un bug connu de l'outil de statistiques GPU d'Intel (intel_gpu_top) : il peut afficher à tort une utilisation de 0 %, même lorsque l'accélération matérielle et la détection d'objets fonctionnent correctement sur l'iGPU. Ce problème ne vient pas de Frigate. Vous pouvez redémarrer l'hôte pour rétablir temporairement l'affichage et confirmer le fonctionnement du GPU. Les performances ne sont pas affectées."
|
||||
}
|
||||
},
|
||||
"otherProcesses": {
|
||||
"title": "Autres processus",
|
||||
|
||||
@ -174,7 +174,11 @@
|
||||
"noCameras": {
|
||||
"buttonText": "Aggiungi telecamera",
|
||||
"title": "Nessuna telecamera configurata",
|
||||
"description": "Per iniziare, collega una telecamera a Frigate."
|
||||
"description": "Per iniziare, collega una telecamera a Frigate.",
|
||||
"restricted": {
|
||||
"title": "Nessuna telecamera disponibile",
|
||||
"description": "Non hai l'autorizzazione per visualizzare alcuna telecamera in questo gruppo."
|
||||
}
|
||||
},
|
||||
"snapshot": {
|
||||
"takeSnapshot": "Scarica l'istantanea attuale",
|
||||
|
||||
@ -65,7 +65,12 @@
|
||||
"gpuUsage": "Utilizzo GPU",
|
||||
"gpuMemory": "Memoria GPU",
|
||||
"npuUsage": "Utilizzo NPU",
|
||||
"npuMemory": "Memoria NPU"
|
||||
"npuMemory": "Memoria NPU",
|
||||
"intelGpuWarning": {
|
||||
"title": "Avviso statistiche GPU Intel",
|
||||
"message": "Statistiche GPU non disponibili",
|
||||
"description": "Si tratta di un problema noto negli strumenti di reportistica delle statistiche GPU di Intel (intel_gpu_top), che si interrompe e restituisce ripetutamente un utilizzo della GPU pari a 0% anche nei casi in cui l'accelerazione hardware e il rilevamento degli oggetti funzionano correttamente sulla (i)GPU. Non si tratta di un problema di Frigate. È possibile riavviare il sistema per risolvere temporaneamente il problema e verificare che la GPU funzioni correttamente. Ciò non influisce sulle prestazioni."
|
||||
}
|
||||
},
|
||||
"detector": {
|
||||
"inferenceSpeed": "Velocità inferenza rilevatore",
|
||||
@ -94,10 +99,17 @@
|
||||
"yolov9_plate_detection_speed": "Velocità di rilevamento della targa con YOLOv9",
|
||||
"yolov9_plate_detection": "Rilevamento della targa con YOLOv9",
|
||||
"image_embedding": "Incorporamento di immagini",
|
||||
"text_embedding": "Incorporamento di testo"
|
||||
"text_embedding": "Incorporamento di testo",
|
||||
"review_description": "Descrizione della revisione",
|
||||
"review_description_speed": "Velocità della descrizione di revisione",
|
||||
"review_description_events_per_second": "Descrizione della revisione",
|
||||
"object_description": "Descrizione dell'oggetto",
|
||||
"object_description_speed": "Velocità della descrizione dell'oggetto",
|
||||
"object_description_events_per_second": "Descrizione dell'oggetto"
|
||||
},
|
||||
"title": "Miglioramenti",
|
||||
"infPerSecond": "Inferenze al secondo"
|
||||
"infPerSecond": "Inferenze al secondo",
|
||||
"averageInf": "Tempo medio di inferenza"
|
||||
},
|
||||
"cameras": {
|
||||
"info": {
|
||||
|
||||
@ -180,6 +180,10 @@
|
||||
"noCameras": {
|
||||
"title": "Ingen kameraer konfigurert",
|
||||
"description": "Kom i gang ved å koble et kamera til Frigate.",
|
||||
"buttonText": "Legg til kamera"
|
||||
"buttonText": "Legg til kamera",
|
||||
"restricted": {
|
||||
"title": "Ingen kameraer tilgjengelig",
|
||||
"description": "Du har ikke tilgang for å se noen kameraer i denne gruppen."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,7 +74,12 @@
|
||||
"title": "Maskinvareinformasjon",
|
||||
"gpuUsage": "GPU-belastning",
|
||||
"npuMemory": "NPU minne",
|
||||
"npuUsage": "NPU belastning"
|
||||
"npuUsage": "NPU belastning",
|
||||
"intelGpuWarning": {
|
||||
"title": "Advarsel om Intel GPU-statistikk",
|
||||
"message": "GPU statistikk ikke tilgjengelig",
|
||||
"description": "Dette er en kjent feil i Intels verktøy for rapportering av GPU-statistikk (intel_gpu_top), der verktøyet slutter å fungere og gjentatte ganger viser 0 % GPU-bruk, selv om maskinvareakselerasjon og objektdeteksjon kjører korrekt på (i)GPU-en. Dette er ikke en feil i Frigate. Du kan starte verten på nytt for å løse problemet midlertidig, og for å bekrefte at GPU-en fungerer som den skal. Dette påvirker ikke ytelsen."
|
||||
}
|
||||
},
|
||||
"otherProcesses": {
|
||||
"title": "Andre prosesser",
|
||||
@ -165,10 +170,17 @@
|
||||
"text_embedding": "Tekst-vektorrepresentasjoner",
|
||||
"plate_recognition": "Kjennemerke gjenkjenning",
|
||||
"yolov9_plate_detection_speed": "Hastighet for YOLOv9 kjennemerkedeteksjon",
|
||||
"yolov9_plate_detection": "YOLOv9 kjennemerkedeteksjon"
|
||||
"yolov9_plate_detection": "YOLOv9 kjennemerkedeteksjon",
|
||||
"object_description": "Objektbeskrivelse",
|
||||
"object_description_speed": "Objektbeskrivelse hastighet",
|
||||
"object_description_events_per_second": "Objektbeskrivelse",
|
||||
"review_description": "Inspeksjonsbeskrivelse",
|
||||
"review_description_events_per_second": "Inspeksjonsbeskrivelse",
|
||||
"review_description_speed": "Inspeksjonsbeskrivelse hastighet"
|
||||
},
|
||||
"title": "Utvidelser",
|
||||
"infPerSecond": "Inferenser per sekund"
|
||||
"infPerSecond": "Inferenser per sekund",
|
||||
"averageInf": "Gjennomsnittlig inferenstid"
|
||||
},
|
||||
"title": "System",
|
||||
"metrics": "Systemmålinger",
|
||||
|
||||
@ -75,7 +75,12 @@
|
||||
"gpuEncoder": "GPU Encodeerder",
|
||||
"gpuMemory": "GPU-geheugen",
|
||||
"npuUsage": "NPU-gebruik",
|
||||
"npuMemory": "NPU-geheugen"
|
||||
"npuMemory": "NPU-geheugen",
|
||||
"intelGpuWarning": {
|
||||
"title": "Waarschuwing Intel GPU-statistieken",
|
||||
"message": "GPU-statistieken niet beschikbaar",
|
||||
"description": "Dit is een bekend probleem in de GPU-statistiekentools van Intel (intel_gpu_top). Deze raken defect en geven herhaaldelijk een GPU-gebruik van 0% weer, zelfs wanneer hardware-acceleratie en objectdetectie correct draaien op de (i)GPU. Dit is geen bug in Frigate. Je kunt de host opnieuw opstarten om het tijdelijk op te lossen en te controleren dat de GPU goed werkt. Dit heeft geen invloed op de prestaties."
|
||||
}
|
||||
},
|
||||
"otherProcesses": {
|
||||
"processMemoryUsage": "Process Geheugen Gebruik",
|
||||
|
||||
@ -42,6 +42,11 @@
|
||||
"closeInfo": {
|
||||
"label": "Închide informațiile GPU"
|
||||
}
|
||||
},
|
||||
"intelGpuWarning": {
|
||||
"title": "Avertisment statistici GPU Intel",
|
||||
"message": "Statistici GPU indisponibile",
|
||||
"description": "Aceasta este o eroare cunoscută în instrumentele Intel pentru raportarea statisticilor GPU (intel_gpu_top), unde acestea se blochează și returnează repetat o utilizare GPU de 0%, chiar și în cazurile în care accelerarea hardware și detectarea obiectelor rulează corect pe (i)GPU. Aceasta nu este o eroare Frigate. Poți reporni gazda pentru a remedia temporar problema și pentru a confirma că GPU-ul funcționează corect. Aceasta nu afectează performanța."
|
||||
}
|
||||
},
|
||||
"detector": {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
"camera": "Настройки камеры - Frigate",
|
||||
"masksAndZones": "Маски и Зоны - Frigate",
|
||||
"motionTuner": "Детекции движения - Frigate",
|
||||
"general": "Общие настройки - Frigate",
|
||||
"general": "Настройки интерфейса - Frigate",
|
||||
"frigatePlus": "Настройки Frigate+ - Frigate",
|
||||
"authentication": "Настройки аутентификации - Frigate",
|
||||
"classification": "Настройки распознавания - Frigate",
|
||||
@ -41,7 +41,7 @@
|
||||
"noCamera": "Нет камеры"
|
||||
},
|
||||
"general": {
|
||||
"title": "Общие настройки",
|
||||
"title": "Настройки интерфейса",
|
||||
"liveDashboard": {
|
||||
"title": "Панель мониторинга",
|
||||
"automaticLiveView": {
|
||||
|
||||
@ -78,7 +78,10 @@
|
||||
"formattedTimestampFilename": {
|
||||
"12hour": "MM-dd-yy-h-mm-ss-a",
|
||||
"24hour": "MM-dd-yy-HH-mm-ss"
|
||||
}
|
||||
},
|
||||
"inProgress": "Spracováva sa",
|
||||
"invalidStartTime": "Neplatný čas štartu",
|
||||
"invalidEndTime": "Neplatný čas ukončenia"
|
||||
},
|
||||
"selectItem": "Vyberte {{item}}",
|
||||
"unit": {
|
||||
@ -104,7 +107,9 @@
|
||||
"back": "Choď späť",
|
||||
"hide": "Skryť {{item}}",
|
||||
"show": "Zobraziť {{item}}",
|
||||
"ID": "ID"
|
||||
"ID": "ID",
|
||||
"none": "None",
|
||||
"all": "Všetko"
|
||||
},
|
||||
"button": {
|
||||
"apply": "Použiť",
|
||||
@ -141,7 +146,8 @@
|
||||
"next": "Ďalej",
|
||||
"unsuspended": "Zrušte pozastavenie",
|
||||
"play": "Hrať",
|
||||
"unselect": "Zrušte výber"
|
||||
"unselect": "Zrušte výber",
|
||||
"continue": "Pokračovať"
|
||||
},
|
||||
"menu": {
|
||||
"system": "Systém",
|
||||
|
||||
@ -7,7 +7,8 @@
|
||||
"deleteImages": "Odstrániť obrázky",
|
||||
"trainModel": "Model vlaku",
|
||||
"addClassification": "Pridať klasifikáciu",
|
||||
"deleteModels": "Odstrániť modely"
|
||||
"deleteModels": "Odstrániť modely",
|
||||
"editModel": "Editovať model"
|
||||
},
|
||||
"toast": {
|
||||
"success": {
|
||||
@ -18,19 +19,26 @@
|
||||
"trainingModel": "Úspešne spustený modelový tréning.",
|
||||
"deletedModel_one": "Úspešne zmazané {{count}} model (y)",
|
||||
"deletedModel_few": "",
|
||||
"deletedModel_other": ""
|
||||
"deletedModel_other": "",
|
||||
"updatedModel": "Úspešne zmenená konfigurácia modelu",
|
||||
"renamedCategory": "Úspešne premenovaná trieda na"
|
||||
},
|
||||
"error": {
|
||||
"deleteImageFailed": "Nepodarilo sa odstrániť: {{errorMessage}}",
|
||||
"deleteCategoryFailed": "Nepodarilo sa odstrániť triedu: {{errorMessage}}",
|
||||
"categorizeFailed": "Nepodarilo sa kategorizovať obrázok: {{errorMessage}}",
|
||||
"trainingFailed": "Nepodarilo sa spustiť trénovanie modelu: {{errorMessage}}",
|
||||
"deleteModelFailed": "Nepodarilo sa odstrániť model: {{errorMessage}}"
|
||||
"deleteModelFailed": "Nepodarilo sa odstrániť model: {{errorMessage}}",
|
||||
"trainingFailedToStart": "Neuspešny štart trenovania modelu:",
|
||||
"updateModelFailed": "Chyba pri úprave modelu:",
|
||||
"renameCategoryFailed": "Chyba pri premenovani triedy:"
|
||||
}
|
||||
},
|
||||
"deleteCategory": {
|
||||
"title": "Odstrániť triedu",
|
||||
"desc": "Naozaj chcete odstrániť triedu {{name}}? Týmto sa natrvalo odstránia všetky súvisiace obrázky a bude potrebné pretrénovať model."
|
||||
"desc": "Naozaj chcete odstrániť triedu {{name}}? Týmto sa natrvalo odstránia všetky súvisiace obrázky a bude potrebné pretrénovať model.",
|
||||
"minClassesTitle": "Nemožete zmazať triedu",
|
||||
"minClassesDesc": "Klasifikačný model musí mať aspoň 2 triedy. Pred odstránením tejto triedy pridajte ďalšiu triedu."
|
||||
},
|
||||
"deleteDatasetImages": {
|
||||
"title": "Odstrániť obrázky množiny údajov",
|
||||
@ -148,5 +156,20 @@
|
||||
"menu": {
|
||||
"objects": "Objekty",
|
||||
"states": "Štátov"
|
||||
},
|
||||
"details": {
|
||||
"scoreInfo": "Skóre predstavuje priemernú istotu klasifikácie naprieč detekciami tohoto objektu."
|
||||
},
|
||||
"tooltip": {
|
||||
"trainingInProgress": "Model sa aktuálne trénuje",
|
||||
"noNewImages": "Žiadne nové obrázky na trénovanie. Najskor klasifikuj nové obrazky do datasetu.",
|
||||
"noChanges": "Žiadne zmeny v datasete od posledného tréningu.",
|
||||
"modelNotReady": "Model nie je pripravený na trénovanie."
|
||||
},
|
||||
"edit": {
|
||||
"title": "Nastavenie modelu",
|
||||
"descriptionState": "Upravte triedy pre tento model klasifikácie. Zmeny budú vyžadovať pretrénovanie modelu.",
|
||||
"descriptionObject": "Upravte typ objektu a typ klasifikácie pre tento model klasifikácie.",
|
||||
"stateClassesInfo": "Poznámka: Zmena tried stavov vyžaduje pretrénovanie modelu s aktualizovanými triedami."
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,7 +112,8 @@
|
||||
"snapshot": "snímka",
|
||||
"video": "video",
|
||||
"object_lifecycle": "životný cyklus objektu",
|
||||
"thumbnail": "Náhľad"
|
||||
"thumbnail": "Náhľad",
|
||||
"tracking_details": "Pohybové detaili"
|
||||
},
|
||||
"objectLifecycle": {
|
||||
"title": "Životný cyklus Objektu",
|
||||
@ -228,7 +229,9 @@
|
||||
"success": "Sledovaný objekt úspešne zmazaný.",
|
||||
"error": "Sledovaný objekt sa nepodarilo zmazať: {{errorMessage}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"previousTrackedObject": "Predchádzajúci trackovaný objekt",
|
||||
"nextTrackedObject": "Ďalší trackovaný objekt"
|
||||
},
|
||||
"aiAnalysis": {
|
||||
"title": "Analýza AI"
|
||||
|
||||
@ -172,7 +172,11 @@
|
||||
"noCameras": {
|
||||
"title": "Nie sú konfigurované žiadne kamery",
|
||||
"description": "Začnite tým, že pripojíte kameru do Frigate.",
|
||||
"buttonText": "Pridať kameru"
|
||||
"buttonText": "Pridať kameru",
|
||||
"restricted": {
|
||||
"title": "Žiadne kamery k dispozícii",
|
||||
"description": "Nemáte povolenie na zobrazenie akýchkoľvek kamier v tejto skupine."
|
||||
}
|
||||
},
|
||||
"snapshot": {
|
||||
"takeSnapshot": "Stiahnite si okamžité snímky",
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
"masksAndZones": "Editor masky a zón - Frigate",
|
||||
"motionTuner": "Ladič detekcie pohybu - Frigate",
|
||||
"object": "Ladenie - Frigate",
|
||||
"general": "Všeobecné nastavenia – Frigate",
|
||||
"general": "UI nastavenia – Frigate",
|
||||
"frigatePlus": "Nastavenia Frigate+ – Frigate",
|
||||
"notifications": "Nastavenia upozornení – Frigate",
|
||||
"cameraManagement": "Manažment kamier - Frigate",
|
||||
@ -39,7 +39,7 @@
|
||||
"noCamera": "Žiadna Kamera"
|
||||
},
|
||||
"general": {
|
||||
"title": "Hlavné nastavenia",
|
||||
"title": "UI nastavenia",
|
||||
"liveDashboard": {
|
||||
"title": "Živý Dashboard",
|
||||
"automaticLiveView": {
|
||||
@ -53,6 +53,10 @@
|
||||
"displayCameraNames": {
|
||||
"label": "Vždy Zobraziť názvy kamier",
|
||||
"desc": "Vždy zobrazujte názvy kamier v čipe na ovládacom paneli živého náhľadu z viacerých kamier."
|
||||
},
|
||||
"liveFallbackTimeout": {
|
||||
"label": "Časový limit",
|
||||
"desc": "Keď je kamerový vysoko kvalitný živý stream nedostupný, prejdite späť na režim nízkej kvality. Predvolené: 3."
|
||||
}
|
||||
},
|
||||
"storedLayouts": {
|
||||
@ -482,7 +486,8 @@
|
||||
"steps": {
|
||||
"nameAndConnection": "Meno a pripojenie",
|
||||
"streamConfiguration": "Konfigurácia prúdu",
|
||||
"validationAndTesting": "Platnosť a testovanie"
|
||||
"validationAndTesting": "Platnosť a testovanie",
|
||||
"probeOrSnapshot": "Probe alebo Snapshot"
|
||||
},
|
||||
"save": {
|
||||
"success": "Úspešne zachránil novú kameru {{cameraName}}.",
|
||||
@ -539,7 +544,14 @@
|
||||
"testing": {
|
||||
"probingMetadata": "Skúmanie metadát kamery...",
|
||||
"fetchingSnapshot": "Načítava sa snímka z kamery..."
|
||||
}
|
||||
},
|
||||
"connectionSettings": "Nastavenie pripojenia",
|
||||
"detectionMethod": "Stream Detekcia Metóda",
|
||||
"onvifPort": "ONVIF Port",
|
||||
"probeMode": "Probe kamera",
|
||||
"manualMode": "Ručný výber",
|
||||
"detectionMethodDescription": "Vyskúša cez ONVIF (ak je podporovaný) nájsť kamery streamové adresy, alebo ručne vyberte značku kamery a jej preddefinované URL. Ak chcete zadať vlastnú URL RTSP, vyberte manuálne zadanie a označte \"Ostatné\".",
|
||||
"onvifPortDescription": "Pre kamery, ktoré podporujú ONVIF, to je zvyčajne 80 alebo 8080."
|
||||
},
|
||||
"step2": {
|
||||
"description": "Konfigurovať prúdové role a pridať ďalšie prúdy pre vašu kameru.",
|
||||
|
||||
@ -76,7 +76,12 @@
|
||||
}
|
||||
},
|
||||
"npuUsage": "Použitie NPU",
|
||||
"npuMemory": "Pamäť NPU"
|
||||
"npuMemory": "Pamäť NPU",
|
||||
"intelGpuWarning": {
|
||||
"title": "Intel GPU Stats Upozornenie",
|
||||
"message": "Štatistiky GPU nedostupné",
|
||||
"description": "Toto je známa chyba v Štatistike správ Intel (intel_gpu_top) kde sa rozpadne a opakovane vráti používanie GPU 0% aj v prípadoch, keď hardvér detekcie objektov správne beží na (i)GPU. Toto nie je Frigate chyba. Môžete reštartovať a tak dočasne opraviť problém a potvrdiť, že GPU funguje správne. Toto nemá vplyv na výkon."
|
||||
}
|
||||
},
|
||||
"otherProcesses": {
|
||||
"title": "Iné procesy",
|
||||
@ -180,7 +185,11 @@
|
||||
"plate_recognition_speed": "Rýchlosť rozpoznávania ŠPZ",
|
||||
"text_embedding_speed": "Rýchlosť vkladania textu",
|
||||
"yolov9_plate_detection_speed": "YOLOv9 rýchlosť detekcie ŠPZ",
|
||||
"yolov9_plate_detection": "YOLOv9 Detekcia ŠPZ"
|
||||
}
|
||||
"yolov9_plate_detection": "YOLOv9 Detekcia ŠPZ",
|
||||
"review_description": "Popis recenzie",
|
||||
"review_description_speed": "Popis recenzie Rýchlosťi",
|
||||
"review_description_events_per_second": "Popis"
|
||||
},
|
||||
"averageInf": "Priemerný čas inferencie"
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,6 +102,11 @@
|
||||
"toast": {
|
||||
"success": "Інформацію про графічний процесор скопійовано в буфер обміну"
|
||||
}
|
||||
},
|
||||
"intelGpuWarning": {
|
||||
"title": "Попередження щодо статистики графічного процесора Intel",
|
||||
"message": "Статистика графічного процесора недоступна",
|
||||
"description": "Це відома помилка в інструментах звітності статистики графічного процесора Intel (intel_gpu_top), яка неодноразово повертає використання графічного процесора на рівні 0%, навіть у випадках, коли апаратне прискорення та виявлення об'єктів працюють належним чином на (i)GPU. Це не помилка Frigate. Ви можете перезавантажити хост, щоб тимчасово виправити проблему та переконатися, що графічний процесор працює правильно. Це не впливає на продуктивність."
|
||||
}
|
||||
},
|
||||
"otherProcesses": {
|
||||
|
||||
@ -572,9 +572,8 @@ export function SortTypeContent({
|
||||
className="w-full space-y-1"
|
||||
>
|
||||
{availableSortTypes.map((value) => (
|
||||
<div className="flex flex-row gap-2">
|
||||
<div key={value} className="flex flex-row gap-2">
|
||||
<RadioGroupItem
|
||||
key={value}
|
||||
value={value}
|
||||
id={`sort-${value}`}
|
||||
className={
|
||||
|
||||
@ -42,9 +42,10 @@ export default function DetailActionsMenu({
|
||||
return `start/${startTime}/end/${endTime}`;
|
||||
}, [search]);
|
||||
|
||||
const { data: reviewItem } = useSWR<ReviewSegment>([
|
||||
`review/event/${search.id}`,
|
||||
]);
|
||||
// currently, audio event ids are not saved in review items
|
||||
const { data: reviewItem } = useSWR<ReviewSegment>(
|
||||
search.data?.type === "audio" ? null : [`review/event/${search.id}`],
|
||||
);
|
||||
|
||||
return (
|
||||
<DropdownMenu open={isOpen} onOpenChange={setIsOpen}>
|
||||
|
||||
@ -1295,6 +1295,7 @@ function ObjectDetailsTab({
|
||||
|
||||
{search.data.type === "object" &&
|
||||
config?.plus?.enabled &&
|
||||
search.end_time != undefined &&
|
||||
search.has_snapshot && (
|
||||
<div
|
||||
className={cn(
|
||||
|
||||
@ -94,24 +94,52 @@ export default function HlsVideoPlayer({
|
||||
const [loadedMetadata, setLoadedMetadata] = useState(false);
|
||||
const [bufferTimeout, setBufferTimeout] = useState<NodeJS.Timeout>();
|
||||
|
||||
const applyVideoDimensions = useCallback(
|
||||
(width: number, height: number) => {
|
||||
if (setFullResolution) {
|
||||
setFullResolution({ width, height });
|
||||
}
|
||||
setVideoDimensions({ width, height });
|
||||
if (height > 0) {
|
||||
setTallCamera(width / height < ASPECT_VERTICAL_LAYOUT);
|
||||
}
|
||||
},
|
||||
[setFullResolution],
|
||||
);
|
||||
|
||||
const handleLoadedMetadata = useCallback(() => {
|
||||
setLoadedMetadata(true);
|
||||
if (videoRef.current) {
|
||||
const width = videoRef.current.videoWidth;
|
||||
const height = videoRef.current.videoHeight;
|
||||
|
||||
if (setFullResolution) {
|
||||
setFullResolution({
|
||||
width,
|
||||
height,
|
||||
});
|
||||
}
|
||||
|
||||
setVideoDimensions({ width, height });
|
||||
|
||||
setTallCamera(width / height < ASPECT_VERTICAL_LAYOUT);
|
||||
if (!videoRef.current) {
|
||||
return;
|
||||
}
|
||||
}, [videoRef, setFullResolution]);
|
||||
|
||||
const width = videoRef.current.videoWidth;
|
||||
const height = videoRef.current.videoHeight;
|
||||
|
||||
// iOS Safari occasionally reports 0x0 for videoWidth/videoHeight
|
||||
// Poll with requestAnimationFrame until dimensions become available (or timeout).
|
||||
if (width > 0 && height > 0) {
|
||||
applyVideoDimensions(width, height);
|
||||
return;
|
||||
}
|
||||
|
||||
let attempts = 0;
|
||||
const maxAttempts = 120; // ~2 seconds at 60fps
|
||||
const tryGetDims = () => {
|
||||
if (!videoRef.current) return;
|
||||
const w = videoRef.current.videoWidth;
|
||||
const h = videoRef.current.videoHeight;
|
||||
if (w > 0 && h > 0) {
|
||||
applyVideoDimensions(w, h);
|
||||
return;
|
||||
}
|
||||
if (attempts < maxAttempts) {
|
||||
attempts += 1;
|
||||
requestAnimationFrame(tryGetDims);
|
||||
}
|
||||
};
|
||||
requestAnimationFrame(tryGetDims);
|
||||
}, [videoRef, applyVideoDimensions]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!videoRef.current) {
|
||||
|
||||
@ -91,7 +91,7 @@ function MSEPlayer({
|
||||
(error: LivePlayerError, description: string = "Unknown error") => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(
|
||||
`${camera} - MSE error '${error}': ${description} See the documentation: https://docs.frigate.video/configuration/live/#live-view-faq`,
|
||||
`${camera} - MSE error '${error}': ${description} See the documentation: https://docs.frigate.video/configuration/live/#live-player-error-messages`,
|
||||
);
|
||||
onError?.(error);
|
||||
},
|
||||
|
||||
@ -42,7 +42,7 @@ export default function WebRtcPlayer({
|
||||
(error: LivePlayerError, description: string = "Unknown error") => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(
|
||||
`${camera} - WebRTC error '${error}': ${description} See the documentation: https://docs.frigate.video/configuration/live/#live-view-faq`,
|
||||
`${camera} - WebRTC error '${error}': ${description} See the documentation: https://docs.frigate.video/configuration/live/#live-player-error-messages`,
|
||||
);
|
||||
onError?.(error);
|
||||
},
|
||||
|
||||
@ -16,7 +16,6 @@ import ImageLoadingIndicator from "@/components/indicators/ImageLoadingIndicator
|
||||
import useImageLoaded from "@/hooks/use-image-loaded";
|
||||
import ActivityIndicator from "@/components/indicators/activity-indicator";
|
||||
import { useTrackedObjectUpdate } from "@/api/ws";
|
||||
import { isEqual } from "lodash";
|
||||
import TimeAgo from "@/components/dynamic/TimeAgo";
|
||||
import SearchResultActions from "@/components/menu/SearchResultActions";
|
||||
import { SearchTab } from "@/components/overlay/detail/SearchDetailDialog";
|
||||
@ -25,14 +24,12 @@ import { useTranslation } from "react-i18next";
|
||||
import { getTranslatedLabel } from "@/utils/i18n";
|
||||
|
||||
type ExploreViewProps = {
|
||||
searchDetail: SearchResult | undefined;
|
||||
setSearchDetail: (search: SearchResult | undefined) => void;
|
||||
setSimilaritySearch: (search: SearchResult) => void;
|
||||
onSelectSearch: (item: SearchResult, ctrl: boolean, page?: SearchTab) => void;
|
||||
};
|
||||
|
||||
export default function ExploreView({
|
||||
searchDetail,
|
||||
setSearchDetail,
|
||||
setSimilaritySearch,
|
||||
onSelectSearch,
|
||||
@ -83,20 +80,6 @@ export default function ExploreView({
|
||||
}
|
||||
}, [wsUpdate, mutate]);
|
||||
|
||||
// update search detail when results change
|
||||
|
||||
useEffect(() => {
|
||||
if (searchDetail && events) {
|
||||
const updatedSearchDetail = events.find(
|
||||
(result) => result.id === searchDetail.id,
|
||||
);
|
||||
|
||||
if (updatedSearchDetail && !isEqual(updatedSearchDetail, searchDetail)) {
|
||||
setSearchDetail(updatedSearchDetail);
|
||||
}
|
||||
}
|
||||
}, [events, searchDetail, setSearchDetail]);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<ActivityIndicator className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2" />
|
||||
|
||||
@ -19,7 +19,6 @@ import useKeyboardListener, {
|
||||
import scrollIntoView from "scroll-into-view-if-needed";
|
||||
import InputWithTags from "@/components/input/InputWithTags";
|
||||
import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area";
|
||||
import { isEqual } from "lodash";
|
||||
import { formatDateToLocaleString } from "@/utils/dateUtil";
|
||||
import SearchThumbnailFooter from "@/components/card/SearchThumbnailFooter";
|
||||
import ExploreSettings from "@/components/settings/SearchSettings";
|
||||
@ -213,7 +212,7 @@ export default function SearchView({
|
||||
|
||||
// detail
|
||||
|
||||
const [searchDetail, setSearchDetail] = useState<SearchResult>();
|
||||
const [selectedId, setSelectedId] = useState<string>();
|
||||
const [page, setPage] = useState<SearchTab>("snapshot");
|
||||
|
||||
// remove duplicate event ids
|
||||
@ -229,6 +228,16 @@ export default function SearchView({
|
||||
return results;
|
||||
}, [searchResults]);
|
||||
|
||||
const searchDetail = useMemo(() => {
|
||||
if (!selectedId) return undefined;
|
||||
// summary view
|
||||
if (defaultView === "summary" && exploreEvents) {
|
||||
return exploreEvents.find((r) => r.id === selectedId);
|
||||
}
|
||||
// grid view
|
||||
return uniqueResults.find((r) => r.id === selectedId);
|
||||
}, [selectedId, uniqueResults, exploreEvents, defaultView]);
|
||||
|
||||
// search interaction
|
||||
|
||||
const [selectedObjects, setSelectedObjects] = useState<string[]>([]);
|
||||
@ -256,7 +265,7 @@ export default function SearchView({
|
||||
}
|
||||
} else {
|
||||
setPage(page);
|
||||
setSearchDetail(item);
|
||||
setSelectedId(item.id);
|
||||
}
|
||||
},
|
||||
[selectedObjects],
|
||||
@ -295,26 +304,12 @@ export default function SearchView({
|
||||
}
|
||||
};
|
||||
|
||||
// update search detail when results change
|
||||
|
||||
// clear selected item when search results clear
|
||||
useEffect(() => {
|
||||
if (searchDetail) {
|
||||
const results =
|
||||
defaultView === "summary" ? exploreEvents : searchResults?.flat();
|
||||
if (results) {
|
||||
const updatedSearchDetail = results.find(
|
||||
(result) => result.id === searchDetail.id,
|
||||
);
|
||||
|
||||
if (
|
||||
updatedSearchDetail &&
|
||||
!isEqual(updatedSearchDetail, searchDetail)
|
||||
) {
|
||||
setSearchDetail(updatedSearchDetail);
|
||||
}
|
||||
}
|
||||
if (!searchResults && !exploreEvents) {
|
||||
setSelectedId(undefined);
|
||||
}
|
||||
}, [searchResults, exploreEvents, searchDetail, defaultView]);
|
||||
}, [searchResults, exploreEvents]);
|
||||
|
||||
const hasExistingSearch = useMemo(
|
||||
() => searchResults != undefined || searchFilter != undefined,
|
||||
@ -340,7 +335,7 @@ export default function SearchView({
|
||||
? results.length - 1
|
||||
: (currentIndex - 1 + results.length) % results.length;
|
||||
|
||||
setSearchDetail(results[newIndex]);
|
||||
setSelectedId(results[newIndex].id);
|
||||
}
|
||||
}, [uniqueResults, exploreEvents, searchDetail, defaultView]);
|
||||
|
||||
@ -357,7 +352,7 @@ export default function SearchView({
|
||||
const newIndex =
|
||||
currentIndex === -1 ? 0 : (currentIndex + 1) % results.length;
|
||||
|
||||
setSearchDetail(results[newIndex]);
|
||||
setSelectedId(results[newIndex].id);
|
||||
}
|
||||
}, [uniqueResults, exploreEvents, searchDetail, defaultView]);
|
||||
|
||||
@ -509,7 +504,7 @@ export default function SearchView({
|
||||
<SearchDetailDialog
|
||||
search={searchDetail}
|
||||
page={page}
|
||||
setSearch={setSearchDetail}
|
||||
setSearch={(item) => setSelectedId(item?.id)}
|
||||
setSearchPage={setPage}
|
||||
setSimilarity={
|
||||
searchDetail && (() => setSimilaritySearch(searchDetail))
|
||||
@ -629,7 +624,7 @@ export default function SearchView({
|
||||
detail: boolean,
|
||||
) => {
|
||||
if (detail && selectedObjects.length == 0) {
|
||||
setSearchDetail(value);
|
||||
setSelectedId(value.id);
|
||||
} else {
|
||||
onSelectSearch(
|
||||
value,
|
||||
@ -724,8 +719,7 @@ export default function SearchView({
|
||||
defaultView == "summary" && (
|
||||
<div className="scrollbar-container flex size-full flex-col overflow-y-auto">
|
||||
<ExploreView
|
||||
searchDetail={searchDetail}
|
||||
setSearchDetail={setSearchDetail}
|
||||
setSearchDetail={(item) => setSelectedId(item?.id)}
|
||||
setSimilaritySearch={setSimilaritySearch}
|
||||
onSelectSearch={onSelectSearch}
|
||||
/>
|
||||
|
||||