diff --git a/Dockerfile b/Dockerfile index b1a5ba1a0..1ddf7d2b1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,7 +27,7 @@ RUN --mount=type=tmpfs,target=/tmp --mount=type=tmpfs,target=/var/cache/apt \ FROM wget AS go2rtc ARG TARGETARCH WORKDIR /rootfs/usr/local/go2rtc/bin -RUN wget -qO go2rtc "https://github.com/AlexxIT/go2rtc/releases/download/v1.0.0/go2rtc_linux_${TARGETARCH}" \ +RUN wget -qO go2rtc "https://github.com/AlexxIT/go2rtc/releases/download/v1.0.1/go2rtc_linux_${TARGETARCH}" \ && chmod +x go2rtc diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run index ae5d7ee60..62fbe33ad 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run @@ -10,7 +10,7 @@ s6-svc -O . function get_ip_and_port_from_supervisor() { local ip_address # Example: 192.168.1.10/24 - local ip_regex='^([0-9]{1,3}\.{3}[0-9]{1,3})/[0-9]{1,2}$' + local ip_regex='^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})/[0-9]{1,2}$' if ip_address=$( curl -fsSL \ -H "Authorization: Bearer ${SUPERVISOR_TOKEN}" \ @@ -32,7 +32,7 @@ function get_ip_and_port_from_supervisor() { -H "Authorization: Bearer ${SUPERVISOR_TOKEN}" \ -H "Content-Type: application/json" \ http://supervisor/addons/self/info | - jq --exit-status --raw-output '.data.network["22/tcp"]' + jq --exit-status --raw-output '.data.network["8555/tcp"]' ) && [[ "${webrtc_port}" =~ ${port_regex} ]]; then webrtc_port="${BASH_REMATCH[1]}" echo "[INFO] Got WebRTC port from supervisor: ${ip_address}" >&2 diff --git a/docker/rootfs/usr/local/go2rtc/create_config.py b/docker/rootfs/usr/local/go2rtc/create_config.py index 4ba2cfbf6..624415633 100644 --- a/docker/rootfs/usr/local/go2rtc/create_config.py +++ b/docker/rootfs/usr/local/go2rtc/create_config.py @@ -2,6 +2,7 @@ import json import os +import sys import yaml @@ -40,6 +41,8 @@ if not go2rtc_config.get("webrtc", {}).get("candidates", []): default_candidates.append("stun:8555") go2rtc_config["webrtc"] = {"candidates": default_candidates} +else: + print("[INFO] Not injecting WebRTC candidates into go2rtc config as it has been set manually", file=sys.stderr) # need to replace ffmpeg command when using ffmpeg4 if not os.path.exists(BTBN_PATH): diff --git a/docs/docs/configuration/camera_specific.md b/docs/docs/configuration/camera_specific.md index 5069d712e..d61d5cbd9 100644 --- a/docs/docs/configuration/camera_specific.md +++ b/docs/docs/configuration/camera_specific.md @@ -108,8 +108,11 @@ According to [this discussion](https://github.com/blakeblackshear/frigate/issues ```yaml go2rtc: streams: - reolink: ffmpeg:http://reolink_ip/flv?port=1935&app=bcs&stream=channel0_main.bcs&user=username&password=password#video=copy#audio=copy#audio=opus - reolink_sub: ffmpeg:http://reolink_ip/flv?port=1935&app=bcs&stream=channel0_ext.bcs&user=username&password=password + reolink: + - http://reolink_ip/flv?port=1935&app=bcs&stream=channel0_main.bcs&user=username&password=password + - ffmpeg:reolink#audio=opus + reolink_sub: + - http://reolink_ip/flv?port=1935&app=bcs&stream=channel0_ext.bcs&user=username&password=password cameras: reolink: @@ -119,7 +122,7 @@ cameras: input_args: preset-rtsp-restream roles: - record - - path: rtsp://127.0.0.1:8554/reolink?video=copy + - path: rtsp://127.0.0.1:8554/reolink_sub?video=copy input_args: preset-rtsp-restream roles: - detect diff --git a/docs/docs/configuration/index.md b/docs/docs/configuration/index.md index f3cc880e3..b33ebd40c 100644 --- a/docs/docs/configuration/index.md +++ b/docs/docs/configuration/index.md @@ -355,7 +355,7 @@ rtmp: enabled: False # Optional: Restream configuration -# Uses https://github.com/AlexxIT/go2rtc (v1.0.0) +# Uses https://github.com/AlexxIT/go2rtc (v1.0.1) go2rtc: # Optional: jsmpeg stream configuration for WebUI @@ -491,4 +491,10 @@ ui: timezone: None # Optional: Use an experimental recordings / camera view UI (default: shown below) experimental_ui: False + +# Optional: Telemetry configuration +telemetry: + # Optional: Enable the latest version outbound check (default: shown below) + # NOTE: If you use the HomeAssistant integration, disabling this will prevent it from reporting new versions + version_check: True ``` diff --git a/docs/docs/configuration/restream.md b/docs/docs/configuration/restream.md index 09967ea8b..9f7e54eb4 100644 --- a/docs/docs/configuration/restream.md +++ b/docs/docs/configuration/restream.md @@ -31,8 +31,9 @@ go2rtc: rtsp_cam: # <- for RTSP streams - rtsp://192.168.1.5:554/live0 # <- stream which supports video & aac audio - ffmpeg:rtsp_cam#audio=opus # <- copy of the stream which transcodes audio to the missing codec (usually will be opus) - http_cam: # <- for http streams - - "ffmpeg:http://192.168.50.155/flv?port=1935&app=bcs&stream=channel0_main.bcs&user=user&password=password#video=copy#audio=copy#audio=opus" # <- http streams must use ffmpeg to set all types + http_cam: # <- for other streams + - http://192.168.50.155/flv?port=1935&app=bcs&stream=channel0_main.bcs&user=user&password=password # <- stream which supports video & aac audio + - ffmpeg:http_cam#audio=opus # <- copy of the stream which transcodes audio to the missing codec (usually will be opus) cameras: rtsp_cam: @@ -71,9 +72,11 @@ go2rtc: - rtsp://192.168.1.5:554/substream # <- stream which supports video & aac audio. This is only supported for rtsp streams, http must use ffmpeg - ffmpeg:rtsp_cam_sub#audio=opus # <- copy of the stream which transcodes audio to opus http_cam: - - "ffmpeg:http://192.168.50.155/flv?port=1935&app=bcs&stream=channel0_main.bcs&user=user&password=password#video=copy#audio=copy#audio=opus" # <- http streams must use ffmpeg to set all types + - http://192.168.50.155/flv?port=1935&app=bcs&stream=channel0_main.bcs&user=user&password=password # <- stream which supports video & aac audio. This is only supported for rtsp streams, http must use ffmpeg + - ffmpeg:http_cam#audio=opus # <- copy of the stream which transcodes audio to opus http_cam_sub: - - "ffmpeg:http://192.168.50.155/flv?port=1935&app=bcs&stream=channel0_ext.bcs&user=user&password=password#video=copy#audio=copy#audio=opus" # <- http streams must use ffmpeg to set all types + - http://192.168.50.155/flv?port=1935&app=bcs&stream=channel0_ext.bcs&user=user&password=password # <- stream which supports video & aac audio. This is only supported for rtsp streams, http must use ffmpeg + - ffmpeg:http_cam_sub#audio=opus # <- copy of the stream which transcodes audio to opus cameras: rtsp_cam: @@ -115,3 +118,15 @@ go2rtc: streams: stream1: exec:ffmpeg -hide_banner -re -stream_loop -1 -i /media/BigBuckBunny.mp4 -c copy -rtsp_transport tcp -f rtsp {{output}} ``` + +## Go2rtc Exec + +Go2rtc offers the ability to [run a full command with exec](https://github.com/AlexxIT/go2rtc#source-exec) and calls for `{output}` at the end of the stream. Due to frigate's handling of templates, the output will need to be passed as `{{output}}`. + +ex: + +```yaml +go2rtc: + streams: + test: exec:ffmpeg -hide_banner -re -stream_loop -1 -i /media/BigBuckBunny.mp4 -c copy -rtsp_transport tcp -f rtsp {{output}} +``` diff --git a/frigate/app.py b/frigate/app.py index 6c3aaf3ed..4080ffbf4 100644 --- a/frigate/app.py +++ b/frigate/app.py @@ -155,7 +155,9 @@ class FrigateApp: self.db.bind(models) def init_stats(self) -> None: - self.stats_tracking = stats_init(self.camera_metrics, self.detectors) + self.stats_tracking = stats_init( + self.config, self.camera_metrics, self.detectors + ) def init_web_server(self) -> None: self.flask_app = create_app( diff --git a/frigate/config.py b/frigate/config.py index a343676f4..62578e1af 100644 --- a/frigate/config.py +++ b/frigate/config.py @@ -74,6 +74,10 @@ class UIConfig(FrigateBaseModel): use_experimental: bool = Field(default=False, title="Experimental UI") +class TelemetryConfig(FrigateBaseModel): + version_check: bool = Field(default=True, title="Enable latest version check.") + + class MqttConfig(FrigateBaseModel): enabled: bool = Field(title="Enable MQTT Communication.", default=True) host: str = Field(default="", title="MQTT Host") @@ -816,6 +820,9 @@ class FrigateConfig(FrigateBaseModel): default_factory=dict, title="Frigate environment variables." ) ui: UIConfig = Field(default_factory=UIConfig, title="UI configuration.") + telemetry: TelemetryConfig = Field( + default_factory=TelemetryConfig, title="Telemetry configuration." + ) model: ModelConfig = Field( default_factory=ModelConfig, title="Detection model configuration." ) diff --git a/frigate/ffmpeg_presets.py b/frigate/ffmpeg_presets.py index 57bd9b9f5..b708b55a1 100644 --- a/frigate/ffmpeg_presets.py +++ b/frigate/ffmpeg_presets.py @@ -82,14 +82,14 @@ PRESETS_HW_ACCEL_DECODE = { } PRESETS_HW_ACCEL_SCALE = { - "preset-rpi-32-h264": "-r {} -s {}x{} -f rawvideo -pix_fmt yuv420p", - "preset-rpi-64-h264": "-r {} -s {}x{} -f rawvideo -pix_fmt yuv420p", - "preset-vaapi": "-vf fps={},scale_vaapi=w={}:h={},hwdownload,format=yuv420p -f rawvideo", - "preset-intel-qsv-h264": "-r {} -vf vpp_qsv=w={}:h={}:format=nv12,hwdownload,format=nv12,format=yuv420p -f rawvideo", - "preset-intel-qsv-h265": "-r {} -vf vpp_qsv=w={}:h={}:format=nv12,hwdownload,format=nv12,format=yuv420p -f rawvideo", - "preset-nvidia-h264": "-vf fps={},scale_cuda=w={}:h={}:format=nv12,hwdownload,format=nv12,format=yuv420p -f rawvideo", - "preset-nvidia-h265": "-vf fps={},scale_cuda=w={}:h={}:format=nv12,hwdownload,format=nv12,format=yuv420p -f rawvideo", - "default": "-r {} -s {}x{}", + "preset-rpi-32-h264": "-r {0} -s {1}x{2} -f rawvideo -pix_fmt yuv420p", + "preset-rpi-64-h264": "-r {0} -s {1}x{2} -f rawvideo -pix_fmt yuv420p", + "preset-vaapi": "-r {0} -vf fps={0},scale_vaapi=w={1}:h={2},hwdownload,format=yuv420p -f rawvideo", + "preset-intel-qsv-h264": "-r {0} -vf vpp_qsv=framerate={0}:w={1}:h={2}:format=nv12,hwdownload,format=nv12,format=yuv420p -f rawvideo", + "preset-intel-qsv-h265": "-r {0} -vf vpp_qsv=framerate={0}:w={1}:h={2}:format=nv12,hwdownload,format=nv12,format=yuv420p -f rawvideo", + "preset-nvidia-h264": "-r {0} -vf fps={0},scale_cuda=w={1}:h={2}:format=nv12,hwdownload,format=nv12,format=yuv420p -f rawvideo", + "preset-nvidia-h265": "-r {0} -vf fps={0},scale_cuda=w={1}:h={2}:format=nv12,hwdownload,format=nv12,format=yuv420p -f rawvideo", + "default": "-r {0} -s {1}x{2}", } PRESETS_HW_ACCEL_ENCODE = { @@ -236,6 +236,10 @@ PRESETS_INPUT = { "tcp", TIMEOUT_PARAM, "5000000", + "-fflags", + "nobuffer", + "-flags", + "low_delay", ], "preset-rtsp-udp": _user_agent_args + [ diff --git a/frigate/stats.py b/frigate/stats.py index b67c2109b..0e23fb94e 100644 --- a/frigate/stats.py +++ b/frigate/stats.py @@ -22,7 +22,11 @@ from frigate.object_detection import ObjectDetectProcess logger = logging.getLogger(__name__) -def get_latest_version() -> str: +def get_latest_version(config: FrigateConfig) -> str: + + if not config.telemetry.version_check: + return "disabled" + try: request = requests.get( "https://api.github.com/repos/blakeblackshear/frigate/releases/latest", @@ -40,6 +44,7 @@ def get_latest_version() -> str: def stats_init( + config: FrigateConfig, camera_metrics: dict[str, CameraMetricsTypes], detectors: dict[str, ObjectDetectProcess], ) -> StatsTrackingTypes: @@ -47,7 +52,7 @@ def stats_init( "camera_metrics": camera_metrics, "detectors": detectors, "started": int(time.time()), - "latest_frigate_version": get_latest_version(), + "latest_frigate_version": get_latest_version(config), } return stats_tracking diff --git a/frigate/util.py b/frigate/util.py index 2987099e8..69ead2a7a 100755 --- a/frigate/util.py +++ b/frigate/util.py @@ -628,8 +628,13 @@ def clipped(obj, frame_shape): def restart_frigate(): - # S6 overlay is configured to exit once the Frigate process exits - os.kill(os.getpid(), signal.SIGTERM) + proc = psutil.Process(1) + # if this is running via s6, sigterm pid 1 + if proc.name() == "s6-svscan": + proc.terminate() + # otherwise, just try and exit frigate + else: + os.kill(os.getpid(), signal.SIGTERM) class EventsPerSecond: