mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-12-23 19:11:14 +01:00
d8123d2497
* Pull go2rtc dependency * Add go2rtc to local services and add to s6 * Add relay controller for go2rtc * Add restream role * Add restream role * Add restream to nginx * Add camera live source config * Disable RTMP by default and use restream * Use go2rtc for camera config * Fix go2rtc move * Start restream on frigate start * Send restream to camera level * Fix restream * Make sure jsmpeg works as expected * Make view rspect live size config * Tweak player options to fit live view * Adjust VideoPlayer to accept live option which disables irrelevant controls * Add multiple options from restream live view * Add base for webrtc option * Setup specific restream modules * Make mp4 the default streaming for now * Expose 8554 for rtsp relay from go2rtc * Formatting * Update docs to suggest new restream method. * Update docs to reflect restream role * Update docs to reflect restream role * Add webrtc player * Improvements to webRTC * Support webrtc * Cleanup * Adjust rtmp test and add restream test * Fix tests * Add restream tests * Add live view docs and show different options * Small docs tweak * Support all stream types * Update to beta 9 of go2rtc * Formatting * Make jsmpeg the default * Support wss if made from https * Support wss if made from https * Use onEffect * Set url outside onEffect * Fix passed deps * Update docs about required host mode * Try memo instead * Close websocket on changing camera * Formatting * Close pc connection * Set video source to null on cleanup * Use full path since go2rtc can't see PATH var * Adjust audio codec to enable browser audio by default * Cleanup stream creation * Add restream tests * Format tests * Mock requests * Adjust paths * Move stream configs to restream * Remove live source * Remove live config * Use live persistence for which view to use on each camera * Fix live sizes * Only use jsmpeg sizes for jsmpeg live * Set max live size * Remove access of live config * Add selector for live view source in web view * Remove RTMP from default list of roles * Update docs * Fix tests * Fix docs for live view modes * make default undefined to avoid race condition * Wait until camera source is loaded to avoid race condition * Fix tests * Add config to go2rtc * Work with config * Set full path for config * Set to use stun * Check for mounted file * Look for frigate-go2rtc * Update docs to reflect webRTC configuration. * Add link to go2rtc config * Update docs to be more clear * Update docs to be more clear * Update format Co-authored-by: Felipe Santos <felipecassiors@gmail.com> * Update live docs * Improve bash startup script * Add option to force audio compatibility * Formatting * Fix mapping * Fix broken link * Update go2rtc version * Get go2rtc webui working * Add support for mse * Remove mp4 option * Undo changes to video player * Update docs for new live view options * Make separate path for mse * Remove unused * Remove mp4 path * Try to get go2rtc proxy working * Try to get go2rtc proxy working * Remove unused callback * Allow websocket on restrea dashboard * Make mse default stream option * Fix mse sizing * don't assume roles is defined * Remove nginx mapping to go2rtc ui Co-authored-by: Felipe Santos <felipecassiors@gmail.com> Co-authored-by: Blake Blackshear <blakeb@blakeshome.com>
1460 lines
48 KiB
Python
1460 lines
48 KiB
Python
import unittest
|
|
import numpy as np
|
|
from pydantic import ValidationError
|
|
from frigate.config import (
|
|
BirdseyeModeEnum,
|
|
FrigateConfig,
|
|
DetectorTypeEnum,
|
|
)
|
|
|
|
|
|
class TestConfig(unittest.TestCase):
|
|
def setUp(self):
|
|
self.minimal = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
|
|
def test_config_class(self):
|
|
frigate_config = FrigateConfig(**self.minimal)
|
|
assert self.minimal == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert "cpu" in runtime_config.detectors.keys()
|
|
assert runtime_config.detectors["cpu"].type == DetectorTypeEnum.cpu
|
|
|
|
def test_invalid_mqtt_config(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt", "user": "test"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
self.assertRaises(ValidationError, lambda: FrigateConfig(**config))
|
|
|
|
def test_inherit_tracked_objects(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"objects": {"track": ["person", "dog"]},
|
|
"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 config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert "dog" in runtime_config.cameras["back"].objects.track
|
|
|
|
def test_override_birdseye(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"birdseye": {"enabled": True, "mode": "continuous"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
"birdseye": {"enabled": False, "mode": "motion"},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert not runtime_config.cameras["back"].birdseye.enabled
|
|
assert runtime_config.cameras["back"].birdseye.mode is BirdseyeModeEnum.motion
|
|
|
|
def test_override_birdseye_non_inheritable(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"birdseye": {"enabled": True, "mode": "continuous", "height": 1920},
|
|
"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 config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.cameras["back"].birdseye.enabled
|
|
|
|
def test_inherit_birdseye(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"birdseye": {"enabled": True, "mode": "continuous"},
|
|
"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 config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.cameras["back"].birdseye.enabled
|
|
assert (
|
|
runtime_config.cameras["back"].birdseye.mode is BirdseyeModeEnum.continuous
|
|
)
|
|
|
|
def test_override_tracked_objects(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"objects": {"track": ["person", "dog"]},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
"objects": {"track": ["cat"]},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert "cat" in runtime_config.cameras["back"].objects.track
|
|
|
|
def test_default_object_filters(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"objects": {"track": ["person", "dog"]},
|
|
"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 config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert "dog" in runtime_config.cameras["back"].objects.filters
|
|
|
|
def test_inherit_object_filters(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"objects": {
|
|
"track": ["person", "dog"],
|
|
"filters": {"dog": {"threshold": 0.7}},
|
|
},
|
|
"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 config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert "dog" in runtime_config.cameras["back"].objects.filters
|
|
assert runtime_config.cameras["back"].objects.filters["dog"].threshold == 0.7
|
|
|
|
def test_override_object_filters(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,
|
|
},
|
|
"objects": {
|
|
"track": ["person", "dog"],
|
|
"filters": {"dog": {"threshold": 0.7}},
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert "dog" in runtime_config.cameras["back"].objects.filters
|
|
assert runtime_config.cameras["back"].objects.filters["dog"].threshold == 0.7
|
|
|
|
def test_global_object_mask(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"objects": {"track": ["person", "dog"]},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
"objects": {
|
|
"mask": "0,0,1,1,0,1",
|
|
"filters": {"dog": {"mask": "1,1,1,1,1,1"}},
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
back_camera = runtime_config.cameras["back"]
|
|
assert "dog" in back_camera.objects.filters
|
|
assert len(back_camera.objects.filters["dog"].raw_mask) == 2
|
|
assert len(back_camera.objects.filters["person"].raw_mask) == 1
|
|
|
|
def test_default_input_args(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 config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert "-rtsp_transport" in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
|
|
|
|
def test_ffmpeg_params_global(self):
|
|
config = {
|
|
"ffmpeg": {"input_args": "-re"},
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
"objects": {
|
|
"track": ["person", "dog"],
|
|
"filters": {"dog": {"threshold": 0.7}},
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert "-re" in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
|
|
|
|
def test_ffmpeg_params_camera(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"ffmpeg": {"input_args": ["test"]},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
],
|
|
"input_args": ["-re"],
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
"objects": {
|
|
"track": ["person", "dog"],
|
|
"filters": {"dog": {"threshold": 0.7}},
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert "-re" in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
|
|
assert "test" not in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
|
|
|
|
def test_ffmpeg_params_input(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"ffmpeg": {"input_args": ["test2"]},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
"input_args": "-re test",
|
|
}
|
|
],
|
|
"input_args": "test3",
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
"objects": {
|
|
"track": ["person", "dog"],
|
|
"filters": {"dog": {"threshold": 0.7}},
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert "-re" in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
|
|
assert "test" in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
|
|
assert "test2" not in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
|
|
assert "test3" not in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
|
|
|
|
def test_inherit_clips_retention(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"record": {
|
|
"events": {"retain": {"default": 20, "objects": {"person": 30}}}
|
|
},
|
|
"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 config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert (
|
|
runtime_config.cameras["back"].record.events.retain.objects["person"] == 30
|
|
)
|
|
|
|
def test_roles_listed_twice_throws_error(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"record": {
|
|
"events": {"retain": {"default": 20, "objects": {"person": 30}}}
|
|
},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]},
|
|
{"path": "rtsp://10.0.0.1:554/video2", "roles": ["detect"]},
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
self.assertRaises(ValidationError, lambda: FrigateConfig(**config))
|
|
|
|
def test_zone_matching_camera_name_throws_error(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"record": {
|
|
"events": {"retain": {"default": 20, "objects": {"person": 30}}}
|
|
},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
"zones": {"back": {"coordinates": "1,1,1,1,1,1"}},
|
|
}
|
|
},
|
|
}
|
|
self.assertRaises(ValidationError, lambda: FrigateConfig(**config))
|
|
|
|
def test_zone_assigns_color_and_contour(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"record": {
|
|
"events": {"retain": {"default": 20, "objects": {"person": 30}}}
|
|
},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
"zones": {"test": {"coordinates": "1,1,1,1,1,1"}},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert isinstance(
|
|
runtime_config.cameras["back"].zones["test"].contour, np.ndarray
|
|
)
|
|
assert runtime_config.cameras["back"].zones["test"].color != (0, 0, 0)
|
|
|
|
def test_clips_should_default_to_global_objects(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"record": {
|
|
"events": {"retain": {"default": 20, "objects": {"person": 30}}}
|
|
},
|
|
"objects": {"track": ["person", "dog"]},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
"record": {"events": {}},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
back_camera = runtime_config.cameras["back"]
|
|
assert back_camera.record.events.objects is None
|
|
assert back_camera.record.events.retain.objects["person"] == 30
|
|
|
|
def test_role_assigned_but_not_enabled(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect", "rtmp", "restream"],
|
|
},
|
|
{"path": "rtsp://10.0.0.1:554/record", "roles": ["record"]},
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
ffmpeg_cmds = runtime_config.cameras["back"].ffmpeg_cmds
|
|
assert len(ffmpeg_cmds) == 1
|
|
assert not "clips" in ffmpeg_cmds[0]["roles"]
|
|
|
|
def test_max_disappeared_default(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
"detect": {
|
|
"enabled": True,
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.cameras["back"].detect.max_disappeared == 5 * 5
|
|
|
|
def test_motion_frame_height_wont_go_below_120(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 config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.cameras["back"].motion.frame_height == 50
|
|
|
|
def test_motion_contour_area_dynamic(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 config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert round(runtime_config.cameras["back"].motion.contour_area) == 30
|
|
|
|
def test_merge_labelmap(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"model": {"labelmap": {7: "truck"}},
|
|
"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 config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.model.merged_labelmap[7] == "truck"
|
|
|
|
def test_default_labelmap_empty(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 config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.model.merged_labelmap[0] == "person"
|
|
|
|
def test_default_labelmap(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"model": {"width": 320, "height": 320},
|
|
"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 config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.model.merged_labelmap[0] == "person"
|
|
|
|
def test_fails_on_invalid_role(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video2",
|
|
"roles": ["clips"],
|
|
},
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
|
|
self.assertRaises(ValidationError, lambda: FrigateConfig(**config))
|
|
|
|
def test_fails_on_missing_role(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video2",
|
|
"roles": ["record"],
|
|
},
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
"rtmp": {"enabled": True},
|
|
}
|
|
},
|
|
}
|
|
|
|
frigate_config = FrigateConfig(**config)
|
|
self.assertRaises(ValueError, lambda: frigate_config.runtime_config)
|
|
|
|
def test_works_on_missing_role_multiple_cams(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"restream": {"enabled": False},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video2",
|
|
"roles": ["record"],
|
|
},
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
},
|
|
"cam2": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video2",
|
|
"roles": ["record"],
|
|
},
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
frigate_config = FrigateConfig(**config)
|
|
runtime_config = frigate_config.runtime_config
|
|
|
|
def test_global_detect(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"detect": {"max_disappeared": 1},
|
|
"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 config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.cameras["back"].detect.max_disappeared == 1
|
|
assert runtime_config.cameras["back"].detect.height == 1080
|
|
|
|
def test_default_detect(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
}
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.cameras["back"].detect.max_disappeared == 25
|
|
assert runtime_config.cameras["back"].detect.height == 720
|
|
|
|
def test_global_detect_merge(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"detect": {"max_disappeared": 1, "height": 720},
|
|
"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 config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.cameras["back"].detect.max_disappeared == 1
|
|
assert runtime_config.cameras["back"].detect.height == 1080
|
|
assert runtime_config.cameras["back"].detect.width == 1920
|
|
|
|
def test_global_snapshots(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"snapshots": {"enabled": True},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
"snapshots": {
|
|
"height": 100,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.cameras["back"].snapshots.enabled
|
|
assert runtime_config.cameras["back"].snapshots.height == 100
|
|
|
|
def test_default_snapshots(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
}
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.cameras["back"].snapshots.bounding_box
|
|
assert runtime_config.cameras["back"].snapshots.quality == 70
|
|
|
|
def test_global_snapshots_merge(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"snapshots": {"bounding_box": False, "height": 300},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
"snapshots": {
|
|
"height": 150,
|
|
"enabled": True,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.cameras["back"].snapshots.bounding_box == False
|
|
assert runtime_config.cameras["back"].snapshots.height == 150
|
|
assert runtime_config.cameras["back"].snapshots.enabled
|
|
|
|
def test_global_restream(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"restream": {"enabled": True},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.cameras["back"].restream.enabled
|
|
|
|
def test_global_rtmp_disabled(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert not runtime_config.cameras["back"].rtmp.enabled
|
|
|
|
def test_default_not_rtmp(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
}
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert not runtime_config.cameras["back"].rtmp.enabled
|
|
|
|
def test_default_restream(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
}
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.cameras["back"].restream.enabled
|
|
|
|
def test_global_restream_merge(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"restream": {"enabled": False},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
"restream": {
|
|
"enabled": True,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.cameras["back"].restream.enabled
|
|
|
|
def test_global_rtmp_merge(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"rtmp": {"enabled": False},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect", "rtmp"],
|
|
},
|
|
]
|
|
},
|
|
"rtmp": {
|
|
"enabled": True,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.cameras["back"].rtmp.enabled
|
|
|
|
def test_global_rtmp_default(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"restream": {"enabled": False},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video2",
|
|
"roles": ["record"],
|
|
},
|
|
]
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert not runtime_config.cameras["back"].rtmp.enabled
|
|
|
|
def test_global_jsmpeg(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"restream": {"jsmpeg": {"quality": 4}},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.cameras["back"].restream.jsmpeg.quality == 4
|
|
|
|
def test_default_live(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
}
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.cameras["back"].restream.jsmpeg.quality == 8
|
|
|
|
def test_global_live_merge(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"restream": {"jsmpeg": {"quality": 4, "height": 480}},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
"restream": {
|
|
"jsmpeg": {
|
|
"quality": 7,
|
|
}
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.cameras["back"].restream.jsmpeg.quality == 7
|
|
assert runtime_config.cameras["back"].restream.jsmpeg.height == 480
|
|
|
|
def test_global_timestamp_style(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"timestamp_style": {"position": "bl"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.cameras["back"].timestamp_style.position == "bl"
|
|
|
|
def test_default_timestamp_style(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
}
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.cameras["back"].timestamp_style.position == "tl"
|
|
|
|
def test_global_timestamp_style_merge(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"rtmp": {"enabled": False},
|
|
"timestamp_style": {"position": "br", "thickness": 2},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
"timestamp_style": {"position": "bl", "thickness": 4},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.cameras["back"].timestamp_style.position == "bl"
|
|
assert runtime_config.cameras["back"].timestamp_style.thickness == 4
|
|
|
|
def test_allow_retain_to_be_a_decimal(self):
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"snapshots": {"retain": {"default": 1.5}},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert runtime_config.cameras["back"].snapshots.retain.default == 1.5
|
|
|
|
def test_fails_on_bad_camera_name(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"snapshots": {"retain": {"default": 1.5}},
|
|
"cameras": {
|
|
"back camer#": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
}
|
|
},
|
|
}
|
|
|
|
frigate_config = FrigateConfig(**config)
|
|
|
|
self.assertRaises(
|
|
ValidationError, lambda: frigate_config.runtime_config.cameras
|
|
)
|
|
|
|
def test_object_filter_ratios_work(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"objects": {
|
|
"track": ["person", "dog"],
|
|
"filters": {"dog": {"min_ratio": 0.2, "max_ratio": 10.1}},
|
|
},
|
|
"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 config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config
|
|
assert "dog" in runtime_config.cameras["back"].objects.filters
|
|
assert runtime_config.cameras["back"].objects.filters["dog"].min_ratio == 0.2
|
|
assert runtime_config.cameras["back"].objects.filters["dog"].max_ratio == 10.1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main(verbosity=2)
|