Rewrite restream (#5106)

* Tear out restream config

* Rework birdseye restream

* Create go2rtc config handler

* Fix bug

* Write start script

* Rework style

* Fix python run syntax

* Output as json instead of yaml

* Put old live config back and fix birdseye references

* Fix camera webUI

* Add frigate env var subsitutions

* Fix webui checks

* Check keys

* Remove unused prest

* Fix tests

* Update restream docs

* Update restream docs

* Update live docs

* Update camera specific recommendation

* Update more docs

* add links for the docs

Co-authored-by: Felipe Santos <felipecassiors@gmail.com>

* Update note about supported audio codecs

* Move restream to go2rtc

* Docs fixes

* Add verification of stream name

* Ensure that webUI uses camera name

* Update docs to reflect new live stream name

* Fix check

* Formatting

* Remove audio from detect

Co-authored-by: Felipe Santos <felipecassiors@gmail.com>

* Fix docs

* Don't handle env variable substitution

* Add go2rtc version

* Clarify docs

Co-authored-by: Felipe Santos <felipecassiors@gmail.com>
This commit is contained in:
Nicolas Mowen
2023-01-16 16:50:35 -07:00
committed by GitHub
parent a7751f210b
commit 19afb035ff
17 changed files with 212 additions and 406 deletions

View File

@@ -621,7 +621,7 @@ class TestConfig(unittest.TestCase):
"inputs": [
{
"path": "rtsp://10.0.0.1:554/video",
"roles": ["detect", "rtmp", "restream"],
"roles": ["detect", "rtmp"],
},
{"path": "rtsp://10.0.0.1:554/record", "roles": ["record"]},
]
@@ -883,7 +883,6 @@ class TestConfig(unittest.TestCase):
config = {
"mqtt": {"host": "mqtt"},
"restream": {"enabled": False},
"cameras": {
"back": {
"ffmpeg": {
@@ -1096,30 +1095,6 @@ class TestConfig(unittest.TestCase):
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 = {
@@ -1166,56 +1141,6 @@ class TestConfig(unittest.TestCase):
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 = {
@@ -1247,7 +1172,6 @@ class TestConfig(unittest.TestCase):
config = {
"mqtt": {"host": "mqtt"},
"restream": {"enabled": False},
"cameras": {
"back": {
"ffmpeg": {
@@ -1275,7 +1199,7 @@ class TestConfig(unittest.TestCase):
config = {
"mqtt": {"host": "mqtt"},
"restream": {"jsmpeg": {"quality": 4}},
"live": {"quality": 4},
"cameras": {
"back": {
"ffmpeg": {
@@ -1293,7 +1217,7 @@ class TestConfig(unittest.TestCase):
assert config == frigate_config.dict(exclude_unset=True)
runtime_config = frigate_config.runtime_config
assert runtime_config.cameras["back"].restream.jsmpeg.quality == 4
assert runtime_config.cameras["back"].live.quality == 4
def test_default_live(self):
@@ -1316,13 +1240,13 @@ class TestConfig(unittest.TestCase):
assert config == frigate_config.dict(exclude_unset=True)
runtime_config = frigate_config.runtime_config
assert runtime_config.cameras["back"].restream.jsmpeg.quality == 8
assert runtime_config.cameras["back"].live.quality == 8
def test_global_live_merge(self):
config = {
"mqtt": {"host": "mqtt"},
"restream": {"jsmpeg": {"quality": 4, "height": 480}},
"live": {"quality": 4, "height": 480},
"cameras": {
"back": {
"ffmpeg": {
@@ -1333,10 +1257,8 @@ class TestConfig(unittest.TestCase):
},
]
},
"restream": {
"jsmpeg": {
"quality": 7,
}
"live": {
"quality": 7,
},
}
},
@@ -1345,8 +1267,8 @@ class TestConfig(unittest.TestCase):
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
assert runtime_config.cameras["back"].live.quality == 7
assert runtime_config.cameras["back"].live.height == 480
def test_global_timestamp_style(self):

View File

@@ -1,82 +0,0 @@
"""Test restream.py."""
from unittest import TestCase, main
from unittest.mock import patch
from frigate.config import FrigateConfig
from frigate.restream import RestreamApi
class TestRestream(TestCase):
def setUp(self) -> None:
"""Setup the tests."""
self.config = {
"mqtt": {"host": "mqtt"},
"restream": {"enabled": False},
"cameras": {
"back": {
"ffmpeg": {
"inputs": [
{
"path": "rtsp://10.0.0.1:554/video",
"roles": ["detect", "restream"],
},
]
},
"restream": {
"enabled": True,
"audio_encoding": ["copy"],
},
},
"front": {
"ffmpeg": {
"inputs": [
{
"path": "http://10.0.0.1:554/video/stream",
"roles": ["detect", "restream"],
},
]
},
"restream": {
"enabled": True,
},
},
},
}
@patch("frigate.restream.requests")
def test_rtsp_stream(
self, mock_request
) -> None: # need to ensure restream doesn't try to call API
"""Test that the normal rtsp stream is sent plainly."""
frigate_config = FrigateConfig(**self.config)
restream = RestreamApi(frigate_config)
restream.add_cameras()
assert restream.relays["back"].startswith("rtsp")
@patch("frigate.restream.requests")
def test_http_stream(
self, mock_request
) -> None: # need to ensure restream doesn't try to call API
"""Test that the http stream is sent via ffmpeg."""
frigate_config = FrigateConfig(**self.config)
restream = RestreamApi(frigate_config)
restream.add_cameras()
assert not restream.relays["front"].startswith("rtsp")
@patch("frigate.restream.requests")
def test_restream_codec_change(
self, mock_request
) -> None: # need to ensure restream doesn't try to call API
"""Test that the http stream is sent via ffmpeg."""
self.config["cameras"]["front"]["restream"]["video_encoding"] = "h265"
self.config["ffmpeg"] = {"hwaccel_args": "preset-nvidia-h264"}
frigate_config = FrigateConfig(**self.config)
restream = RestreamApi(frigate_config)
restream.add_cameras()
assert "#hardware=cuda" in restream.relays["front"]
assert "#video=h265" in restream.relays["front"]
if __name__ == "__main__":
main(verbosity=2)