Skip to content

MediaMTX on caneast-site1-ot2-cam01

Status: Tier 3 Platform Document Last Updated: 2026-05-03 WI: WI-400

Overview

MediaMTX v1.18.1 runs on caneast-site1-ot2-cam01 as a dedicated RTSP/HLS/WebRTC server. It provides continuous low-latency camera streaming to Frigate NVR and optionally to browsers or Home Assistant directly.

MediaMTX is managed by the cam01-mediamtx Ansible role and runs as a dedicated system user.

Installation

Binary: /usr/local/bin/mediamtx (statically linked Go binary) Config: /etc/mediamtx/mediamtx.yml Version: 1.18.1 (arm64, pinned with checksum) Source: https://github.com/bluenviron/mediamtx/releases/download/v1.18.1/mediamtx_v1.18.1_linux_arm64v8.tar.gz

The binary is downloaded by Ansible with SHA256 checksum verification: sha256:REDACTED

Configuration

The rpiCamera source drives the IMX708 (Camera Module 3) directly through MediaMTX's bundled libcamera v0.5.0+59. System libcamera (v0.7.0 on Trixie) is not used at runtime.

logLevel: info
logDestinations: [stdout]

rtsp: true
rtspAddress: :8554

rtmp: false

hls: true
hlsAddress: :8888
hlsAlwaysRemux: false

webrtc: true
webrtcAddress: :8889

srt: false

paths:
  cam01:
    source: rpiCamera
    rpiCameraWidth: 1920
    rpiCameraHeight: 1080
    rpiCameraFPS: 5
    rpiCameraCodec: softwareH264
    rpiCameraIDRPeriod: 60

softwareH264 on Pi 5

The Pi 5 (BCM2712/RP1) does not expose the VC4-style V4L2 M2M H264 encoder that Pi 4 used. Setting rpiCameraCodec: hardwareH264 fails with:

encoder_create(): unable to open device

softwareH264 uses OpenH264 via MediaMTX's bundled libcamera build. The Pi 5's quad-core Cortex-A76 handles 1080p at 5fps with minimal CPU load (observed: ~8% on one core).

Systemd Unit

The service runs as mediamtx:mediamtx system user (no login shell, no home directory) with SupplementaryGroups=video to access /dev/media* and /dev/video* devices.

/etc/systemd/system/cam01-mediamtx.service

Key settings: - User=mediamtx, Group=mediamtx, SupplementaryGroups=video - Restart=on-failure, RestartSec=5 - PrivateTmp=true

Enable and start:

systemctl enable cam01-mediamtx
systemctl start cam01-mediamtx

Integration with cam01-capture

The cam01-capture service uses Option A camera contention: MediaMTX holds /dev/media* continuously during streaming. On a door-open event, capture.py releases the camera:

subprocess.run(["sudo", "/usr/bin/systemctl", "stop", "cam01-mediamtx"], ...)
try:
    rpicam-still --immediate --output /tmp/cam01_latest.jpg ...
finally:
    subprocess.run(["sudo", "/usr/bin/systemctl", "start", "cam01-mediamtx"], ...)

The try/finally guard ensures MediaMTX is always restarted even if capture fails. Stream gap per door event is approximately 2 seconds.

sudoers Entry

/etc/sudoers.d/cam01-mediamtx grants cam01 user passwordless systemctl control:

cam01 ALL=(root) NOPASSWD: /usr/bin/systemctl stop cam01-mediamtx, /usr/bin/systemctl start cam01-mediamtx

Viewing Streams

Three paths are available without additional infrastructure:

Path URL Notes
Frigate web UI https://frigate.peries.ca Traefik TLS, continuous + event recording
HLS (browser) http://REDACTED:[REDACTED]/cam01 Works in any browser, ~2-4s latency
WebRTC (browser) http://REDACTED:[REDACTED]/cam01 Sub-second latency, LAN only
RTSP (VLC/HA) rtsp://REDACTED:[REDACTED]/cam01 Home Assistant Frigate integration

Operational Notes

Check service status:

systemctl status cam01-mediamtx
journalctl -u cam01-mediamtx -n 50

Verify stream is live:

# From any LAN host
curl -s http://REDACTED:[REDACTED]/cam01/index.m3u8 | head -5

Frigate stats (via Frigate API or UI): - camera_fps: 5.x confirms MediaMTX is streaming - skipped_fps: 0.0 confirms Frigate is consuming all frames

If MediaMTX fails to start after capture: The Restart=on-failure, RestartSec=5 policy handles transient failures automatically. Check journalctl -u cam01-mediamtx for encoder_create or device busy errors.

Ansible Role

The cam01-mediamtx role in ansible/roles/cam01-mediamtx/ manages the full lifecycle: download, binary install, config deploy, sudoers, systemd enable+start.

Deploy:

.venv/bin/ansible-playbook ansible/playbooks/ot/cam01-mediamtx.yml

References