diff --git a/Makefile b/Makefile index d1427b6df8..51f12f972a 100644 --- a/Makefile +++ b/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 diff --git a/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run b/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run index 7df29f8f59..599ab887e4 100755 --- a/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run +++ b/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run @@ -55,7 +55,7 @@ function setup_homekit_config() { if [[ ! -f "${config_path}" ]]; then echo "[INFO] Creating empty config file for HomeKit..." - echo '{}' > "${config_path}" + : > "${config_path}" fi # Convert YAML to JSON for jq processing @@ -65,23 +65,25 @@ function setup_homekit_config() { return 0 } - # Use jq to filter and keep only the homekit section - local cleaned_json="/tmp/cache/homekit_cleaned.json" - jq ' - # Keep only the homekit section if it exists, otherwise empty object - if has("homekit") then {homekit: .homekit} else {} end - ' "${temp_json}" > "${cleaned_json}" 2>/dev/null || { - echo '{}' > "${cleaned_json}" - } + # Use jq to extract the homekit section, if it exists + local homekit_json + homekit_json=$(jq ' + if has("homekit") then {homekit: .homekit} else null end + ' "${temp_json}" 2>/dev/null) || homekit_json="null" - # Convert back to YAML and write to the config file - yq eval -P "${cleaned_json}" > "${config_path}" 2>/dev/null || { - echo "[WARNING] Failed to convert cleaned config to YAML, creating minimal config" - echo '{}' > "${config_path}" - } + # If no homekit section, write an empty config file + if [[ "${homekit_json}" == "null" ]]; then + : > "${config_path}" + else + # Convert homekit JSON back to YAML and write to the config file + echo "${homekit_json}" | yq eval -P - > "${config_path}" 2>/dev/null || { + echo "[WARNING] Failed to convert cleaned config to YAML, creating minimal config" + : > "${config_path}" + } + fi # Clean up temp files - rm -f "${temp_json}" "${cleaned_json}" + rm -f "${temp_json}" } set_libva_version diff --git a/docs/docs/configuration/advanced.md b/docs/docs/configuration/advanced.md index 17eb2053d9..c04cec97cc 100644 --- a/docs/docs/configuration/advanced.md +++ b/docs/docs/configuration/advanced.md @@ -44,13 +44,21 @@ go2rtc: ### `environment_vars` -This section can be used to set environment variables for those unable to modify the environment of the container, like within Home Assistant OS. +This section can be used to set environment variables for those unable to modify the environment of the container, like within Home Assistant OS. Docker users should set environment variables in their `docker run` command (`-e FRIGATE_MQTT_PASSWORD=secret`) or `docker-compose.yml` file (`environment:` section) instead. Note that values set here are stored in plain text in your config file, so if the goal is to keep credentials out of your configuration, use Docker environment variables or Docker secrets instead. + +Variables prefixed with `FRIGATE_` can be referenced in config fields that support environment variable substitution (such as MQTT host and credentials, camera stream URLs, and ONVIF host and credentials) using the `{FRIGATE_VARIABLE_NAME}` syntax. Example: ```yaml environment_vars: - VARIABLE_NAME: variable_value + FRIGATE_MQTT_USER: my_mqtt_user + FRIGATE_MQTT_PASSWORD: my_mqtt_password + +mqtt: + host: "{FRIGATE_MQTT_HOST}" + user: "{FRIGATE_MQTT_USER}" + password: "{FRIGATE_MQTT_PASSWORD}" ``` #### TensorFlow Thread Configuration diff --git a/docs/docs/configuration/authentication.md b/docs/docs/configuration/authentication.md index 70f756b681..694c4badaf 100644 --- a/docs/docs/configuration/authentication.md +++ b/docs/docs/configuration/authentication.md @@ -86,7 +86,7 @@ Frigate looks for a JWT token secret in the following order: 1. An environment variable named `FRIGATE_JWT_SECRET` 2. A file named `FRIGATE_JWT_SECRET` in the directory specified by the `CREDENTIALS_DIRECTORY` environment variable (defaults to the Docker Secrets directory: `/run/secrets/`) -3. A `jwt_secret` option from the Home Assistant Add-on options +3. A `jwt_secret` option from the Home Assistant App options 4. A `.jwt_secret` file in the config directory If no secret is found on startup, Frigate generates one and stores it in a `.jwt_secret` file in the config directory. @@ -232,7 +232,7 @@ The viewer role provides read-only access to all cameras in the UI and API. Cust ### Role Configuration Example -```yaml +```yaml {11-16} cameras: front_door: # ... camera config diff --git a/docs/docs/configuration/birdseye.md b/docs/docs/configuration/birdseye.md index d4bd1a15e7..f48299aec6 100644 --- a/docs/docs/configuration/birdseye.md +++ b/docs/docs/configuration/birdseye.md @@ -24,7 +24,7 @@ A custom icon can be added to the birdseye background by providing a 180x180 ima If you want to include a camera in Birdseye view only for specific circumstances, or just don't include it at all, the Birdseye setting can be set at the camera level. -```yaml +```yaml {8-10,12-14} # Include all cameras by default in Birdseye view birdseye: enabled: True @@ -48,6 +48,7 @@ By default birdseye shows all cameras that have had the configured activity in t ```yaml birdseye: enabled: True + # highlight-next-line inactivity_threshold: 15 ``` @@ -78,9 +79,11 @@ birdseye: cameras: front: birdseye: + # highlight-next-line order: 1 back: birdseye: + # highlight-next-line order: 2 ``` @@ -92,7 +95,7 @@ It is possible to limit the number of cameras shown on birdseye at one time. Whe For example, this can be configured to only show the most recently active camera. -```yaml +```yaml {3-4} birdseye: enabled: True layout: @@ -103,7 +106,7 @@ birdseye: By default birdseye tries to fit 2 cameras in each row and then double in size until a suitable layout is found. The scaling can be configured with a value between 1.0 and 5.0 depending on use case. -```yaml +```yaml {3-4} birdseye: enabled: True layout: diff --git a/docs/docs/configuration/camera_specific.md b/docs/docs/configuration/camera_specific.md index 50d5c52aa7..c18b87f2e8 100644 --- a/docs/docs/configuration/camera_specific.md +++ b/docs/docs/configuration/camera_specific.md @@ -23,6 +23,7 @@ Some cameras support h265 with different formats, but Safari only supports the a cameras: h265_cam: # <------ Doesn't matter what the camera is called ffmpeg: + # highlight-next-line apple_compatibility: true # <- Adds compatibility with MacOS and iPhone ``` @@ -30,7 +31,7 @@ cameras: Note that mjpeg cameras require encoding the video into h264 for recording, and restream roles. This will use significantly more CPU than if the cameras supported h264 feeds directly. It is recommended to use the restream role to create an h264 restream and then use that as the source for ffmpeg. -```yaml +```yaml {3,10} go2rtc: streams: mjpeg_cam: "ffmpeg:http://your_mjpeg_stream_url#video=h264#hardware" # <- use hardware acceleration to create an h264 stream usable for other components. @@ -96,6 +97,7 @@ This camera is H.265 only. To be able to play clips on some devices (like MacOs cameras: annkec800: # <------ Name the camera ffmpeg: + # highlight-next-line apple_compatibility: true # <- Adds compatibility with MacOS and iPhone output_args: record: preset-record-generic-audio-aac @@ -274,7 +276,7 @@ To use a USB camera (webcam) with Frigate, the recommendation is to use go2rtc's - In your Frigate Configuration File, add the go2rtc stream and roles as appropriate: -``` +```yaml {4,11-12} go2rtc: streams: usb_camera: diff --git a/docs/docs/configuration/cameras.md b/docs/docs/configuration/cameras.md index 47efa5bba9..eed430b520 100644 --- a/docs/docs/configuration/cameras.md +++ b/docs/docs/configuration/cameras.md @@ -66,7 +66,7 @@ Not every PTZ supports ONVIF, which is the standard protocol Frigate uses to com Add the onvif section to your camera in your configuration file: -```yaml +```yaml {4-8} cameras: back: ffmpeg: ... diff --git a/docs/docs/configuration/custom_classification/object_classification.md b/docs/docs/configuration/custom_classification/object_classification.md index ac0b9387a1..caf05d8f3c 100644 --- a/docs/docs/configuration/custom_classification/object_classification.md +++ b/docs/docs/configuration/custom_classification/object_classification.md @@ -7,11 +7,11 @@ Object classification allows you to train a custom MobileNetV2 classification mo ## Minimum System Requirements -Object classification models are lightweight and run very fast on CPU. Inference should be usable on virtually any machine that can run Frigate. +Object classification models are lightweight and run very fast on CPU. Training the model does briefly use a high amount of system resources for about 1–3 minutes per training run. On lower-power devices, training may take longer. -A CPU with AVX instructions is required for training and inference. +A CPU with AVX + AVX2 instructions is required for training and inference. ## Classes @@ -27,7 +27,6 @@ For object classification: ### Classification Type - **Sub label**: - - Applied to the object’s `sub_label` field. - Ideal for a single, more specific identity or type. - Example: `cat` → `Leo`, `Charlie`, `None`. @@ -119,6 +118,7 @@ Enable debug logs for classification models by adding `frigate.data_processing.r logger: default: info logs: + # highlight-next-line frigate.data_processing.real_time.custom_classification: debug ``` diff --git a/docs/docs/configuration/custom_classification/state_classification.md b/docs/docs/configuration/custom_classification/state_classification.md index 1ffdf90115..c41d05439f 100644 --- a/docs/docs/configuration/custom_classification/state_classification.md +++ b/docs/docs/configuration/custom_classification/state_classification.md @@ -7,11 +7,11 @@ State classification allows you to train a custom MobileNetV2 classification mod ## Minimum System Requirements -State classification models are lightweight and run very fast on CPU. Inference should be usable on virtually any machine that can run Frigate. +State classification models are lightweight and run very fast on CPU. Training the model does briefly use a high amount of system resources for about 1–3 minutes per training run. On lower-power devices, training may take longer. -A CPU with AVX instructions is required for training and inference. +A CPU with AVX + AVX2 instructions is required for training and inference. ## Classes @@ -85,6 +85,7 @@ Enable debug logs for classification models by adding `frigate.data_processing.r logger: default: info logs: + # highlight-next-line frigate.data_processing.real_time.custom_classification: debug ``` diff --git a/docs/docs/configuration/face_recognition.md b/docs/docs/configuration/face_recognition.md index 713671a160..c44f76dea2 100644 --- a/docs/docs/configuration/face_recognition.md +++ b/docs/docs/configuration/face_recognition.md @@ -32,6 +32,8 @@ All of these features run locally on your system. ## Minimum System Requirements +A CPU with AVX + AVX2 instructions is required to run Face Recognition. + The `small` model is optimized for efficiency and runs on the CPU, most CPUs should run the model efficiently. The `large` model is optimized for accuracy, an integrated or discrete GPU / NPU is required. See the [Hardware Accelerated Enrichments](/configuration/hardware_acceleration_enrichments.md) documentation. @@ -143,17 +145,14 @@ Start with the [Usage](#usage) section and re-read the [Model Requirements](#mod 1. Ensure `person` is being _detected_. A `person` will automatically be scanned by Frigate for a face. Any detected faces will appear in the Recent Recognitions tab in the Frigate UI's Face Library. If you are using a Frigate+ or `face` detecting model: - - Watch the debug view (Settings --> Debug) to ensure that `face` is being detected along with `person`. - You may need to adjust the `min_score` for the `face` object if faces are not being detected. If you are **not** using a Frigate+ or `face` detecting model: - - Check your `detect` stream resolution and ensure it is sufficiently high enough to capture face details on `person` objects. - You may need to lower your `detection_threshold` if faces are not being detected. 2. Any detected faces will then be _recognized_. - - Make sure you have trained at least one face per the recommendations above. - Adjust `recognition_threshold` settings per the suggestions [above](#advanced-configuration). diff --git a/docs/docs/configuration/genai/config.md b/docs/docs/configuration/genai/config.md index e1f79b7443..cde503e8b1 100644 --- a/docs/docs/configuration/genai/config.md +++ b/docs/docs/configuration/genai/config.md @@ -109,7 +109,7 @@ genai: To use a different Gemini-compatible API endpoint, set the `provider_options` with the `base_url` key to your provider's API URL. For example: -``` +```yaml {4,5} genai: provider: gemini ... @@ -152,7 +152,7 @@ To use a different OpenAI-compatible API endpoint, set the `OPENAI_BASE_URL` env For OpenAI-compatible servers (such as llama.cpp) that don't expose the configured context size in the API response, you can manually specify the context size in `provider_options`: -```yaml +```yaml {5,6} genai: provider: openai base_url: http://your-llama-server diff --git a/docs/docs/configuration/genai/review_summaries.md b/docs/docs/configuration/genai/review_summaries.md index df287446c8..c0d677a013 100644 --- a/docs/docs/configuration/genai/review_summaries.md +++ b/docs/docs/configuration/genai/review_summaries.md @@ -80,6 +80,7 @@ By default, review summaries use preview images (cached preview frames) which ha review: genai: enabled: true + # highlight-next-line image_source: recordings # Options: "preview" (default) or "recordings" ``` @@ -104,7 +105,7 @@ If recordings are not available for a given time period, the system will automat Along with the concern of suspicious activity or immediate threat, you may have concerns such as animals in your garden or a gate being left open. These concerns can be configured so that the review summaries will make note of them if the activity requires additional review. For example: -```yaml +```yaml {4,5} review: genai: enabled: true @@ -116,7 +117,7 @@ review: By default, review summaries are generated in English. You can configure Frigate to generate summaries in your preferred language by setting the `preferred_language` option: -```yaml +```yaml {4} review: genai: enabled: true diff --git a/docs/docs/configuration/hardware_acceleration_enrichments.md b/docs/docs/configuration/hardware_acceleration_enrichments.md index fac2ffa61e..fc246df988 100644 --- a/docs/docs/configuration/hardware_acceleration_enrichments.md +++ b/docs/docs/configuration/hardware_acceleration_enrichments.md @@ -12,23 +12,20 @@ Some of Frigate's enrichments can use a discrete GPU or integrated GPU for accel Object detection and enrichments (like Semantic Search, Face Recognition, and License Plate Recognition) are independent features. To use a GPU / NPU for object detection, see the [Object Detectors](/configuration/object_detectors.md) documentation. If you want to use your GPU for any supported enrichments, you must choose the appropriate Frigate Docker image for your GPU / NPU and configure the enrichment according to its specific documentation. - **AMD** - - ROCm support in the `-rocm` Frigate image is automatically detected for enrichments, but only some enrichment models are available due to ROCm's focus on LLMs and limited stability with certain neural network models. Frigate disables models that perform poorly or are unstable to ensure reliable operation, so only compatible enrichments may be active. - **Intel** - - OpenVINO will automatically be detected and used for enrichments in the default Frigate image. - **Note:** Intel NPUs have limited model support for enrichments. GPU is recommended for enrichments when available. - **Nvidia** - - Nvidia GPUs will automatically be detected and used for enrichments in the `-tensorrt` Frigate image. - Jetson devices will automatically be detected and used for enrichments in the `-tensorrt-jp6` Frigate image. - **RockChip** - RockChip NPU will automatically be detected and used for semantic search v1 and face recognition in the `-rk` Frigate image. -Utilizing a GPU for enrichments does not require you to use the same GPU for object detection. For example, you can run the `tensorrt` Docker image for enrichments and still use other dedicated hardware like a Coral or Hailo for object detection. However, one combination that is not supported is TensorRT for object detection and OpenVINO for enrichments. +Utilizing a GPU for enrichments does not require you to use the same GPU for object detection. For example, you can run the `tensorrt` Docker image to run enrichments on an Nvidia GPU and still use other dedicated hardware like a Coral or Hailo for object detection. However, one combination that is not supported is the `tensorrt` image for object detection on an Nvidia GPU and Intel iGPU for enrichments. :::note diff --git a/docs/docs/configuration/hardware_acceleration_video.md b/docs/docs/configuration/hardware_acceleration_video.md index bbbf5a6406..318e1b23e5 100644 --- a/docs/docs/configuration/hardware_acceleration_video.md +++ b/docs/docs/configuration/hardware_acceleration_video.md @@ -10,6 +10,7 @@ import CommunityBadge from '@site/src/components/CommunityBadge'; It is highly recommended to use an integrated or discrete GPU for hardware acceleration video decoding in Frigate. Some types of hardware acceleration are detected and used automatically, but you may need to update your configuration to enable hardware accelerated decoding in ffmpeg. To verify that hardware acceleration is working: + - Check the logs: A message will either say that hardware acceleration was automatically detected, or there will be a warning that no hardware acceleration was automatically detected - If hardware acceleration is specified in the config, verification can be done by ensuring the logs are free from errors. There is no CPU fallback for hardware acceleration. @@ -67,7 +68,7 @@ Frigate can utilize most Intel integrated GPUs and Arc GPUs to accelerate video :::note -The default driver is `iHD`. You may need to change the driver to `i965` by adding the following environment variable `LIBVA_DRIVER_NAME=i965` to your docker-compose file or [in the `config.yml` for HA Add-on users](advanced.md#environment_vars). +The default driver is `iHD`. You may need to change the driver to `i965` by adding the following environment variable `LIBVA_DRIVER_NAME=i965` to your docker-compose file or [in the `config.yml` for HA App users](advanced.md#environment_vars). See [The Intel Docs](https://www.intel.com/content/www/us/en/support/articles/000005505/processors.html) to figure out what generation your CPU is. @@ -116,12 +117,13 @@ services: frigate: ... image: ghcr.io/blakeblackshear/frigate:stable + # highlight-next-line privileged: true ``` ##### Docker Run CLI - Privileged -```bash +```bash {4} docker run -d \ --name frigate \ ... @@ -135,7 +137,7 @@ Only recent versions of Docker support the `CAP_PERFMON` capability. You can tes ##### Docker Compose - CAP_PERFMON -```yaml +```yaml {5,6} services: frigate: ... @@ -146,7 +148,7 @@ services: ##### Docker Run CLI - CAP_PERFMON -```bash +```bash {4} docker run -d \ --name frigate \ ... @@ -188,7 +190,7 @@ Frigate can utilize modern AMD integrated GPUs and AMD GPUs to accelerate video ### Configuring Radeon Driver -You need to change the driver to `radeonsi` by adding the following environment variable `LIBVA_DRIVER_NAME=radeonsi` to your docker-compose file or [in the `config.yml` for HA Add-on users](advanced.md#environment_vars). +You need to change the driver to `radeonsi` by adding the following environment variable `LIBVA_DRIVER_NAME=radeonsi` to your docker-compose file or [in the `config.yml` for HA App users](advanced.md#environment_vars). ### Via VAAPI @@ -213,7 +215,7 @@ Additional configuration is needed for the Docker container to be able to access #### Docker Compose - Nvidia GPU -```yaml +```yaml {5-12} services: frigate: ... @@ -230,7 +232,7 @@ services: #### Docker Run CLI - Nvidia GPU -```bash +```bash {4} docker run -d \ --name frigate \ ... @@ -292,7 +294,7 @@ These instructions were originally based on the [Jellyfin documentation](https:/ ## Raspberry Pi 3/4 Ensure you increase the allocated RAM for your GPU to at least 128 (`raspi-config` > Performance Options > GPU Memory). -If you are using the HA Add-on, you may need to use the full access variant and turn off _Protection mode_ for hardware acceleration. +If you are using the HA App, you may need to use the full access variant and turn off _Protection mode_ for hardware acceleration. ```yaml # if you want to decode a h264 stream @@ -309,7 +311,7 @@ ffmpeg: If running Frigate through Docker, you either need to run in privileged mode or map the `/dev/video*` devices to Frigate. With Docker Compose add: -```yaml +```yaml {4-5} services: frigate: ... @@ -319,7 +321,7 @@ services: Or with `docker run`: -```bash +```bash {4} docker run -d \ --name frigate \ ... @@ -351,7 +353,7 @@ You will need to use the image with the nvidia container runtime: ### Docker Run CLI - Jetson -```bash +```bash {3} docker run -d \ ... --runtime nvidia @@ -360,7 +362,7 @@ docker run -d \ ### Docker Compose - Jetson -```yaml +```yaml {5} services: frigate: ... @@ -451,14 +453,14 @@ Restarting ffmpeg... you should try to uprade to FFmpeg 7. This can be done using this config option: -``` +```yaml ffmpeg: path: "7.0" ``` You can set this option globally to use FFmpeg 7 for all cameras or on camera level to use it only for specific cameras. Do not confuse this option with: -``` +```yaml cameras: name: ffmpeg: @@ -480,7 +482,7 @@ Make sure to follow the [Synaptics specific installation instructions](/frigate/ Add one of the following FFmpeg presets to your `config.yml` to enable hardware video processing: -```yaml +```yaml {2} ffmpeg: hwaccel_args: -c:v h264_v4l2m2m input_args: preset-rtsp-restream diff --git a/docs/docs/configuration/index.md b/docs/docs/configuration/index.md index b1fa876f95..a7495b28bb 100644 --- a/docs/docs/configuration/index.md +++ b/docs/docs/configuration/index.md @@ -3,7 +3,7 @@ id: index title: Frigate Configuration --- -For Home Assistant Add-on installations, the config file should be at `/addon_configs//config.yml`, where `` is specific to the variant of the Frigate Add-on you are running. See the list of directories [here](#accessing-add-on-config-dir). +For Home Assistant App installations, the config file should be at `/addon_configs//config.yml`, where `` is specific to the variant of the Frigate App you are running. See the list of directories [here](#accessing-app-config-dir). For all other installation types, the config file should be mapped to `/config/config.yml` inside the container. @@ -25,24 +25,24 @@ cameras: - detect ``` -## Accessing the Home Assistant Add-on configuration directory {#accessing-add-on-config-dir} +## Accessing the Home Assistant App configuration directory {#accessing-app-config-dir} -When running Frigate through the HA Add-on, the Frigate `/config` directory is mapped to `/addon_configs/` in the host, where `` is specific to the variant of the Frigate Add-on you are running. +When running Frigate through the HA App, the Frigate `/config` directory is mapped to `/addon_configs/` in the host, where `` is specific to the variant of the Frigate App you are running. -| Add-on Variant | Configuration directory | -| -------------------------- | -------------------------------------------- | -| Frigate | `/addon_configs/ccab4aaf_frigate` | -| Frigate (Full Access) | `/addon_configs/ccab4aaf_frigate-fa` | -| Frigate Beta | `/addon_configs/ccab4aaf_frigate-beta` | -| Frigate Beta (Full Access) | `/addon_configs/ccab4aaf_frigate-fa-beta` | +| App Variant | Configuration directory | +| -------------------------- | ----------------------------------------- | +| Frigate | `/addon_configs/ccab4aaf_frigate` | +| Frigate (Full Access) | `/addon_configs/ccab4aaf_frigate-fa` | +| Frigate Beta | `/addon_configs/ccab4aaf_frigate-beta` | +| Frigate Beta (Full Access) | `/addon_configs/ccab4aaf_frigate-fa-beta` | **Whenever you see `/config` in the documentation, it refers to this directory.** -If for example you are running the standard Add-on variant and use the [VS Code Add-on](https://github.com/hassio-addons/addon-vscode) to browse your files, you can click _File_ > _Open folder..._ and navigate to `/addon_configs/ccab4aaf_frigate` to access the Frigate `/config` directory and edit the `config.yaml` file. You can also use the built-in file editor in the Frigate UI to edit the configuration file. +If for example you are running the standard App variant and use the [VS Code App](https://github.com/hassio-addons/addon-vscode) to browse your files, you can click _File_ > _Open folder..._ and navigate to `/addon_configs/ccab4aaf_frigate` to access the Frigate `/config` directory and edit the `config.yaml` file. You can also use the built-in file editor in the Frigate UI to edit the configuration file. ## VS Code Configuration Schema -VS Code supports JSON schemas for automatically validating configuration files. You can enable this feature by adding `# yaml-language-server: $schema=http://frigate_host:5000/api/config/schema.json` to the beginning of the configuration file. Replace `frigate_host` with the IP address or hostname of your Frigate server. If you're using both VS Code and Frigate as an Add-on, you should use `ccab4aaf-frigate` instead. Make sure to expose the internal unauthenticated port `5000` when accessing the config from VS Code on another machine. +VS Code supports JSON schemas for automatically validating configuration files. You can enable this feature by adding `# yaml-language-server: $schema=http://frigate_host:5000/api/config/schema.json` to the beginning of the configuration file. Replace `frigate_host` with the IP address or hostname of your Frigate server. If you're using both VS Code and Frigate as an App, you should use `ccab4aaf-frigate` instead. Make sure to expose the internal unauthenticated port `5000` when accessing the config from VS Code on another machine. ## Environment Variable Substitution @@ -50,6 +50,7 @@ Frigate supports the use of environment variables starting with `FRIGATE_` **onl ```yaml mqtt: + host: "{FRIGATE_MQTT_HOST}" user: "{FRIGATE_MQTT_USER}" password: "{FRIGATE_MQTT_PASSWORD}" ``` @@ -60,7 +61,7 @@ mqtt: ```yaml onvif: - host: 10.0.10.10 + host: "192.168.1.12" port: 8000 user: "{FRIGATE_RTSP_USER}" password: "{FRIGATE_RTSP_PASSWORD}" @@ -82,10 +83,10 @@ genai: Here are some common starter configuration examples. Refer to the [reference config](./reference.md) for detailed information about all the config values. -### Raspberry Pi Home Assistant Add-on with USB Coral +### Raspberry Pi Home Assistant App with USB Coral - Single camera with 720p, 5fps stream for detect -- MQTT connected to the Home Assistant Mosquitto Add-on +- MQTT connected to the Home Assistant Mosquitto App - Hardware acceleration for decoding video - USB Coral detector - Save all video with any detectable motion for 7 days regardless of whether any objects were detected or not @@ -109,15 +110,16 @@ detectors: record: enabled: True - retain: + motion: days: 7 - mode: motion alerts: retain: days: 30 + mode: motion detections: retain: days: 30 + mode: motion snapshots: enabled: True @@ -165,15 +167,16 @@ detectors: record: enabled: True - retain: + motion: days: 7 - mode: motion alerts: retain: days: 30 + mode: motion detections: retain: days: 30 + mode: motion snapshots: enabled: True @@ -231,15 +234,16 @@ model: record: enabled: True - retain: + motion: days: 7 - mode: motion alerts: retain: days: 30 + mode: motion detections: retain: days: 30 + mode: motion snapshots: enabled: True diff --git a/docs/docs/configuration/license_plate_recognition.md b/docs/docs/configuration/license_plate_recognition.md index ac79426750..a44006b634 100644 --- a/docs/docs/configuration/license_plate_recognition.md +++ b/docs/docs/configuration/license_plate_recognition.md @@ -30,7 +30,7 @@ In the default mode, Frigate's LPR needs to first detect a `car` or `motorcycle` ## Minimum System Requirements -License plate recognition works by running AI models locally on your system. The YOLOv9 plate detector model and the OCR models ([PaddleOCR](https://github.com/PaddlePaddle/PaddleOCR)) are relatively lightweight and can run on your CPU or GPU, depending on your configuration. At least 4GB of RAM is required. +License plate recognition works by running AI models locally on your system. The YOLOv9 plate detector model and the OCR models ([PaddleOCR](https://github.com/PaddlePaddle/PaddleOCR)) are relatively lightweight and can run on your CPU or GPU, depending on your configuration. At least 4GB of RAM and a CPU with AVX + AVX2 instructions is required. ## Configuration @@ -43,7 +43,7 @@ lpr: Like other enrichments in Frigate, LPR **must be enabled globally** to use the feature. You should disable it for specific cameras at the camera level if you don't want to run LPR on cars on those cameras: -```yaml +```yaml {4,5} cameras: garage: ... @@ -375,7 +375,6 @@ Use `match_distance` to allow small character mismatches. Alternatively, define Start with ["Why isn't my license plate being detected and recognized?"](#why-isnt-my-license-plate-being-detected-and-recognized). If you are still having issues, work through these steps. 1. Start with a simplified LPR config. - - Remove or comment out everything in your LPR config, including `min_area`, `min_plate_length`, `format`, `known_plates`, or `enhancement` values so that the only values left are `enabled` and `debug_save_plates`. This will run LPR with Frigate's default values. ```yaml @@ -386,31 +385,28 @@ Start with ["Why isn't my license plate being detected and recognized?"](#why-is ``` 2. Enable debug logs to see exactly what Frigate is doing. - - Enable debug logs for LPR by adding `frigate.data_processing.common.license_plate: debug` to your `logger` configuration. These logs are _very_ verbose, so only keep this enabled when necessary. Restart Frigate after this change. ```yaml logger: default: info logs: + # highlight-next-line frigate.data_processing.common.license_plate: debug ``` 3. Ensure your plates are being _detected_. If you are using a Frigate+ or `license_plate` detecting model: - - Watch the debug view (Settings --> Debug) to ensure that `license_plate` is being detected. - View MQTT messages for `frigate/events` to verify detected plates. - You may need to adjust your `min_score` and/or `threshold` for the `license_plate` object if your plates are not being detected. If you are **not** using a Frigate+ or `license_plate` detecting model: - - Watch the debug logs for messages from the YOLOv9 plate detector. - You may need to adjust your `detection_threshold` if your plates are not being detected. 4. Ensure the characters on detected plates are being _recognized_. - - Enable `debug_save_plates` to save images of detected text on plates to the clips directory (`/media/frigate/clips/lpr`). Ensure these images are readable and the text is clear. - Watch the debug view to see plates recognized in real-time. For non-dedicated LPR cameras, the `car` or `motorcycle` label will change to the recognized plate when LPR is enabled and working. - Adjust `recognition_threshold` settings per the suggestions [above](#advanced-configuration). diff --git a/docs/docs/configuration/live.md b/docs/docs/configuration/live.md index 910cb69f16..8e7eff163b 100644 --- a/docs/docs/configuration/live.md +++ b/docs/docs/configuration/live.md @@ -15,7 +15,7 @@ The jsmpeg live view will use more browser and client GPU resources. Using go2rt | ------ | ------------------------------------- | ---------- | ---------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | jsmpeg | same as `detect -> fps`, capped at 10 | 720p | no | no | Resolution is configurable, but go2rtc is recommended if you want higher resolutions and better frame rates. jsmpeg is Frigate's default without go2rtc configured. | | mse | native | native | yes (depends on audio codec) | yes | iPhone requires iOS 17.1+, Firefox is h.264 only. This is Frigate's default when go2rtc is configured. | -| webrtc | native | native | yes (depends on audio codec) | yes | Requires extra configuration. Frigate attempts to use WebRTC when MSE fails or when using a camera's two-way talk feature. | +| webrtc | native | native | yes (depends on audio codec) | yes | Requires extra configuration. Frigate attempts to use WebRTC when MSE fails or when using a camera's two-way talk feature. | ### Camera Settings Recommendations @@ -77,7 +77,7 @@ Configure the `streams` option with a "friendly name" for your stream followed b Using Frigate's internal version of go2rtc is required to use this feature. You cannot specify paths in the `streams` configuration, only go2rtc stream names. -```yaml +```yaml {3,6,8,25-29} go2rtc: streams: test_cam: @@ -114,9 +114,9 @@ cameras: WebRTC works by creating a TCP or UDP connection on port `8555`. However, it requires additional configuration: - For external access, over the internet, setup your router to forward port `8555` to port `8555` on the Frigate device, for both TCP and UDP. -- For internal/local access, unless you are running through the HA Add-on, you will also need to set the WebRTC candidates list in the go2rtc config. For example, if `192.168.1.10` is the local IP of the device running Frigate: +- For internal/local access, unless you are running through the HA App, you will also need to set the WebRTC candidates list in the go2rtc config. For example, if `192.168.1.10` is the local IP of the device running Frigate: - ```yaml title="config.yml" + ```yaml title="config.yml" {4-7} go2rtc: streams: test_cam: ... @@ -128,13 +128,13 @@ WebRTC works by creating a TCP or UDP connection on port `8555`. However, it req - For access through Tailscale, the Frigate system's Tailscale IP must be added as a WebRTC candidate. Tailscale IPs all start with `100.`, and are reserved within the `100.64.0.0/10` CIDR block. -- Note that some browsers may not support H.265 (HEVC). You can check your browser's current version for H.265 compatibility [here](https://github.com/AlexxIT/go2rtc?tab=readme-ov-file#codecs-madness). +- Note that some browsers may not support H.265 (HEVC). You can check your browser's current version for H.265 compatibility [here](https://github.com/AlexxIT/go2rtc?tab=readme-ov-file#codecs-madness). :::tip -This extra configuration may not be required if Frigate has been installed as a Home Assistant Add-on, as Frigate uses the Supervisor's API to generate a WebRTC candidate. +This extra configuration may not be required if Frigate has been installed as a Home Assistant App, as Frigate uses the Supervisor's API to generate a WebRTC candidate. -However, it is recommended if issues occur to define the candidates manually. You should do this if the Frigate Add-on fails to generate a valid candidate. If an error occurs you will see some warnings like the below in the Add-on logs page during the initialization: +However, it is recommended if issues occur to define the candidates manually. You should do this if the Frigate App fails to generate a valid candidate. If an error occurs you will see some warnings like the below in the App logs page during the initialization: ```log [WARN] Failed to get IP address from supervisor @@ -154,7 +154,7 @@ If not running in host mode, port 8555 will need to be mapped for the container: docker-compose.yml -```yaml +```yaml {4-6} services: frigate: ... @@ -222,34 +222,28 @@ Note that disabling a camera through the config file (`enabled: False`) removes 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: Check the browser console for the supported and negotiated codecs. 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 seconds due to insufficient buffering or a network interruption.` (the seconds value will vary) @@ -270,21 +264,18 @@ When your browser runs into problems playing back your camera streams, it will l If you are using continuous streaming or you are loading more than a few high resolution streams at once on the dashboard, your browser may struggle to begin playback of your streams before the timeout. Frigate always prioritizes showing a live stream as quickly as possible, even if it is a lower quality jsmpeg stream. You can use the "Reset" link/button to try loading your high resolution stream again. Errors in stream playback (e.g., connection failures, codec issues, or buffering timeouts) that cause the fallback to low bandwidth mode (jsmpeg) are logged to the browser console for easier debugging. These errors may include: - - Network issues (e.g., MSE or WebRTC network connection problems). - Unsupported codecs or stream formats (e.g., H.265 in WebRTC, which is not supported in some browsers). - Buffering timeouts or low bandwidth conditions causing fallback to jsmpeg. - Browser compatibility problems (e.g., iOS Safari limitations with MSE). To view browser console logs: - 1. Open the Frigate Live View in your browser. 2. Open the browser's Developer Tools (F12 or right-click > Inspect > Console tab). 3. Reproduce the error (e.g., load a problematic stream or simulate network issues). 4. Look for messages prefixed with the camera name. These logs help identify if the issue is player-specific (MSE vs. WebRTC) or related to camera configuration (e.g., go2rtc streams, codecs). If you see frequent errors: - - Verify your camera's H.264/AAC settings (see [Frigate's camera settings recommendations](#camera_settings_recommendations)). - Check go2rtc configuration for transcoding (e.g., audio to AAC/OPUS). - Test with a different stream via the UI dropdown (if `live -> streams` is configured). @@ -324,9 +315,7 @@ When your browser runs into problems playing back your camera streams, it will l 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) diff --git a/docs/docs/configuration/object_detectors.md b/docs/docs/configuration/object_detectors.md index d4a7f55661..9bdacfb28d 100644 --- a/docs/docs/configuration/object_detectors.md +++ b/docs/docs/configuration/object_detectors.md @@ -34,7 +34,7 @@ Frigate supports multiple different detectors that work on different types of ha **Nvidia GPU** -- [ONNX](#onnx): TensorRT will automatically be detected and used as a detector in the `-tensorrt` Frigate image when a supported ONNX model is configured. +- [ONNX](#onnx): Nvidia GPUs will automatically be detected and used as a detector in the `-tensorrt` Frigate image when a supported ONNX model is configured. **Nvidia Jetson** @@ -65,7 +65,7 @@ This does not affect using hardware for accelerating other tasks such as [semant # Officially Supported Detectors -Frigate provides the following builtin detector types: `cpu`, `edgetpu`, `hailo8l`, `memryx`, `onnx`, `openvino`, `rknn`, and `tensorrt`. By default, Frigate will use a single CPU detector. Other detectors may require additional configuration as described below. When using multiple detectors they will run in dedicated processes, but pull from a common queue of detection requests from across all cameras. +Frigate provides a number of builtin detector types. By default, Frigate will use a single CPU detector. Other detectors may require additional configuration as described below. When using multiple detectors they will run in dedicated processes, but pull from a common queue of detection requests from across all cameras. ## Edge TPU Detector @@ -157,7 +157,13 @@ A TensorFlow Lite model is provided in the container at `/edgetpu_model.tflite` #### YOLOv9 -YOLOv9 models that are compiled for TensorFlow Lite and properly quantized are supported, but not included by default. [Download the model](https://github.com/dbro/frigate-detector-edgetpu-yolo9/releases/download/v1.0/yolov9-s-relu6-best_320_int8_edgetpu.tflite), bind mount the file into the container, and provide the path with `model.path`. Note that the linked model requires a 17-label [labelmap file](https://raw.githubusercontent.com/dbro/frigate-detector-edgetpu-yolo9/refs/heads/main/labels-coco17.txt) that includes only 17 COCO classes. +YOLOv9 models that are compiled for TensorFlow Lite and properly quantized are supported, but not included by default. [Instructions](#yolov9-for-google-coral-support) for downloading a model with support for the Google Coral. + +:::tip + +**Frigate+ Users:** Follow the [instructions](/integrations/plus#use-models) to set a model ID in your config file. + +:::
YOLOv9 Setup & Config @@ -566,7 +572,7 @@ $ docker run --device=/dev/kfd --device=/dev/dri \ When using Docker Compose: -```yaml +```yaml {4-6} services: frigate: ... @@ -597,7 +603,7 @@ $ docker run -e HSA_OVERRIDE_GFX_VERSION=10.0.0 \ When using Docker Compose: -```yaml +```yaml {4-5} services: frigate: ... @@ -654,11 +660,9 @@ ONNX is an open format for building machine learning models, Frigate supports ru If the correct build is used for your GPU then the GPU will be detected and used automatically. - **AMD** - - ROCm will automatically be detected and used with the ONNX detector in the `-rocm` Frigate image. - **Intel** - - OpenVINO will automatically be detected and used with the ONNX detector in the default Frigate image. - **Nvidia** @@ -1514,11 +1518,11 @@ RF-DETR can be exported as ONNX by running the command below. You can copy and p ```sh docker build . --build-arg MODEL_SIZE=Nano --rm --output . -f- <<'EOF' -FROM python:3.11 AS build +FROM python:3.12 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/ +COPY --from=ghcr.io/astral-sh/uv:0.10.4 /uv /bin/ WORKDIR /rfdetr -RUN uv pip install --system rfdetr[onnxexport] torch==2.8.0 onnx==1.19.1 onnxscript +RUN uv pip install --system rfdetr[onnxexport] torch==2.8.0 onnx==1.19.1 transformers==4.57.6 onnxscript ARG MODEL_SIZE RUN python3 -c "from rfdetr import RFDETR${MODEL_SIZE}; x = RFDETR${MODEL_SIZE}(resolution=320); x.export(simplify=True)" FROM scratch @@ -1556,19 +1560,23 @@ cd tensorrt_demos/yolo python3 yolo_to_onnx.py -m yolov7-320 ``` -#### YOLOv9 +#### YOLOv9 for Google Coral Support + +[Download the model](https://github.com/dbro/frigate-detector-edgetpu-yolo9/releases/download/v1.0/yolov9-s-relu6-best_320_int8_edgetpu.tflite), bind mount the file into the container, and provide the path with `model.path`. Note that the linked model requires a 17-label [labelmap file](https://raw.githubusercontent.com/dbro/frigate-detector-edgetpu-yolo9/refs/heads/main/labels-coco17.txt) that includes only 17 COCO classes. + +#### YOLOv9 for other detectors YOLOv9 model can be exported as ONNX using the command below. You can copy and paste the whole thing to your terminal and execute, altering `MODEL_SIZE=t` and `IMG_SIZE=320` in the first line to the [model size](https://github.com/WongKinYiu/yolov9#performance) you would like to convert (available model sizes are `t`, `s`, `m`, `c`, and `e`, common image sizes are `320` and `640`). ```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 diff --git a/docs/docs/configuration/record.md b/docs/docs/configuration/record.md index 4dfd8b77c2..4d696dad0e 100644 --- a/docs/docs/configuration/record.md +++ b/docs/docs/configuration/record.md @@ -130,7 +130,7 @@ When exporting a time-lapse the default speed-up is 25x with 30 FPS. This means To configure the speed-up factor, the frame rate and further custom settings, the configuration parameter `timelapse_args` can be used. The below configuration example would change the time-lapse speed to 60x (for fitting 1 hour of recording into 1 minute of time-lapse) with 25 FPS: -```yaml +```yaml {3-4} record: enabled: True export: diff --git a/docs/docs/configuration/reference.md b/docs/docs/configuration/reference.md index 206d7012e3..edcea57a14 100644 --- a/docs/docs/configuration/reference.md +++ b/docs/docs/configuration/reference.md @@ -16,6 +16,8 @@ mqtt: # Optional: Enable mqtt server (default: shown below) enabled: True # Required: host name + # NOTE: MQTT host can be specified with an environment variable or docker secrets that must begin with 'FRIGATE_'. + # e.g. host: '{FRIGATE_MQTT_HOST}' host: mqtt.server.com # Optional: port (default: shown below) port: 1883 @@ -906,6 +908,8 @@ cameras: onvif: # Required: host of the camera being connected to. # NOTE: HTTP is assumed by default; HTTPS is supported if you specify the scheme, ex: "https://0.0.0.0". + # NOTE: ONVIF user, and password can be specified with environment variables or docker secrets + # that must begin with 'FRIGATE_'. e.g. host: '{FRIGATE_ONVIF_USERNAME}' host: 0.0.0.0 # Optional: ONVIF port for device (default: shown below). port: 8000 diff --git a/docs/docs/configuration/restream.md b/docs/docs/configuration/restream.md index ebd5062944..875d9a2921 100644 --- a/docs/docs/configuration/restream.md +++ b/docs/docs/configuration/restream.md @@ -34,7 +34,7 @@ To improve connection speed when using Birdseye via restream you can enable a sm The go2rtc restream can be secured with RTSP based username / password authentication. Ex: -```yaml +```yaml {2-4} go2rtc: rtsp: username: "admin" @@ -147,6 +147,7 @@ For example: ```yaml go2rtc: streams: + # highlight-error-line my_camera: rtsp://username:$@foo%@192.168.1.100 ``` @@ -155,6 +156,7 @@ becomes ```yaml go2rtc: streams: + # highlight-next-line my_camera: rtsp://username:$%40foo%25@192.168.1.100 ``` diff --git a/docs/docs/configuration/review.md b/docs/docs/configuration/review.md index 752c496a32..d8769749b8 100644 --- a/docs/docs/configuration/review.md +++ b/docs/docs/configuration/review.md @@ -71,7 +71,7 @@ To exclude a specific camera from alerts or detections, simply provide an empty For example, to exclude objects on the camera _gatecamera_ from any detections, include this in your config: -```yaml +```yaml {3-5} cameras: gatecamera: review: diff --git a/docs/docs/configuration/semantic_search.md b/docs/docs/configuration/semantic_search.md index 91f435ff04..19346454bd 100644 --- a/docs/docs/configuration/semantic_search.md +++ b/docs/docs/configuration/semantic_search.md @@ -13,7 +13,7 @@ Semantic Search is accessed via the _Explore_ view in the Frigate UI. Semantic Search works by running a large AI model locally on your system. Small or underpowered systems like a Raspberry Pi will not run Semantic Search reliably or at all. -A minimum of 8GB of RAM is required to use Semantic Search. A GPU is not strictly required but will provide a significant performance increase over CPU-only systems. +A minimum of 8GB of RAM is required to use Semantic Search. A CPU with AVX + AVX2 instructions is required to run Semantic Search. A GPU is not strictly required but will provide a significant performance increase over CPU-only systems. For best performance, 16GB or more of RAM and a dedicated GPU are recommended. diff --git a/docs/docs/configuration/snapshots.md b/docs/docs/configuration/snapshots.md index 815e301baa..01c034a040 100644 --- a/docs/docs/configuration/snapshots.md +++ b/docs/docs/configuration/snapshots.md @@ -9,4 +9,25 @@ Snapshots are accessible in the UI in the Explore pane. This allows for quick su To only save snapshots for objects that enter a specific zone, [see the zone docs](./zones.md#restricting-snapshots-to-specific-zones) -Snapshots sent via MQTT are configured in the [config file](https://docs.frigate.video/configuration/) under `cameras -> your_camera -> mqtt` +Snapshots sent via MQTT are configured in the [config file](/configuration) under `cameras -> your_camera -> mqtt` + +## Frame Selection + +Frigate does not save every frame — it picks a single "best" frame for each tracked object and uses it for both the snapshot and clean copy. As the object is tracked across frames, Frigate continuously evaluates whether the current frame is better than the previous best based on detection confidence, object size, and the presence of key attributes like faces or license plates. Frames where the object touches the edge of the frame are deprioritized. The snapshot is written to disk once tracking ends using whichever frame was determined to be the best. + +MQTT snapshots are published more frequently — each time a better thumbnail frame is found during tracking, or when the current best image is older than `best_image_timeout` (default: 60s). These use their own annotation settings configured under `cameras -> your_camera -> mqtt`. + +## Clean Copy + +Frigate can produce up to two snapshot files per event, each used in different places: + +| Version | File | Annotations | Used by | +| --- | --- | --- | --- | +| **Regular snapshot** | `-.jpg` | Respects your `timestamp`, `bounding_box`, `crop`, and `height` settings | API (`/api/events//snapshot.jpg`), MQTT (`/