mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-01-24 13:08:29 +03:00
Allow segment length override
This commit is contained in:
parent
fb9604fbcc
commit
a2e010e220
@ -263,6 +263,8 @@ ffmpeg:
|
|||||||
detect: -threads 2 -f rawvideo -pix_fmt yuv420p
|
detect: -threads 2 -f rawvideo -pix_fmt yuv420p
|
||||||
# Optional: output args for record streams (default: shown below)
|
# Optional: output args for record streams (default: shown below)
|
||||||
record: preset-record-generic
|
record: preset-record-generic
|
||||||
|
# Optional: Set segment length for recording stream. (default: shown below)
|
||||||
|
segment_time : 10
|
||||||
# Optional: Time in seconds to wait before ffmpeg retries connecting to the camera. (default: shown below)
|
# Optional: Time in seconds to wait before ffmpeg retries connecting to the camera. (default: shown below)
|
||||||
# If set too low, frigate will retry a connection to the camera's stream too frequently, using up the limited streams some cameras can allow at once
|
# If set too low, frigate will retry a connection to the camera's stream too frequently, using up the limited streams some cameras can allow at once
|
||||||
# If set too high, then if a ffmpeg crash or camera stream timeout occurs, you could potentially lose up to a maximum of retry_interval second(s) of footage
|
# If set too high, then if a ffmpeg crash or camera stream timeout occurs, you could potentially lose up to a maximum of retry_interval second(s) of footage
|
||||||
|
|||||||
@ -214,6 +214,7 @@ class CameraConfig(FrigateBaseModel):
|
|||||||
parse_preset_output_record(
|
parse_preset_output_record(
|
||||||
self.ffmpeg.output_args.record,
|
self.ffmpeg.output_args.record,
|
||||||
self.ffmpeg.apple_compatibility,
|
self.ffmpeg.apple_compatibility,
|
||||||
|
self.ffmpeg.output_args.segment_time,
|
||||||
)
|
)
|
||||||
or self.ffmpeg.output_args.record
|
or self.ffmpeg.output_args.record
|
||||||
)
|
)
|
||||||
|
|||||||
@ -41,6 +41,7 @@ class FfmpegOutputArgsConfig(FrigateBaseModel):
|
|||||||
default=RECORD_FFMPEG_OUTPUT_ARGS_DEFAULT,
|
default=RECORD_FFMPEG_OUTPUT_ARGS_DEFAULT,
|
||||||
title="Record role FFmpeg output arguments.",
|
title="Record role FFmpeg output arguments.",
|
||||||
)
|
)
|
||||||
|
segment_time: int = Field(default=10, title="Segment length for recording stream.")
|
||||||
|
|
||||||
|
|
||||||
class FfmpegConfig(FrigateBaseModel):
|
class FfmpegConfig(FrigateBaseModel):
|
||||||
|
|||||||
@ -76,6 +76,8 @@ FFMPEG_HWACCEL_VULKAN = "preset-vulkan"
|
|||||||
FFMPEG_HWACCEL_RKMPP = "preset-rkmpp"
|
FFMPEG_HWACCEL_RKMPP = "preset-rkmpp"
|
||||||
FFMPEG_HWACCEL_AMF = "preset-amd-amf"
|
FFMPEG_HWACCEL_AMF = "preset-amd-amf"
|
||||||
FFMPEG_HVC1_ARGS = ["-tag:v", "hvc1"]
|
FFMPEG_HVC1_ARGS = ["-tag:v", "hvc1"]
|
||||||
|
FFMPEG_SEGMENT_TIME_PARAM = "-segment_time"
|
||||||
|
FFMPEG_SEGMENT_TIME_VALUE = "10"
|
||||||
|
|
||||||
# RKNN constants
|
# RKNN constants
|
||||||
SUPPORTED_RK_SOCS = ["rk3562", "rk3566", "rk3568", "rk3576", "rk3588"]
|
SUPPORTED_RK_SOCS = ["rk3562", "rk3566", "rk3568", "rk3576", "rk3588"]
|
||||||
|
|||||||
@ -12,6 +12,8 @@ from frigate.const import (
|
|||||||
FFMPEG_HWACCEL_RKMPP,
|
FFMPEG_HWACCEL_RKMPP,
|
||||||
FFMPEG_HWACCEL_VAAPI,
|
FFMPEG_HWACCEL_VAAPI,
|
||||||
FFMPEG_HWACCEL_VULKAN,
|
FFMPEG_HWACCEL_VULKAN,
|
||||||
|
FFMPEG_SEGMENT_TIME_PARAM,
|
||||||
|
FFMPEG_SEGMENT_TIME_VALUE,
|
||||||
LIBAVFORMAT_VERSION_MAJOR,
|
LIBAVFORMAT_VERSION_MAJOR,
|
||||||
)
|
)
|
||||||
from frigate.util.services import vainfo_hwaccel
|
from frigate.util.services import vainfo_hwaccel
|
||||||
@ -446,8 +448,8 @@ PRESETS_RECORD_OUTPUT = {
|
|||||||
"preset-record-generic": [
|
"preset-record-generic": [
|
||||||
"-f",
|
"-f",
|
||||||
"segment",
|
"segment",
|
||||||
"-segment_time",
|
FFMPEG_SEGMENT_TIME_PARAM,
|
||||||
"10",
|
FFMPEG_SEGMENT_TIME_VALUE,
|
||||||
"-segment_format",
|
"-segment_format",
|
||||||
"mp4",
|
"mp4",
|
||||||
"-reset_timestamps",
|
"-reset_timestamps",
|
||||||
@ -461,8 +463,8 @@ PRESETS_RECORD_OUTPUT = {
|
|||||||
"preset-record-generic-audio-aac": [
|
"preset-record-generic-audio-aac": [
|
||||||
"-f",
|
"-f",
|
||||||
"segment",
|
"segment",
|
||||||
"-segment_time",
|
FFMPEG_SEGMENT_TIME_PARAM,
|
||||||
"10",
|
FFMPEG_SEGMENT_TIME_VALUE,
|
||||||
"-segment_format",
|
"-segment_format",
|
||||||
"mp4",
|
"mp4",
|
||||||
"-reset_timestamps",
|
"-reset_timestamps",
|
||||||
@ -477,8 +479,8 @@ PRESETS_RECORD_OUTPUT = {
|
|||||||
"preset-record-generic-audio-copy": [
|
"preset-record-generic-audio-copy": [
|
||||||
"-f",
|
"-f",
|
||||||
"segment",
|
"segment",
|
||||||
"-segment_time",
|
FFMPEG_SEGMENT_TIME_PARAM,
|
||||||
"10",
|
FFMPEG_SEGMENT_TIME_VALUE,
|
||||||
"-segment_format",
|
"-segment_format",
|
||||||
"mp4",
|
"mp4",
|
||||||
"-reset_timestamps",
|
"-reset_timestamps",
|
||||||
@ -491,8 +493,8 @@ PRESETS_RECORD_OUTPUT = {
|
|||||||
"preset-record-mjpeg": [
|
"preset-record-mjpeg": [
|
||||||
"-f",
|
"-f",
|
||||||
"segment",
|
"segment",
|
||||||
"-segment_time",
|
FFMPEG_SEGMENT_TIME_PARAM,
|
||||||
"10",
|
FFMPEG_SEGMENT_TIME_VALUE,
|
||||||
"-segment_format",
|
"-segment_format",
|
||||||
"mp4",
|
"mp4",
|
||||||
"-reset_timestamps",
|
"-reset_timestamps",
|
||||||
@ -506,8 +508,8 @@ PRESETS_RECORD_OUTPUT = {
|
|||||||
"preset-record-jpeg": [
|
"preset-record-jpeg": [
|
||||||
"-f",
|
"-f",
|
||||||
"segment",
|
"segment",
|
||||||
"-segment_time",
|
FFMPEG_SEGMENT_TIME_PARAM,
|
||||||
"10",
|
FFMPEG_SEGMENT_TIME_VALUE,
|
||||||
"-segment_format",
|
"-segment_format",
|
||||||
"mp4",
|
"mp4",
|
||||||
"-reset_timestamps",
|
"-reset_timestamps",
|
||||||
@ -521,8 +523,8 @@ PRESETS_RECORD_OUTPUT = {
|
|||||||
"preset-record-ubiquiti": [
|
"preset-record-ubiquiti": [
|
||||||
"-f",
|
"-f",
|
||||||
"segment",
|
"segment",
|
||||||
"-segment_time",
|
FFMPEG_SEGMENT_TIME_PARAM,
|
||||||
"10",
|
FFMPEG_SEGMENT_TIME_VALUE,
|
||||||
"-segment_format",
|
"-segment_format",
|
||||||
"mp4",
|
"mp4",
|
||||||
"-reset_timestamps",
|
"-reset_timestamps",
|
||||||
@ -539,7 +541,7 @@ PRESETS_RECORD_OUTPUT = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def parse_preset_output_record(arg: Any, force_record_hvc1: bool) -> list[str]:
|
def parse_preset_output_record(arg: Any, force_record_hvc1: bool, segment_time: int = -1) -> list[str] | None:
|
||||||
"""Return the correct preset if in preset format otherwise return None."""
|
"""Return the correct preset if in preset format otherwise return None."""
|
||||||
if not isinstance(arg, str):
|
if not isinstance(arg, str):
|
||||||
return None
|
return None
|
||||||
@ -549,6 +551,11 @@ def parse_preset_output_record(arg: Any, force_record_hvc1: bool) -> list[str]:
|
|||||||
if not preset:
|
if not preset:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
if 0 < segment_time <= 60 and FFMPEG_SEGMENT_TIME_PARAM in preset:
|
||||||
|
idx = preset.index(FFMPEG_SEGMENT_TIME_PARAM)
|
||||||
|
if idx + 1 < len(preset):
|
||||||
|
preset[idx + 1] = str(segment_time)
|
||||||
|
|
||||||
if force_record_hvc1:
|
if force_record_hvc1:
|
||||||
# Apple only supports HEVC if it is hvc1 (vs. hev1)
|
# Apple only supports HEVC if it is hvc1 (vs. hev1)
|
||||||
return preset + FFMPEG_HVC1_ARGS
|
return preset + FFMPEG_HVC1_ARGS
|
||||||
|
|||||||
@ -128,6 +128,75 @@ class TestConfig(unittest.TestCase):
|
|||||||
}
|
}
|
||||||
self.assertRaises(ValidationError, lambda: FrigateConfig(**config))
|
self.assertRaises(ValidationError, lambda: FrigateConfig(**config))
|
||||||
|
|
||||||
|
def test_default_segment_length(self):
|
||||||
|
config = {
|
||||||
|
"mqtt": {"host": "mqtt"},
|
||||||
|
"cameras": {
|
||||||
|
"back": {
|
||||||
|
"ffmpeg": {
|
||||||
|
"inputs": [
|
||||||
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"detect": {
|
||||||
|
"height": 1080,
|
||||||
|
"width": 1920,
|
||||||
|
"fps": 5,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
frigate_config = FrigateConfig(**config)
|
||||||
|
assert frigate_config.cameras["back"].ffmpeg.output_args.segment_time == 10
|
||||||
|
|
||||||
|
def test_inherit_segment_length(self):
|
||||||
|
config = {
|
||||||
|
"mqtt": {"host": "mqtt"},
|
||||||
|
"ffmpeg": {"output_args": {"segment_time": 15}},
|
||||||
|
"cameras": {
|
||||||
|
"back": {
|
||||||
|
"ffmpeg": {
|
||||||
|
"inputs": [
|
||||||
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"detect": {
|
||||||
|
"height": 1080,
|
||||||
|
"width": 1920,
|
||||||
|
"fps": 5,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
frigate_config = FrigateConfig(**config)
|
||||||
|
assert frigate_config.cameras["back"].ffmpeg.output_args.segment_time == 15
|
||||||
|
|
||||||
|
def test_override_segment_length(self):
|
||||||
|
config = {
|
||||||
|
"mqtt": {"host": "mqtt"},
|
||||||
|
"ffmpeg": {"output_args": {"segment_time": 15}},
|
||||||
|
"cameras": {
|
||||||
|
"back": {
|
||||||
|
"ffmpeg": {
|
||||||
|
"inputs": [
|
||||||
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
||||||
|
],
|
||||||
|
"output_args": {"segment_time": 25}
|
||||||
|
},
|
||||||
|
"detect": {
|
||||||
|
"height": 1080,
|
||||||
|
"width": 1920,
|
||||||
|
"fps": 5,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
frigate_config = FrigateConfig(**config)
|
||||||
|
assert frigate_config.cameras["back"].ffmpeg.output_args.segment_time == 25
|
||||||
|
|
||||||
def test_inherit_tracked_objects(self):
|
def test_inherit_tracked_objects(self):
|
||||||
config = {
|
config = {
|
||||||
"mqtt": {"host": "mqtt"},
|
"mqtt": {"host": "mqtt"},
|
||||||
|
|||||||
@ -158,6 +158,9 @@
|
|||||||
},
|
},
|
||||||
"record": {
|
"record": {
|
||||||
"label": "Record role FFmpeg output arguments."
|
"label": "Record role FFmpeg output arguments."
|
||||||
|
},
|
||||||
|
"segment_time": {
|
||||||
|
"label": "Segment length for recording stream."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -21,6 +21,9 @@
|
|||||||
},
|
},
|
||||||
"record": {
|
"record": {
|
||||||
"label": "Record role FFmpeg output arguments."
|
"label": "Record role FFmpeg output arguments."
|
||||||
|
},
|
||||||
|
"segment_time": {
|
||||||
|
"label": "Segment length for recording stream."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -87,6 +87,7 @@ export interface CameraConfig {
|
|||||||
detect: string[];
|
detect: string[];
|
||||||
record: string;
|
record: string;
|
||||||
rtmp: string;
|
rtmp: string;
|
||||||
|
segment_time: number;
|
||||||
};
|
};
|
||||||
retry_interval: number;
|
retry_interval: number;
|
||||||
};
|
};
|
||||||
@ -418,6 +419,7 @@ export interface FrigateConfig {
|
|||||||
detect: string[];
|
detect: string[];
|
||||||
record: string;
|
record: string;
|
||||||
rtmp: string;
|
rtmp: string;
|
||||||
|
segment_time: number;
|
||||||
};
|
};
|
||||||
retry_interval: number;
|
retry_interval: number;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user