2022-11-29 04:48:11 +01:00
|
|
|
import unittest
|
2023-05-29 12:31:17 +02:00
|
|
|
|
2022-11-30 23:53:45 +01:00
|
|
|
from frigate.config import FFMPEG_INPUT_ARGS_DEFAULT, FrigateConfig
|
2022-11-29 04:48:11 +01:00
|
|
|
from frigate.ffmpeg_presets import parse_preset_input
|
|
|
|
|
|
|
|
|
|
|
|
class TestFfmpegPresets(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
|
|
self.default_ffmpeg = {
|
|
|
|
"mqtt": {"host": "mqtt"},
|
|
|
|
"cameras": {
|
|
|
|
"back": {
|
|
|
|
"ffmpeg": {
|
|
|
|
"inputs": [
|
|
|
|
{
|
|
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
|
|
"roles": ["detect", "rtmp"],
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"output_args": {
|
|
|
|
"detect": "-f rawvideo -pix_fmt yuv420p",
|
|
|
|
"record": "-f segment -segment_time 10 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c copy -an",
|
|
|
|
"rtmp": "-c copy -f flv",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"detect": {
|
|
|
|
"height": 1080,
|
|
|
|
"width": 1920,
|
|
|
|
"fps": 5,
|
|
|
|
},
|
|
|
|
"record": {
|
|
|
|
"enabled": True,
|
|
|
|
},
|
|
|
|
"rtmp": {
|
|
|
|
"enabled": True,
|
|
|
|
},
|
|
|
|
"name": "back",
|
|
|
|
}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
def test_default_ffmpeg(self):
|
|
|
|
frigate_config = FrigateConfig(**self.default_ffmpeg)
|
|
|
|
frigate_config.cameras["back"].create_ffmpeg_cmds()
|
|
|
|
assert self.default_ffmpeg == frigate_config.dict(exclude_unset=True)
|
|
|
|
|
|
|
|
def test_ffmpeg_hwaccel_preset(self):
|
2024-03-30 11:44:44 +01:00
|
|
|
self.default_ffmpeg["cameras"]["back"]["ffmpeg"]["hwaccel_args"] = (
|
|
|
|
"preset-rpi-64-h264"
|
|
|
|
)
|
2022-11-29 04:48:11 +01:00
|
|
|
frigate_config = FrigateConfig(**self.default_ffmpeg)
|
|
|
|
frigate_config.cameras["back"].create_ffmpeg_cmds()
|
|
|
|
assert "preset-rpi-64-h264" not in (
|
|
|
|
" ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"])
|
|
|
|
)
|
2023-05-05 00:55:44 +02:00
|
|
|
assert "-c:v:1 h264_v4l2m2m" in (
|
2022-11-29 04:48:11 +01:00
|
|
|
" ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"])
|
|
|
|
)
|
|
|
|
|
|
|
|
def test_ffmpeg_hwaccel_not_preset(self):
|
2024-03-30 11:44:44 +01:00
|
|
|
self.default_ffmpeg["cameras"]["back"]["ffmpeg"]["hwaccel_args"] = (
|
|
|
|
"-other-hwaccel args"
|
|
|
|
)
|
2022-11-29 04:48:11 +01:00
|
|
|
frigate_config = FrigateConfig(**self.default_ffmpeg)
|
|
|
|
frigate_config.cameras["back"].create_ffmpeg_cmds()
|
|
|
|
assert "-other-hwaccel args" in (
|
|
|
|
" ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"])
|
|
|
|
)
|
|
|
|
|
2022-12-30 17:56:52 +01:00
|
|
|
def test_ffmpeg_hwaccel_scale_preset(self):
|
2024-03-30 11:44:44 +01:00
|
|
|
self.default_ffmpeg["cameras"]["back"]["ffmpeg"]["hwaccel_args"] = (
|
|
|
|
"preset-nvidia-h264"
|
|
|
|
)
|
2022-12-30 17:56:52 +01:00
|
|
|
self.default_ffmpeg["cameras"]["back"]["detect"] = {
|
|
|
|
"height": 1920,
|
|
|
|
"width": 2560,
|
|
|
|
"fps": 10,
|
|
|
|
}
|
|
|
|
frigate_config = FrigateConfig(**self.default_ffmpeg)
|
|
|
|
frigate_config.cameras["back"].create_ffmpeg_cmds()
|
|
|
|
assert "preset-nvidia-h264" not in (
|
|
|
|
" ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"])
|
|
|
|
)
|
|
|
|
assert (
|
|
|
|
"fps=10,scale_cuda=w=2560:h=1920:format=nv12,hwdownload,format=nv12,format=yuv420p"
|
|
|
|
in (" ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"]))
|
|
|
|
)
|
|
|
|
|
2022-11-29 04:48:11 +01:00
|
|
|
def test_default_ffmpeg_input_arg_preset(self):
|
|
|
|
frigate_config = FrigateConfig(**self.default_ffmpeg)
|
|
|
|
|
2024-03-30 11:44:44 +01:00
|
|
|
self.default_ffmpeg["cameras"]["back"]["ffmpeg"]["input_args"] = (
|
|
|
|
"preset-rtsp-generic"
|
|
|
|
)
|
2022-11-29 04:48:11 +01:00
|
|
|
frigate_preset_config = FrigateConfig(**self.default_ffmpeg)
|
|
|
|
frigate_config.cameras["back"].create_ffmpeg_cmds()
|
|
|
|
frigate_preset_config.cameras["back"].create_ffmpeg_cmds()
|
|
|
|
assert (
|
2022-12-04 16:46:03 +01:00
|
|
|
# Ignore global and user_agent args in comparison
|
2022-12-16 14:41:03 +01:00
|
|
|
frigate_preset_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
|
|
|
|
== frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
|
2022-11-29 04:48:11 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
def test_ffmpeg_input_preset(self):
|
2024-03-30 11:44:44 +01:00
|
|
|
self.default_ffmpeg["cameras"]["back"]["ffmpeg"]["input_args"] = (
|
|
|
|
"preset-rtmp-generic"
|
|
|
|
)
|
2022-11-29 04:48:11 +01:00
|
|
|
frigate_config = FrigateConfig(**self.default_ffmpeg)
|
|
|
|
frigate_config.cameras["back"].create_ffmpeg_cmds()
|
|
|
|
assert "preset-rtmp-generic" not in (
|
|
|
|
" ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"])
|
|
|
|
)
|
|
|
|
assert (" ".join(parse_preset_input("preset-rtmp-generic", 5))) in (
|
|
|
|
" ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"])
|
|
|
|
)
|
|
|
|
|
2022-11-30 23:53:45 +01:00
|
|
|
def test_ffmpeg_input_args_as_string(self):
|
2022-12-16 14:41:03 +01:00
|
|
|
# Strip user_agent args here to avoid handling quoting issues
|
|
|
|
defaultArgsList = parse_preset_input(FFMPEG_INPUT_ARGS_DEFAULT, 5)[2::]
|
|
|
|
argsString = " ".join(defaultArgsList) + ' -some "arg with space"'
|
|
|
|
argsList = defaultArgsList + ["-some", "arg with space"]
|
2022-11-30 23:53:45 +01:00
|
|
|
self.default_ffmpeg["cameras"]["back"]["ffmpeg"]["input_args"] = argsString
|
|
|
|
frigate_config = FrigateConfig(**self.default_ffmpeg)
|
|
|
|
frigate_config.cameras["back"].create_ffmpeg_cmds()
|
|
|
|
assert set(argsList).issubset(
|
|
|
|
frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
|
|
|
|
)
|
|
|
|
|
2022-11-29 04:48:11 +01:00
|
|
|
def test_ffmpeg_input_not_preset(self):
|
|
|
|
self.default_ffmpeg["cameras"]["back"]["ffmpeg"]["input_args"] = "-some inputs"
|
|
|
|
frigate_config = FrigateConfig(**self.default_ffmpeg)
|
|
|
|
frigate_config.cameras["back"].create_ffmpeg_cmds()
|
|
|
|
assert "-some inputs" in (
|
|
|
|
" ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"])
|
|
|
|
)
|
|
|
|
|
|
|
|
def test_ffmpeg_output_record_preset(self):
|
2024-03-30 11:44:44 +01:00
|
|
|
self.default_ffmpeg["cameras"]["back"]["ffmpeg"]["output_args"]["record"] = (
|
|
|
|
"preset-record-generic-audio-aac"
|
|
|
|
)
|
2022-11-29 04:48:11 +01:00
|
|
|
frigate_config = FrigateConfig(**self.default_ffmpeg)
|
|
|
|
frigate_config.cameras["back"].create_ffmpeg_cmds()
|
2023-01-15 16:40:42 +01:00
|
|
|
assert "preset-record-generic-audio-aac" not in (
|
2022-11-29 04:48:11 +01:00
|
|
|
" ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"])
|
|
|
|
)
|
|
|
|
assert "-c:v copy -c:a aac" in (
|
|
|
|
" ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"])
|
|
|
|
)
|
|
|
|
|
|
|
|
def test_ffmpeg_output_record_not_preset(self):
|
2024-03-30 11:44:44 +01:00
|
|
|
self.default_ffmpeg["cameras"]["back"]["ffmpeg"]["output_args"]["record"] = (
|
|
|
|
"-some output"
|
|
|
|
)
|
2022-11-29 04:48:11 +01:00
|
|
|
frigate_config = FrigateConfig(**self.default_ffmpeg)
|
|
|
|
frigate_config.cameras["back"].create_ffmpeg_cmds()
|
|
|
|
assert "-some output" in (
|
|
|
|
" ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"])
|
|
|
|
)
|
|
|
|
|
|
|
|
def test_ffmpeg_output_rtmp_preset(self):
|
2024-03-30 11:44:44 +01:00
|
|
|
self.default_ffmpeg["cameras"]["back"]["ffmpeg"]["output_args"]["rtmp"] = (
|
|
|
|
"preset-rtmp-jpeg"
|
|
|
|
)
|
2022-11-29 04:48:11 +01:00
|
|
|
frigate_config = FrigateConfig(**self.default_ffmpeg)
|
|
|
|
frigate_config.cameras["back"].create_ffmpeg_cmds()
|
|
|
|
assert "preset-rtmp-jpeg" not in (
|
|
|
|
" ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"])
|
|
|
|
)
|
|
|
|
assert "-c:v libx264" in (
|
|
|
|
" ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"])
|
|
|
|
)
|
|
|
|
|
|
|
|
def test_ffmpeg_output_rtmp_not_preset(self):
|
2024-03-30 11:44:44 +01:00
|
|
|
self.default_ffmpeg["cameras"]["back"]["ffmpeg"]["output_args"]["rtmp"] = (
|
|
|
|
"-some output"
|
|
|
|
)
|
2022-11-29 04:48:11 +01:00
|
|
|
frigate_config = FrigateConfig(**self.default_ffmpeg)
|
|
|
|
frigate_config.cameras["back"].create_ffmpeg_cmds()
|
|
|
|
assert "-some output" in (
|
|
|
|
" ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"])
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
unittest.main(verbosity=2)
|