Camera-specific hwaccel settings for timelapse exports (correct base) (#21386)

* added hwaccel_args to camera.record.export config struct

* populate camera.record.export.hwaccel_args with a cascade up to camera then global if 'auto'

* use new hwaccel args in export

* added documentation for camera-specific hwaccel export

* fix c/p error

* missed an import

* fleshed out the docs and comments a bit

* ruff lint

* separated out the tips in the doc

* fix documentation

* fix and simplify reference config doc
This commit is contained in:
Andrew Roberts
2025-12-22 11:10:40 -05:00
committed by GitHub
parent b8bc98a423
commit 7fb8d9b050
5 changed files with 26 additions and 4 deletions

View File

@@ -139,7 +139,11 @@ record:
:::tip :::tip
When using `hwaccel_args` globally hardware encoding is used for time lapse generation. The encoder determines its own behavior so the resulting file size may be undesirably large. When using `hwaccel_args`, hardware encoding is used for timelapse generation. This setting can be overridden for a specific camera (e.g., when camera resolution exceeds hardware encoder limits); set `cameras.<camera>.record.export.hwaccel_args` with the appropriate settings. Using an unrecognized value or empty string will fall back to software encoding (libx264).
:::tip
The encoder determines its own behavior so the resulting file size may be undesirably large.
To reduce the output file size the ffmpeg parameter `-qp n` can be utilized (where `n` stands for the value of the quantisation parameter). The value can be adjusted to get an acceptable tradeoff between quality and file size for the given scenario. To reduce the output file size the ffmpeg parameter `-qp n` can be utilized (where `n` stands for the value of the quantisation parameter). The value can be adjusted to get an acceptable tradeoff between quality and file size for the given scenario.
::: :::

View File

@@ -534,6 +534,8 @@ record:
# The -r (framerate) dictates how smooth the output video is. # The -r (framerate) dictates how smooth the output video is.
# So the args would be -vf setpts=0.02*PTS -r 30 in that case. # So the args would be -vf setpts=0.02*PTS -r 30 in that case.
timelapse_args: "-vf setpts=0.04*PTS -r 30" timelapse_args: "-vf setpts=0.04*PTS -r 30"
# Optional: Global hardware acceleration settings for timelapse exports. (default: inherit)
hwaccel_args: auto
# Optional: Recording Preview Settings # Optional: Recording Preview Settings
preview: preview:
# Optional: Quality of recording preview (default: shown below). # Optional: Quality of recording preview (default: shown below).
@@ -835,6 +837,11 @@ cameras:
# Optional: camera specific output args (default: inherit) # Optional: camera specific output args (default: inherit)
# output_args: # output_args:
# Optional: camera specific hwaccel args for timelapse export (default: inherit)
# record:
# export:
# hwaccel_args:
# Optional: timeout for highest scoring image before allowing it # Optional: timeout for highest scoring image before allowing it
# to be replaced by a newer image. (default: shown below) # to be replaced by a newer image. (default: shown below)
best_image_timeout: 60 best_image_timeout: 60

View File

@@ -1,5 +1,5 @@
from enum import Enum from enum import Enum
from typing import Optional from typing import Optional, Union
from pydantic import Field from pydantic import Field
@@ -70,6 +70,9 @@ class RecordExportConfig(FrigateBaseModel):
timelapse_args: str = Field( timelapse_args: str = Field(
default=DEFAULT_TIME_LAPSE_FFMPEG_ARGS, title="Timelapse Args" default=DEFAULT_TIME_LAPSE_FFMPEG_ARGS, title="Timelapse Args"
) )
hwaccel_args: Union[str, list[str]] = Field(
default="auto", title="Export-specific FFmpeg hardware acceleration arguments."
)
class RecordConfig(FrigateBaseModel): class RecordConfig(FrigateBaseModel):

View File

@@ -523,6 +523,14 @@ class FrigateConfig(FrigateBaseModel):
if camera_config.ffmpeg.hwaccel_args == "auto": if camera_config.ffmpeg.hwaccel_args == "auto":
camera_config.ffmpeg.hwaccel_args = self.ffmpeg.hwaccel_args camera_config.ffmpeg.hwaccel_args = self.ffmpeg.hwaccel_args
# Resolve export hwaccel_args: camera export -> camera ffmpeg -> global ffmpeg
# This allows per-camera override for exports (e.g., when camera resolution
# exceeds hardware encoder limits)
if camera_config.record.export.hwaccel_args == "auto":
camera_config.record.export.hwaccel_args = (
camera_config.ffmpeg.hwaccel_args
)
for input in camera_config.ffmpeg.inputs: for input in camera_config.ffmpeg.inputs:
need_detect_dimensions = "detect" in input.roles and ( need_detect_dimensions = "detect" in input.roles and (
camera_config.detect.height is None camera_config.detect.height is None

View File

@@ -228,7 +228,7 @@ class RecordingExporter(threading.Thread):
ffmpeg_cmd = ( ffmpeg_cmd = (
parse_preset_hardware_acceleration_encode( parse_preset_hardware_acceleration_encode(
self.config.ffmpeg.ffmpeg_path, self.config.ffmpeg.ffmpeg_path,
self.config.ffmpeg.hwaccel_args, self.config.cameras[self.camera].record.export.hwaccel_args,
f"-an {ffmpeg_input}", f"-an {ffmpeg_input}",
f"{self.config.cameras[self.camera].record.export.timelapse_args} -movflags +faststart", f"{self.config.cameras[self.camera].record.export.timelapse_args} -movflags +faststart",
EncodeTypeEnum.timelapse, EncodeTypeEnum.timelapse,
@@ -319,7 +319,7 @@ class RecordingExporter(threading.Thread):
ffmpeg_cmd = ( ffmpeg_cmd = (
parse_preset_hardware_acceleration_encode( parse_preset_hardware_acceleration_encode(
self.config.ffmpeg.ffmpeg_path, self.config.ffmpeg.ffmpeg_path,
self.config.ffmpeg.hwaccel_args, self.config.cameras[self.camera].record.export.hwaccel_args,
f"{TIMELAPSE_DATA_INPUT_ARGS} {ffmpeg_input}", f"{TIMELAPSE_DATA_INPUT_ARGS} {ffmpeg_input}",
f"{self.config.cameras[self.camera].record.export.timelapse_args} -movflags +faststart {video_path}", f"{self.config.cameras[self.camera].record.export.timelapse_args} -movflags +faststart {video_path}",
EncodeTypeEnum.timelapse, EncodeTypeEnum.timelapse,