diff --git a/docker/install_deps.sh b/docker/install_deps.sh index 9ba7c3c68..422752292 100755 --- a/docker/install_deps.sh +++ b/docker/install_deps.sh @@ -10,7 +10,9 @@ apt-get -qq install --no-install-recommends -y \ wget \ procps vainfo \ unzip locales tzdata libxml2 xz-utils \ - python3-pip + python3-pip \ + curl \ + jq mkdir -p -m 600 /root/.gnupg diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/run index 905f4b670..1adf1a0cb 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/run +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/run @@ -7,7 +7,9 @@ set -o errexit -o nounset -o pipefail # Tell S6-Overlay not to restart this service s6-svc -O . -cd /opt/frigate +echo "[INFO] Starting Frigate..." >&2 + +cd /opt/frigate || echo "[ERROR] Failed to change working directory to /opt/frigate" >&2 # Replace the bash process with the Frigate process, redirecting stderr to stdout exec 2>&1 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 aa753bd12..ae5d7ee60 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run @@ -7,8 +7,54 @@ set -o errexit -o nounset -o pipefail # Tell S6-Overlay not to restart this service 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}$' + if ip_address=$( + curl -fsSL \ + -H "Authorization: Bearer ${SUPERVISOR_TOKEN}" \ + -H "Content-Type: application/json" \ + http://supervisor/network/interface/default/info | + jq --exit-status --raw-output '.data.ipv4.address[0]' + ) && [[ "${ip_address}" =~ ${ip_regex} ]]; then + ip_address="${BASH_REMATCH[1]}" + echo "[INFO] Got IP address from supervisor: ${ip_address}" >&2 + else + echo "[WARN] Failed to get IP address from supervisor" >&2 + return 0 + fi + + local webrtc_port + local port_regex='^([0-9]{1,5})$' + if webrtc_port=$( + curl -fsSL \ + -H "Authorization: Bearer ${SUPERVISOR_TOKEN}" \ + -H "Content-Type: application/json" \ + http://supervisor/addons/self/info | + jq --exit-status --raw-output '.data.network["22/tcp"]' + ) && [[ "${webrtc_port}" =~ ${port_regex} ]]; then + webrtc_port="${BASH_REMATCH[1]}" + echo "[INFO] Got WebRTC port from supervisor: ${ip_address}" >&2 + else + echo "[WARN] Failed to get WebRTC port from supervisor" >&2 + return 0 + fi + + export FRIGATE_GO2RTC_WEBRTC_CANDIDATE_INTERNAL="${ip_address}:${webrtc_port}" +} + +echo "[INFO] Preparing go2rtc config..." >&2 + +if [[ -n "${SUPERVISOR_TOKEN:-}" ]]; then + # Running as a Home Assistant add-on, infer the IP address and port + get_ip_and_port_from_supervisor +fi + raw_config=$(python3 /usr/local/go2rtc/create_config.py) +echo "[INFO] Starting go2rtc..." >&2 + # Replace the bash process with the go2rtc process, redirecting stderr to stdout exec 2>&1 exec go2rtc -config="${raw_config}" diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/run index f9978b6b2..f7a5a6d0a 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/run +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/run @@ -2,6 +2,10 @@ # shellcheck shell=bash # Start the NGINX service +set -o errexit -o nounset -o pipefail + +echo "[INFO] Starting NGINX..." >&2 + # Replace the bash process with the NGINX process, redirecting stderr to stdout exec 2>&1 exec nginx diff --git a/docker/rootfs/usr/local/go2rtc/create_config.py b/docker/rootfs/usr/local/go2rtc/create_config.py index e2658a6bf..faa84c287 100644 --- a/docker/rootfs/usr/local/go2rtc/create_config.py +++ b/docker/rootfs/usr/local/go2rtc/create_config.py @@ -29,9 +29,16 @@ if go2rtc_config.get("log") is None: elif go2rtc_config["log"].get("format") is None: go2rtc_config["log"]["format"] = "text" -# should set default stun server so webrtc can work if not go2rtc_config.get("webrtc", {}).get("candidates", []): - go2rtc_config["webrtc"] = {"candidates": ["stun:8555"]} + default_candidates = [] + # use internal candidate if it was discovered when running through the add-on + internal_candidate = os.environ.get("FRIGATE_GO2RTC_WEBRTC_CANDIDATE_INTERNAL", None) + if internal_candidate is not None: + default_candidates.append(internal_candidate) + # should set default stun server so webrtc can work + default_candidates.append("stun:8555") + + go2rtc_config["webrtc"] = {"candidates": default_candidates} # need to replace ffmpeg command when using ffmpeg4 if not os.path.exists(BTBN_PATH): diff --git a/docs/docs/configuration/live.md b/docs/docs/configuration/live.md index f453a508f..6569e9891 100644 --- a/docs/docs/configuration/live.md +++ b/docs/docs/configuration/live.md @@ -76,11 +76,9 @@ cameras: WebRTC works by creating a TCP or UDP connection on port `8555`. However, it requires additional configuration: - For external access, over the internet, setup your router to forward port `8555` to port `8555` on the Frigate device, for both TCP and UDP. -- For internal/local access, you will need to use a custom go2rtc config: +- For internal/local access, unless you are running through the add-on, you will also need to set the WebRTC candidates list in the go2rtc config. For example, if `192.168.1.10` is the local IP of the device running Frigate: - 1. Add your internal IP to the list of `candidates`. Here is an example, assuming that `192.168.1.10` is the local IP of the device running Frigate: - - ```yaml + ```yaml title="/config/frigate.yaml" go2rtc: streams: test_cam: ... @@ -90,6 +88,19 @@ WebRTC works by creating a TCP or UDP connection on port `8555`. However, it req - stun:8555 ``` +:::tip + +This extra configuration may not be required if Frigate has been installed as a Home Assistant add-on, as Frigate uses the Supervisor's API to generate a WebRTC candidate. + +However, it is recommended if issues occur to define the candidates manually. You should do this if the Frigate add-on fails to generate a valid candidate. If an error occurs you will see some warnings like the below in the add-on logs page during the initialization: + +```log +[WARN] Failed to get IP address from supervisor +[WARN] Failed to get WebRTC port from supervisor +``` + +::: + :::note If you are having difficulties getting WebRTC to work and you are running Frigate with docker, you may want to try changing the container network mode: