MediaMTX
Ready-to-use media server and RTSP/WebRTC proxy
MediaMTX, formerly rtsp-simple-server, is a ready-to-use media server and proxy that lets you publish and read live video streams over RTSP, RTMP, HLS, and WebRTC. It is commonly used to relay IP camera feeds for surveillance setups.
Key features
- RTSP, RTMP, HLS, WebRTC support
- Stream proxying and relaying
- On-demand publishing
- Single binary deployment
Pros & cons
Strengths
- Extremely lightweight
- Wide protocol support
Trade-offs
- No recording UI
- Not a complete NVR
MediaMTX replaces
Last reviewed Aug 26, 2026 · 782 words
Most IP cameras fall over at 2 or 3 simultaneous RTSP clients, and that is the problem MediaMTX solves: it pulls the camera stream once and re-serves it to as many viewers as you like, over RTSP, RTMP, HLS, WebRTC and SRT, from one Go binary that fits comfortably in the 128 MB the catalogue lists. It is not an NVR. There is no motion detection, no timeline, no web UI for recordings, and the project (formerly rtsp-simple-server) is deliberate about that scope. Think of it as the plumbing under a surveillance or streaming setup, and it is the best plumbing available.
One YAML file, one entry per stream
Everything lives in mediamtx.yml. To proxy a camera:
paths:
garage:
source: rtsp://admin:[email protected]:554/stream1
sourceOnDemand: yes
Start the binary or the bluenviron/mediamtx container and the same stream is available as rtsp://server:8554/garage, as HLS at http://server:8888/garage, and as a WebRTC page at http://server:8889/garage that plays in any browser with no plugin. sourceOnDemand means the camera is only contacted while someone is watching, which matters for battery cameras and for cameras that misbehave under a permanent connection. The default listeners are 8554 for RTSP, 1935 for RTMP, 8888 for HLS, 8889 for WebRTC, 8890 for SRT, 9997 for the HTTP API and 9998 for Prometheus metrics; expose only the ones you use.
WebRTC is the feature worth the trouble
HLS is easy and works everywhere but lags by several seconds. WebRTC gives sub-second latency in the browser, which is the difference between "is that the delivery driver" and watching him leave. The catch is NAT. WebRTC negotiates a UDP path, and if the viewer is not on the same network as the server you need UDP 8189 reachable and webrtcAdditionalHosts set to the address viewers will use, or a TURN server. The pragmatic shortcut for a home setup is a mesh VPN: over Tailscale every device is on the same virtual network and WebRTC works with no port forwarding at all.
It records, it just does not manage recordings
Add three lines to a path and MediaMTX writes segmented MP4 to disk:
record: yes
recordPath: /recordings/%path/%Y-%m-%d_%H-%M-%S-%f
recordDeleteAfter: 168h
That gives you 7 days of continuous footage per camera with automatic pruning, and the API can list and serve segments. What you do not get is an interface, events, or object detection. That is the job of Frigate, which is the NVR I would put on top. Note that Frigate bundles go2rtc, a close cousin with heavy overlap; if you run Frigate you may not need MediaMTX at all, and if you need a standalone relay for OBS, a drone feed or a public stream, MediaMTX is the more general tool of the two.
Publishing into it from anything with ffmpeg
Streams do not have to come from cameras. Any encoder can push to a path:
ffmpeg -re -i input.mp4 -c copy -f rtsp rtsp://server:8554/live
OBS publishes to rtmp://server:1935/live as a custom server, and Raspberry Pi cameras are supported natively in the ARM builds. That makes it a self-hosted stand-in for a Wowza-style relay for a small event or a private livestream, at a cost of zero.
Add auth before you forward a single port
Out of the box every path is readable and publishable by anyone who can reach the ports, and the API on 9997 controls the server. Fix both before anything is exposed:
authInternalUsers:
- user: admin
pass: a-long-password
permissions:
- action: publish
- action: read
- action: api
- user: viewer
pass: another-password
permissions:
- action: read
path: garage
Bind the API to localhost, put the HLS and WebRTC ports behind a reverse proxy with TLS, and treat camera passwords in the config file as the secrets they are. The wider video surveillance category is full of people who forwarded 8554 and found their garage on a search engine for open streams.
What I'd do
MediaMTX in a container on the same box as Frigate or Home Assistant, every camera proxied through it with sourceOnDemand, WebRTC over Tailscale for phone viewing, 7-day rolling recording on the paths that matter, and authInternalUsers set before the first docker compose up. If you only need what Frigate does, use Frigate's built-in go2rtc and skip this. If you need a general-purpose relay that speaks every protocol, this is the one, and at 128 MB there is no reason to run anything heavier.
Compare MediaMTX
2 head-to-head comparisons.
Similar video surveillance apps
go2rtc
Video SurveillanceUltimate camera streaming gateway with low latency
Replaces Nest Cam
OpenALPR
Video SurveillanceAutomatic license plate recognition library
Replaces Rekor Scout, Plate Recognizer
CompreFace
Video SurveillanceSelf-hosted face recognition service with REST API
Replaces Amazon Rekognition
OpenCvSharp
Video Surveillance.NET wrapper for OpenCV computer vision
Replaces Commercial vision SDKs
ZoneMinder
Video SurveillanceFull-featured closed-circuit television software suite
Replaces Blue Iris, Milestone XProtect
Cameradar
Video SurveillanceRTSP stream discovery and access-auditing tool for cameras
Replaces Commercial camera audit tools