Skip to main content

Camera System (Advanced)

O.D.I.N. uses go2rtc as a WebRTC proxy to deliver low-latency camera streams from all your printers to any browser.


Architecture

Printer Camera → RTSP/MJPEG → go2rtc → WebRTC → Browser

go2rtc receives RTSP or MJPEG streams from each printer and re-transmits them as WebRTC to connected browsers. MJPEG streams (HTTP) are transcoded to H.264 via ffmpeg before WebRTC delivery.

O.D.I.N. manages the go2rtc configuration automatically — when you add a printer with a camera, O.D.I.N. writes the stream entry to go2rtc.yaml and signals go2rtc to reload.


Camera Auto-Discovery by Protocol

ProtocolAuto-Discovery MethodStream Format
Bambu MQTT (X1C, H2D)RTSP URL broadcast via MQTT on printer connectionRTSPS (encrypted)
Moonraker / KlipperWebcam URL pulled from Moonraker's camera config APIRTSP or MJPEG
PrusaLinkSnapshot endpoint probed on first connectionMJPEG (transcoded)
Elegoo SDCPMJPEG stream probed on port 8080MJPEG (transcoded)

For protocols that auto-discover camera URLs, no manual configuration is needed.


Manual Camera Configuration

For printers with cameras not auto-discovered (or to override the discovered URL), enter the camera URL manually:

  1. Go to Settings → Printers → [Printer] → Edit
  2. Set the Camera URL field
  3. Save

Examples:

# RTSP stream (most IP cameras)
rtsp://192.168.1.100:554/stream

# RTSPS (Bambu encrypted RTSP)
rtsps://bblp:ACCESS_CODE@192.168.1.50:322/streaming/live/1

# MJPEG over HTTP
http://192.168.1.100:8080/?action=stream

# USB camera (if exposed via v4l2rtspserver)
rtsp://localhost:8554/usb

Entered camera URLs containing credentials are Fernet-encrypted before storage.


Ports and Networking

Both Ports Must Be Accessible from the Client Browser

WebRTC uses two separate connections: the API/negotiation port (1984) and the WebRTC data channel (8555). Both must be reachable from the browser. If you access O.D.I.N. from outside the Docker host, forward both ports.

PortServicePurpose
1984go2rtc API and HLSWebRTC negotiation, stream list, HLS fallback
8555go2rtc WebRTCActual video data channel (UDP/TCP)
8000O.D.I.N. web UIMain application
WebRTC Candidate IP Must Be the Host IP, Not Docker Bridge IP

go2rtc auto-detects the host IP for ICE candidates. In some Docker Desktop or bridge network configurations, it may detect the Docker bridge IP (e.g., 172.17.x.x) instead of the host's LAN IP. This causes WebRTC to fail from remote clients.

Set the host IP explicitly:

  • Via environment variable: ODIN_HOST_IP=192.168.1.x in your docker-compose.yml
  • Or via UI: Settings → General → Host IP

The go2rtc WebRTC candidates config will then use the correct LAN IP (e.g., 192.168.1.x:8555).


go2rtc Configuration

The go2rtc config file is at /app/go2rtc/go2rtc.yaml inside the container. O.D.I.N. manages this file automatically. The current managed config structure:

api:
listen: 127.0.0.1:1984

webrtc:
listen: "0.0.0.0:8555"
candidates:
- 192.168.1.x:8555 # auto-set from host IP

streams:
printer_1: rtsps://bblp:***@192.168.1.50:322/streaming/live/1
printer_2: ffmpeg:http://192.168.1.100:8080/?action=stream#video=h264

For advanced go2rtc configuration (custom streams, additional sources, WebRTC STUN server), you can create a supplemental config — see the go2rtc documentation.


Camera Grid Page

Navigate to Cameras to see all active camera feeds in a grid layout.

  • Feeds connect via WebRTC automatically
  • Each tile shows the printer name and a status indicator
  • Click any tile to open the Camera Detail view

Enable or disable individual feeds with the toggle per printer. The grid refreshes live — no page reload needed when printers go offline or online.


Camera Detail View

Click any camera feed to open the dedicated detail route (/cameras/:id):

  • Large WebRTC stream (~70% of width)
  • Data panels alongside the stream:
    • Status, nozzle temp, bed temp, fan speed
    • Filament slots with remaining weight
    • Active job with progress bar and ETA
  • AI indicator badge if Vigil vision is enabled for this printer
  • Fullscreen button — native browser fullscreen
  • Back button to return to the Camera Grid
  • On mobile: panels stack below the stream

Picture-in-Picture

Pop out any camera feed into a floating, draggable, resizable mini-player:

  1. On any camera tile, click the Picture-in-Picture icon
  2. The feed floats above all other content
  3. Navigate to other pages — the PiP feed persists until you close it

See Also