用 MediaMTX 搭建低延迟直播:从 SRT 推流到 WebRTC 播放的完整指南
2026/9/8 17:53:07 网站建设 项目流程

用 MediaMTX 搭建低延迟直播:从 SRT 推流到 WebRTC 播放的完整指南

【免费下载链接】mediamtxReady-to-use Media-over-QUIC / SRT / WebRTC / RTSP / RTMP / LL-HLS / MPEG-TS / RTP live media server and media proxy that allows to read, publish, proxy, record and playback real-time video and audio streams.项目地址: https://gitcode.com/GitHub_Trending/me/mediamtx

推一路线路测试码流到观众屏幕,走 HLS 是 3 到 10 秒,走 RTMP 也要 1 到 3 秒。对娱乐直播来说尚可忍受,但对游戏直播,观众看到技能释放时操作已经完成,体验直接崩掉。延迟问题的根源不在网络带宽,而在协议本身的分段缓冲机制——而破局的办法,是用支持WebRTC的流媒体服务器把播放端延迟压到亚秒级。

MediaMTX是一个开箱即用的零依赖实时流媒体服务器,同时内置 WebRTC、SRT、RTSP、RTMP、LL-HLS 等协议栈,可以把一路推流转成任意协议播放,并支持录制与回放。

一条流如何同时喂饱四种播放器

MediaMTX 的核心心智模型很朴素:所有流都挂在一个叫path(路径)的对象上,path 由一个path manager统一管理。

  • 一个 path 只有一个推流者(publisher),可以是 RTSP/RTMP/WebRTC/SRT 客户端,也可以是被配置拉流的外部源
  • 任意多个观众可以用任意受支持的协议读同一条流
  • 服务器内部只做remux(协议转换、不重编码),所以 CPU 开销极低,单进程即可撑起多路并发

也就是说,推流者用 SRT 进来,浏览器观众用 WebRTC 看,移动端用 LL-HLS 看,VLC 用 RTSP 看——它们读的是同一条流。数据流向就是:推流客户端 → path → 各协议 server → 观众,完整说明见架构文档。

关键技术决策

为什么用 SRT 推流

SRT(Secure Reliable Transport)是基于 UDP 的可靠传输协议,用应用层重传对抗丢包,典型端到端延迟在 100ms 量级,远低于 TCP 系的 RTSP/RTMP。对游戏场景更重要的是它天然适配 OBS 这类推流端。MediaMTX 的 SRT server 默认开启,监听 UDP:8890,streamid 同时支持m=publish,r=live这种标准语法(部分硬件只认它),细节见SRT 特性文档:

srt: true srtAddress: :8890

为什么用 WebRTC 播放

WebRTC 在浏览器里无需插件,媒体走 SRTP 直连,观众端延迟通常在几十毫秒到 100ms 出头。MediaMTX 的 WebRTC 握手走 HTTP(:8889),媒体走独立的 UDP/ICE 监听(默认:8189),四层连通方案按优先级排列:静态 UDP 端口 → 静态 TCP 端口 → STUN 打洞 → TURN 中继。局域网或端口放通的内网机器,默认配置就够了;公网部署时把公网 IP 写进webrtcAdditionalHosts即可:

webrtc: true webrtcAddress: :8889 webrtcLocalUDPAddress: :8189 webrtcAdditionalHosts: [1.2.3.4]

为什么留一个 LL-HLS 兜底

部分移动端场景(尤其是 iOS 系统播放器)只能走 HLS。MediaMTX 的 HLS 默认就是lowLatency变体,hlsPartDuration: 200ms,把 LL-HLS 的 part 粒度压到 200 毫秒,配合 CDN 分发时延迟能到 2 秒左右——不是最优,但足够覆盖 WebRTC 触达不了的终端。

从安装到出画面的最小配置

MediaMTX 是单个可执行文件,Docker 启动最快。注意 WebRTC 的 UDP 端口8189和 SRT 的8890都要用/udp映射,漏掉 8189 是新手最常见的失败点:

docker run --rm -it \ -p 8554:8554 -p 8888:8888 -p 8889:8889 \ -p 8189:8189/udp -p 8890:8890/udp \ bluenviron/mediamtx:1

启动后日志会逐行列出各 server 的监听状态。默认配置(仓库根目录的mediamtx.yml,共 800 余行注释)里authMethod: internaluser: any放行匿名读写,局域网实验直接可用;上生产前至少要改成按 path 限制权限,完整参数以配置文件参考为准。

推流端用 FFmpeg 生成测试源,走 SRT 标准 streamid 语法推入live路径:

ffmpeg -re -f lavfi -i testsrc=duration=30 -f lavfi -i sine=duration=30 \ -c:v libx264 -preset ultrafast -c:a aac \ -f srt "srt://127.0.0.1:8890?streamid=#!::m=publish,r=live"

验证闭环只需要两条命令。第一条确认流真的进了服务器(跨协议读取成功):

ffprobe -v error -show_entries stream=codec_name rtsp://127.0.0.1:8554/live # 预期输出:h264 与 aac 两行 codec_name

第二条确认 LL-HLS 播放列表已生成:

curl -s http://127.0.0.1:8888/live/index.m3u8 | head # 预期输出:#EXTM3U 开头的播放列表

浏览器打开http://服务器IP:8889,MediaMTX 自带 WebRTC 查看页,填入流地址即可出画面——从推流到出画面,这条链路通常不到 1 秒。

两个文档不会重点提醒的坑

⚠️ 第一个坑在编码器上:浏览器用 WebRTC 播 H265 基本全军覆没(仅 Windows 版 Chrome 在特定 GPU 下支持),而含B 帧的 H264 同样不被 WebRTC 规范接纳——服务端转不动浏览器的编码限制,唯一解法是推流端改用 H264 baseline profile + Opus 重新编码,WebRTC 特性文档 里给了现成的 FFmpeg 转码参数。如果你的推流设备固定输出 B 帧 H264,观众端大概率是黑屏而非报错,这点非常隐蔽。

第二个坑在网络层:Docker 部署时如果只映射了8889忘了8189/udp,握手 HTTP 200、页面正常加载、但画面永远转圈——因为 ICE 媒体通道根本建立不起来。排查顺序建议照文档的四层方案走:先确认 UDP 8189 放通,再开webrtcLocalTCPAddress: :8189走 TCP 兜底(代价是拥塞时延迟递增),最后才上 STUN/TURN。

另外录制是默认关闭的(record: false),开启后recordPath默认按%path与时间戳落盘 fMP4 分段,单段 1 小时,适合比赛回放,详见录制文档。

延伸方向

  • 大规模并发时把主服务器的 path 通过forward推到边缘 MediaMTX 节点,或反向用source拉流做读副本,见转发文档
  • :9998的 Prometheus metrics 端点接 Grafana,盯每路的 reader 数与 CPU 占用
  • 探索 MoQ(Media over QUIC)协议栈,它基于 HTTP3/WebTransport,是比 WebRTC 更轻的下一代低延迟方案,仓库已内置完整实现

【免费下载链接】mediamtxReady-to-use Media-over-QUIC / SRT / WebRTC / RTSP / RTMP / LL-HLS / MPEG-TS / RTP live media server and media proxy that allows to read, publish, proxy, record and playback real-time video and audio streams.项目地址: https://gitcode.com/GitHub_Trending/me/mediamtx

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询