MediaMTX:把家里的直播源统一收口成 WebRTC/HLS 的「媒体网关」

前阵子想把家里几条来源不太统一的直播信号——有的是摄像头给的 RTSP,有的是网上搜来的 HLS,再有就是 IPTV 那种 HTTP TS——集中到一个地方:电视上能看、手机浏览器点开就能播、最好别再为每条流单独装一个客户端。试过几个方案都差点意思,直到撞上 MediaMTX,才觉得「这事就该这么干」。

MediaMTX 官方文档首页

它到底是啥

如果让我用一句话讲明白,MediaMTX 是个「媒体路由器」,不是「媒体转换器」。它自己不烧 CPU 重新编解码(transcoding),只做一件事:把一种协议的流拆包,按另一种协议重新打包送走。支持读的有 Media-over-QUIC、SRT、WebRTC、RTSP、RTMP、HLS、MPEG-TS、RTP;支持写出去的几乎一样多。任何一条流进来,可以同时被多协议客户端订阅——这正是我想要的「收口」。

它是 Go 写的单二进制,零运行时依赖,Linux/Windows/macOS 都跑,官方 Docker 镜像也常驻在 Docker Hub。截至 2026-08-28,GitHub 上 19.9k stars、MIT 协议,最新稳定版是 v1.20.1(8 月 18 日发布),主分支昨天还有提交,活跃度完全不用担心。

MediaMTX GitHub 仓库页

三件让我觉得值的小事

第一,协议自动转换。把那条 RTSP 摄像头源推上去之后,浏览器能直接 WebRTC 观看(延迟肉眼可接受),VLC 拉 RTSP,电视盒子拉 HLS——一条源三种消费,不用预先想清楚客户端是什么。这是它区别于普通流媒体服务器的核心能力。

第二,always-available 流。配置里把某个 path 标成 always-available,发布方下线后客户端拉流会先收到一张占位图像(可自定义),不会直接断连黑屏。对偶尔要「一直挂着、但不一定有人在推」的场景特别友好,比如我那条只在有人按门铃时才推送的摄像头。

第三,录制是真·省心。开 record: yes 之后,它按时间段切片写盘,文件格式在 fMP4 和 MPEG-TS 之间选。我用 fMP4 比较多,因为浏览器和大多数工具都吃。可以配 recordDeleteAfter 自动清旧文件,避免一夜之间把 NAS 塞满。它不做转码,所以录制出来的视频编码就是源端编码——如果源是 H.264/H.265/AAC 直接播,那录出来就是这些,不用再过一遍 ffmpeg。

MediaMTX Publish streams 文档页

我是这么把它跑起来的

装它就一条 Docker 命令的事:

docker run --rm -it 
  -p 8554:8554 -p 1935:1935 -p 8888:8888 
  -p 8889:8889 -p 8890:8890/udp -p 8189:8189/udp 
  -v /path/to/mediamtx.yml:/mediamtx.yml 
  bluenviron/mediamtx:latest

端口看着多,是因为不同协议各占一个:8554 默认 RTSP、1935 RTMP、8888 HLS、8889 WebRTC、8890/udp 是 SRT、8189/udp 是 RTP。暴露之前想清楚哪些真要对外,内网用就只开 8554 + 8889 + 8888 三个就够了,其他全 drop。

配置文件 mediamtx.yml 是它控制一切的入口。一条典型的 path 长这样:

paths:
  cam_door:
    source: rtsp://user:pass@192.168.x.x/stream1
    sourceOnDemand: yes
    alwaysAvailable: yes
    runOnReady: notify-telegram "门铃摄像头已上线"

  4k_live:
    source: publisher
    record: yes
    recordPath: ./recordings/%path/%Y-%m-%d_%H-%M-%S
    recordFormat: fmp4
    recordSegmentDuration: 1h
    recordDeleteAfter: 24h

第一条是拉现有的 RTSP 转多协议分发,第二条是允许外部推流上来、自动录制、按 1 小时切片、24 小时后自动清runOnReady 这种 hook 让我在摄像头真上线的时候给自己发个 Telegram 通知,省得反复去 WebUI 看。

想远程看每条流的状态(在线、客户端数、码率、录制大小),8888 端口有个内置 WebUI——不需要额外部署。还有 Control API(/control 路径下的 HTTP 接口),能脚本化查询和踢人,做自动化时特别顺手。

踩到的几个坑

浏览器看 WebRTC 需要 HTTPS,或者用 localhost 访问。我家 NAS 走的是反代,统一在网关那层接了个证书转发才解决——你也可以用 Caddy/Nginx 给 MediaMTX 套 TLS,别直接把它扔到公网 8889

它真的不转码。我一开始以为能像 ffmpeg 一样把 H.265 直播源「顺便」给老电视转成 H.264,不行。MediaMTX 只做协议层搬运,编码转换要么源端搞定,要么在它前面/后面挂 ffmpeg。如果你的客户端硬解 H.265 吃力,得老老实实起 ffmpeg 转一道。

认证要自己开。默认所有 path 都不需要账号密码,公网开之前一定要配 internal / HTTP / JWT 三种之一,最简单是 internal 写死用户密码表。我偷懒内网裸跑了一段时间,直到某天在路由器日志里看见外面有人扫 8554 才补上。

fMP4 录制的小坑:录像是按 recordPartDuration 拼起来的,系统崩溃时最后一个 part 会丢。对家用场景无所谓,对正经做录像归档的需要自己用 hook + rclone 之类同步到别处。官方文档里的「Remote upload」一节就是干这个的。

适合谁、不适合谁

适合:家里有几路异构来源(摄像头、IPTV、自建直播)想统一入口的人;想给老监控头加 WebRTC 浏览器观看能力的人;想低资源跑一个能录能播的实验性小平台的人——单二进制、内存几十兆、CPU 基本只跑协议解析,树莓派 4B 都跑得动

不太适合:需要「点播电影库」的人——它只做实时流和录制回放,不是 Jellyfin / Plex 那种带刮削的媒体库;需要给老电视强制 H.264 输出的人——前面说过,它不转码。

GitHub: bluenviron/mediamtx | 文档: mediamtx.org | 协议: MIT | 当前稳定版: v1.20.1(2026-08-18)。Docker 镜像、Linux/macOS/Windows 二进制、Homebrew tap 都有,按需取用。

发表评论