mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-06-25 22:01:51 +03:00
150 lines
4.7 KiB
Python
150 lines
4.7 KiB
Python
from enum import Enum
|
|
from typing import Union
|
|
|
|
from pydantic import Field, field_validator
|
|
|
|
from frigate.util.config import resolve_ffmpeg_path
|
|
|
|
from ..base import FrigateBaseModel
|
|
from ..env import EnvString
|
|
|
|
__all__ = [
|
|
"CameraFfmpegConfig",
|
|
"CameraInput",
|
|
"CameraRoleEnum",
|
|
"FfmpegConfig",
|
|
"FfmpegOutputArgsConfig",
|
|
]
|
|
|
|
# Note: Setting threads to less than 2 caused several issues with recording segments
|
|
# https://github.com/blakeblackshear/frigate/issues/5659
|
|
FFMPEG_GLOBAL_ARGS_DEFAULT = ["-hide_banner", "-loglevel", "warning", "-threads", "2"]
|
|
FFMPEG_INPUT_ARGS_DEFAULT = "preset-rtsp-generic"
|
|
|
|
RECORD_FFMPEG_OUTPUT_ARGS_DEFAULT = "preset-record-generic-audio-aac"
|
|
DETECT_FFMPEG_OUTPUT_ARGS_DEFAULT = [
|
|
"-threads",
|
|
"2",
|
|
"-f",
|
|
"rawvideo",
|
|
"-pix_fmt",
|
|
"yuv420p",
|
|
]
|
|
|
|
|
|
class FfmpegOutputArgsConfig(FrigateBaseModel):
|
|
detect: Union[str, list[str]] = Field(
|
|
default=DETECT_FFMPEG_OUTPUT_ARGS_DEFAULT,
|
|
title="Detect output arguments",
|
|
description="Default output arguments for detect role streams.",
|
|
)
|
|
record: Union[str, list[str]] = Field(
|
|
default=RECORD_FFMPEG_OUTPUT_ARGS_DEFAULT,
|
|
title="Record output arguments",
|
|
description="Default output arguments for record role streams.",
|
|
)
|
|
|
|
|
|
class FfmpegConfig(FrigateBaseModel):
|
|
path: str = Field(
|
|
default="default",
|
|
title="FFmpeg path",
|
|
description='Path to the FFmpeg binary to use or a version alias ("7.0" or "8.0").',
|
|
)
|
|
global_args: Union[str, list[str]] = Field(
|
|
default=FFMPEG_GLOBAL_ARGS_DEFAULT,
|
|
title="FFmpeg global arguments",
|
|
description="Global arguments passed to FFmpeg processes.",
|
|
)
|
|
hwaccel_args: Union[str, list[str]] = Field(
|
|
default="auto",
|
|
title="Hardware acceleration arguments",
|
|
description="Hardware acceleration arguments for FFmpeg. Provider-specific presets are recommended.",
|
|
)
|
|
input_args: Union[str, list[str]] = Field(
|
|
default=FFMPEG_INPUT_ARGS_DEFAULT,
|
|
title="Input arguments",
|
|
description="Input arguments applied to FFmpeg input streams.",
|
|
)
|
|
output_args: FfmpegOutputArgsConfig = Field(
|
|
default_factory=FfmpegOutputArgsConfig,
|
|
title="Output arguments",
|
|
description="Default output arguments used for different FFmpeg roles such as detect and record.",
|
|
)
|
|
retry_interval: float = Field(
|
|
default=10.0,
|
|
title="FFmpeg retry time",
|
|
description="Seconds to wait before attempting to reconnect a camera stream after failure. Default is 10.",
|
|
gt=0.0,
|
|
)
|
|
apple_compatibility: bool = Field(
|
|
default=False,
|
|
title="Apple compatibility",
|
|
description="Enable HEVC tagging for better Apple player compatibility when recording H.265.",
|
|
)
|
|
gpu: int = Field(
|
|
default=0,
|
|
title="GPU index",
|
|
description="Default GPU index used for hardware acceleration if available.",
|
|
)
|
|
|
|
@property
|
|
def ffmpeg_path(self) -> str:
|
|
return resolve_ffmpeg_path(self.path, "ffmpeg")
|
|
|
|
@property
|
|
def ffprobe_path(self) -> str:
|
|
return resolve_ffmpeg_path(self.path, "ffprobe")
|
|
|
|
|
|
class CameraRoleEnum(str, Enum):
|
|
audio = "audio"
|
|
record = "record"
|
|
detect = "detect"
|
|
|
|
|
|
class CameraInput(FrigateBaseModel):
|
|
path: EnvString = Field(
|
|
title="Input path",
|
|
description="Camera input stream URL or path.",
|
|
)
|
|
roles: list[CameraRoleEnum] = Field(
|
|
title="Input roles",
|
|
description="Roles for this input stream.",
|
|
)
|
|
global_args: Union[str, list[str]] = Field(
|
|
default_factory=list,
|
|
title="FFmpeg global arguments",
|
|
description="FFmpeg global arguments for this input stream.",
|
|
)
|
|
hwaccel_args: Union[str, list[str]] = Field(
|
|
default_factory=list,
|
|
title="Hardware acceleration arguments",
|
|
description="Hardware acceleration arguments for this input stream.",
|
|
)
|
|
input_args: Union[str, list[str]] = Field(
|
|
default_factory=list,
|
|
title="Input arguments",
|
|
description="Input arguments specific to this stream.",
|
|
)
|
|
|
|
|
|
class CameraFfmpegConfig(FfmpegConfig):
|
|
inputs: list[CameraInput] = Field(
|
|
title="Camera inputs",
|
|
description="List of input stream definitions (paths and roles) for this camera.",
|
|
)
|
|
|
|
@field_validator("inputs")
|
|
@classmethod
|
|
def validate_roles(cls, v):
|
|
roles = [role for input in v for role in input.roles]
|
|
|
|
if len(roles) != len(set(roles)):
|
|
raise ValueError("Each input role may only be used once.")
|
|
|
|
if "detect" not in roles:
|
|
raise ValueError("The detect role is required.")
|
|
|
|
return v
|