How to Configure go2rtc for WebRTC and MSE Streaming in Frigate

Configure go2rtc in your Frigate config.yml by defining camera streams under the go2rtc.streams section and referencing the local restream endpoint at rtsp://127.0.0.1:8554/<camera_name> in your FFmpeg inputs to enable low-latency WebRTC and MSE playback in the browser.

The blakeblackshear/frigate repository ships with an embedded go2rtc instance (v1.9.x) that functions as a lightweight media gateway between your surveillance cameras and web browser. By configuring go2rtc properly, you can leverage WebRTC for native-resolution, low-latency streaming with audio support, while relying on MSE (Media Source Extensions) as a fallback for incompatible codecs or network conditions.

Understanding the go2rtc Streaming Architecture

Frigate utilizes go2rtc to create a three-stage pipeline that isolates camera connections from the detection workload, as documented in docs/docs/configuration/restream.md. The architecture flows as follows:

  • Camera to go2rtc: go2rtc pulls the raw feed (RTSP, ONVIF, or MJPEG) from your camera using its built-in client or FFmpeg modules.
  • go2rtc to Frigate: go2rtc exposes a local RTSP restream on port 8554. Frigate's detection pipeline connects to rtsp://127.0.0.1:8554/<camera_name> for object detection and recording.
  • go2rtc to Browser: When viewing the Live dashboard, the browser connects directly to go2rtc via port 1984 (proxied through Nginx as configured in docker/main/rootfs/usr/local/nginx/conf/go2rtc_upstream.conf). This connection uses WebRTC by default or falls back to MSE, bypassing the detection pipeline entirely.

This design reduces simultaneous connections to your cameras and enables on-the-fly codec translation without burdening Frigate's detection workers.

Configuring go2rtc Streams in config.yml

Begin by adding a go2rtc section to your config.yml. The stream name must match your camera name for automatic mapping, as detailed in docs/docs/guides/configuring_go2rtc.md.

go2rtc:
  streams:
    front_door: rtsp://192.168.1.10:554/live
    front_door_sub: rtsp://192.168.1.10:554/sub
    garage: rtsp://192.168.1.20:554/stream#audio=aac

The front_door entry defines the primary stream, while front_door_sub provides a lower-resolution alternative. The #audio=aac flag in the garage example triggers FFmpeg transcoding if your camera does not natively output AAC audio, utilizing the logic defined in web/src/utils/go2rtcFfmpeg.ts.

Mapping FFmpeg Inputs to the Restream

After defining go2rtc streams, configure your cameras to consume the local restream instead of connecting directly to the camera IP. This ensures Frigate's detection pipeline and the browser view share the same go2rtc connection.

cameras:
  front_door:
    ffmpeg:
      inputs:
        - path: rtsp://127.0.0.1:8554/front_door
          roles: ["detect", "record"]
        - path: rtsp://127.0.0.1:8554/front_door_sub
          roles: ["clips"]

Using rtsp://127.0.0.1:8554/<stream_name> tells Frigate to pull from go2rtc's internal RTSP server. This configuration is essential for enabling the WebRTC and MSE playback options in the web interface.

Enabling WebRTC and MSE Playback

The Frigate UI automatically selects between WebRTC and MSE based on browser capabilities and codec compatibility, as outlined in docs/docs/configuration/live.md.

  • WebRTC: Establishes a direct peer-to-peer connection between your browser and go2rtc using UDP or TCP candidates. This provides the lowest latency and supports native audio playback when codecs are compatible.
  • MSE: Packages the stream into an MP4 container accessible via the HTML5 MediaSource API. This serves as a fallback when WebRTC connectivity fails or when the camera uses H.265 codecs incompatible with browser-based WebRTC implementations.

For cameras using H.265 or proprietary audio formats, add transcoding parameters to ensure WebRTC compatibility:

go2rtc:
  streams:
    front_door: rtsp://192.168.1.10:554/live#video=h264#audio=aac

Advanced Configuration Options

Audio Transcoding

If your camera outputs PCMU, PCMA, or other non-browser-compatible formats, use the #audio=aac or #audio=opus query parameters in the stream URL. The transcoding is performed by go2rtc's FFmpeg module.

Back-Channel Suppression

For cameras with two-way audio, prevent the back-channel from blocking other applications by adding #backchannel=0:

go2rtc:
  streams:
    front_door: rtsp://192.168.1.10:554/live#backchannel=0

WebRTC Candidates

If accessing Frigate remotely (e.g., via Home Assistant or external networks), configure ICE candidates to ensure WebRTC connectivity through NAT:

go2rtc:
  webrtc:
    candidates:
      - "stun:8555"
      - "192.168.1.100:8555"
      - "your-public-ip:8555"

Validating Your go2rtc Configuration

After restarting Frigate, verify your configuration through the following methods:

  1. Check go2rtc Logs: Navigate to Logs → go2rtc in the Frigate UI to confirm streams are active without binding or codec errors.

  2. Access the go2rtc Web UI: Visit http://<frigate_host>:1984 to view all configured streams directly. The Nginx proxy configuration in docker/main/rootfs/usr/local/nginx/conf/go2rtc_upstream.conf routes this traffic to the go2rtc instance.

  3. API Validation: Use curl to verify stream availability programmatically:

curl http://localhost:5000/api/go2rtc/streams | jq .

If the stream works in the go2rtc Web UI on port 1984 but fails in the Frigate Live view, inspect your browser's codec support. H.265 or high-profile H.264 streams may require transcoding parameters to function with WebRTC or MSE.

Summary

  • Configure camera streams under the go2rtc.streams section in config.yml to enable the embedded go2rtc instance (v1.9.x).
  • Point Frigate's FFmpeg inputs to rtsp://127.0.0.1:8554/<camera_name> to consume the local restream for detection and recording.
  • WebRTC provides low-latency playback with audio on compatible browsers, while MSE serves as a codec-compatible fallback for incompatible formats.
  • Use URL parameters like #audio=aac and #backchannel=0 to handle transcoding and two-way audio conflicts.
  • Validate configuration via the go2rtc Web UI on port 1984 and the /api/go2rtc/streams endpoint.

Frequently Asked Questions

What is the difference between WebRTC and MSE streaming in Frigate?

WebRTC establishes a direct peer-to-peer connection between your browser and the go2rtc instance, offering the lowest latency and full audio support when codecs match. MSE (Media Source Extensions) serves as a fallback that delivers the stream through an HTML5 media container, which is essential when WebRTC connectivity fails or when the camera uses H.265 codecs incompatible with browser-based WebRTC implementations.

Why should I use go2rtc instead of connecting Frigate directly to my cameras?

Using go2rtc reduces the number of connections to your cameras (as Frigate and your browser share the go2rtc restream), enables on-the-fly codec transcoding for browser compatibility, and provides isolation between the detection pipeline and live viewing. This architecture handles protocol translation and audio transcoding without burdening the main Frigate detection workers.

How do I fix "codec not supported" errors when using WebRTC?

Add transcoding parameters to your go2rtc stream URL in config.yml. For example, append #video=h264 or #audio=aac to force FFmpeg to transcode the stream into browser-compatible formats. According to web/src/utils/go2rtcFfmpeg.ts, these parameters trigger go2rtc's internal FFmpeg module to re-encode the stream on-the-fly before serving it to the browser.

Can I use two-way audio with go2rtc without blocking other applications?

Yes. Add the #backchannel=0 query parameter to your go2rtc stream configuration. This suppresses the back-channel audio path in go2rtc, allowing Frigate and other applications to access the camera's audio stream without conflicts from the talk-back functionality.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →