forked from Github/frigate
Rework audio encoding for restream (#5092)
* Use memo for recordings timezone * Add audio encoding field and simplify stream creation * Update docs and tests * Fix bad logic
This commit is contained in:
@@ -524,16 +524,26 @@ class JsmpegStreamConfig(FrigateBaseModel):
|
||||
quality: int = Field(default=8, ge=1, le=31, title="Live camera view quality.")
|
||||
|
||||
|
||||
class RestreamCodecEnum(str, Enum):
|
||||
class RestreamVideoCodecEnum(str, Enum):
|
||||
copy = "copy"
|
||||
h264 = "h264"
|
||||
h265 = "h265"
|
||||
|
||||
|
||||
class RestreamAudioCodecEnum(str, Enum):
|
||||
aac = "aac"
|
||||
copy = "copy"
|
||||
opus = "opus"
|
||||
|
||||
|
||||
class RestreamConfig(FrigateBaseModel):
|
||||
enabled: bool = Field(default=True, title="Restreaming enabled.")
|
||||
video_encoding: RestreamCodecEnum = Field(
|
||||
default=RestreamCodecEnum.copy, title="Method for encoding the restream."
|
||||
audio_encoding: list[RestreamAudioCodecEnum] = Field(
|
||||
default=[RestreamAudioCodecEnum.aac, RestreamAudioCodecEnum.opus],
|
||||
title="Codecs to supply for audio.",
|
||||
)
|
||||
video_encoding: RestreamVideoCodecEnum = Field(
|
||||
default=RestreamVideoCodecEnum.copy, title="Method for encoding the restream."
|
||||
)
|
||||
force_audio: bool = Field(
|
||||
default=True, title="Force audio compatibility with the browser."
|
||||
|
||||
@@ -6,7 +6,7 @@ import requests
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from frigate.config import FrigateConfig, RestreamCodecEnum
|
||||
from frigate.config import FrigateConfig, RestreamAudioCodecEnum, RestreamVideoCodecEnum
|
||||
from frigate.const import BIRDSEYE_PIPE
|
||||
from frigate.ffmpeg_presets import (
|
||||
parse_preset_hardware_acceleration_encode,
|
||||
@@ -18,18 +18,26 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_manual_go2rtc_stream(
|
||||
camera_url: str, codec: RestreamCodecEnum, engine: Optional[str]
|
||||
camera_url: str,
|
||||
aCodecs: list[RestreamAudioCodecEnum],
|
||||
vCodec: RestreamVideoCodecEnum,
|
||||
engine: Optional[str],
|
||||
) -> str:
|
||||
"""Get a manual stream for go2rtc."""
|
||||
if codec == RestreamCodecEnum.copy:
|
||||
return f"ffmpeg:{camera_url}#video=copy#audio=aac#audio=opus"
|
||||
stream = f"ffmpeg:{camera_url}"
|
||||
|
||||
if engine:
|
||||
return (
|
||||
f"ffmpeg:{camera_url}#video={codec}#hardware={engine}#audio=aac#audio=opus"
|
||||
)
|
||||
for aCodec in aCodecs:
|
||||
stream += f"#audio={aCodec}"
|
||||
|
||||
return f"ffmpeg:{camera_url}#video={codec}#audio=aac#audio=opus"
|
||||
if vCodec == RestreamVideoCodecEnum.copy:
|
||||
stream += "#video=copy"
|
||||
else:
|
||||
stream += f"#video={vCodec}"
|
||||
|
||||
if engine:
|
||||
stream += f"#hardware={engine}"
|
||||
|
||||
return stream
|
||||
|
||||
|
||||
class RestreamApi:
|
||||
@@ -50,7 +58,10 @@ class RestreamApi:
|
||||
if "restream" in input.roles:
|
||||
if (
|
||||
input.path.startswith("rtsp")
|
||||
and not camera.restream.force_audio
|
||||
and camera.restream.video_encoding
|
||||
== RestreamVideoCodecEnum.copy
|
||||
and camera.restream.audio_encoding
|
||||
== [RestreamAudioCodecEnum.copy]
|
||||
):
|
||||
self.relays[
|
||||
cam_name
|
||||
@@ -59,6 +70,7 @@ class RestreamApi:
|
||||
# go2rtc only supports rtsp for direct relay, otherwise ffmpeg is used
|
||||
self.relays[cam_name] = get_manual_go2rtc_stream(
|
||||
escape_special_characters(input.path),
|
||||
camera.restream.audio_encoding,
|
||||
camera.restream.video_encoding,
|
||||
parse_preset_hardware_acceleration_go2rtc_engine(
|
||||
self.config.ffmpeg.hwaccel_args
|
||||
|
||||
@@ -25,7 +25,7 @@ class TestRestream(TestCase):
|
||||
},
|
||||
"restream": {
|
||||
"enabled": True,
|
||||
"force_audio": False,
|
||||
"audio_encoding": ["copy"],
|
||||
},
|
||||
},
|
||||
"front": {
|
||||
|
||||
Reference in New Issue
Block a user