diff --git a/docs/docs/configuration/record.md b/docs/docs/configuration/record.md index 4dfd8b77c..ddbf0f612 100644 --- a/docs/docs/configuration/record.md +++ b/docs/docs/configuration/record.md @@ -139,7 +139,11 @@ record: :::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..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. ::: diff --git a/docs/docs/configuration/reference.md b/docs/docs/configuration/reference.md index cccaf3eaa..f2d7eccb2 100644 --- a/docs/docs/configuration/reference.md +++ b/docs/docs/configuration/reference.md @@ -534,6 +534,8 @@ record: # 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. 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 preview: # Optional: Quality of recording preview (default: shown below). @@ -835,6 +837,11 @@ cameras: # Optional: camera specific output args (default: inherit) # 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 # to be replaced by a newer image. (default: shown below) best_image_timeout: 60 diff --git a/frigate/config/camera/record.py b/frigate/config/camera/record.py index 09a7a84d5..90881f448 100644 --- a/frigate/config/camera/record.py +++ b/frigate/config/camera/record.py @@ -1,5 +1,5 @@ from enum import Enum -from typing import Optional +from typing import Optional, Union from pydantic import Field @@ -70,6 +70,9 @@ class RecordExportConfig(FrigateBaseModel): timelapse_args: str = Field( 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): diff --git a/frigate/config/config.py b/frigate/config/config.py index 6342c13bf..00350358c 100644 --- a/frigate/config/config.py +++ b/frigate/config/config.py @@ -523,6 +523,14 @@ class FrigateConfig(FrigateBaseModel): if camera_config.ffmpeg.hwaccel_args == "auto": 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: need_detect_dimensions = "detect" in input.roles and ( camera_config.detect.height is None diff --git a/frigate/record/export.py b/frigate/record/export.py index 9a2a77ebf..9a8b5dbdb 100644 --- a/frigate/record/export.py +++ b/frigate/record/export.py @@ -228,7 +228,7 @@ class RecordingExporter(threading.Thread): ffmpeg_cmd = ( parse_preset_hardware_acceleration_encode( self.config.ffmpeg.ffmpeg_path, - self.config.ffmpeg.hwaccel_args, + self.config.cameras[self.camera].record.export.hwaccel_args, f"-an {ffmpeg_input}", f"{self.config.cameras[self.camera].record.export.timelapse_args} -movflags +faststart", EncodeTypeEnum.timelapse, @@ -319,7 +319,7 @@ class RecordingExporter(threading.Thread): ffmpeg_cmd = ( parse_preset_hardware_acceleration_encode( 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"{self.config.cameras[self.camera].record.export.timelapse_args} -movflags +faststart {video_path}", EncodeTypeEnum.timelapse,