MediaMTX:零依赖多协议流媒体服务器,5 分钟跑通 RTSP 推流到 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
MediaMTX 是一个用 Go 编写的零依赖实时媒体服务器与媒体代理,发布、读取、录制、回放音视频流一个进程全部完成。它编译后是一个独立可执行文件,不依赖 FFmpeg 或任何运行时。对开发者最直接的好处是:用一份配置替代一整套协议转换组件,RTSP、RTMP、WebRTC、SRT、LL-HLS 在同一个实例上同时工作,5 分钟即可搭建。
它解决了什么问题
| 典型需求 | MediaMTX 的解法 |
|---|---|
| RTSP 摄像头需要在浏览器里看 | 摄像头用 RTSP 推流,浏览器用 WebRTC 读取,协议转换由服务器自动完成,无需转码 |
| OBS 推 RTMP,移动端要低延迟观看 | 一条路径接收推流后,WebRTC、SRT、HLS 读者可同时拉取,各取所需 |
| 流要落盘保存,还要支持回放 | 一个参数开启录制,fMP4 或 MPEG-TS 分段写盘,回放服务器直接提供回放 |
| 同一台机器管理几十路流 | 每路流对应一条 path,互不干扰,可单独配置认证、录制、转发 |
🚀 首次运行
前置条件:已安装 Docker;二进制与其他方式见安装文档。
第 1 步,启动服务器,映射常用端口:
docker run --rm -it \ -p 8554:8554 -p 1935:1935 -p 8888:8888 \ -p 8889:8889 -p 8189:8189/udp \ -e MTX_RTSPTRANSPORTS=tcp \ bluenviron/mediamtx:1验证:终端持续输出各服务器启动日志,且ss -tln | grep 8554能看到端口在监听。
第 2 步,用 FFmpeg 模拟一个推流端:
ffmpeg -re -stream_loop -1 -i test.mp4 -c copy -f rtsp rtsp://localhost:8554/mystream验证:MediaMTX 日志出现针对mystream的 RTSP 发布会话记录。
第 3 步,读取这条流:
ffmpeg -i rtsp://localhost:8554/mystream -c copy -t 5 out.mp4验证:out.mp4生成且可正常播放,日志中多出一条读取会话。
到这一步,"推流 → 中转 → 拉流"的完整链路已经跑通。
🗺️ 能力地图速览
| 维度 | 支持内容 |
|---|---|
| 发布协议 | MoQ、SRT、WebRTC、RTSP、RTMP、HLS、MPEG-TS(UDP/Unix 套接字)、RTP、树莓派摄像头 |
| 读取协议 | MoQ、SRT、WebRTC、RTSP、RTMP、低延迟 HLS(LL-HLS) |
| 协议转换 | 自动完成。一端发布,另一端可用不同协议读取,不做转码 |
| 录制与回放 | fMP4/MPEG-TS 分段录制,按 part 写入降低故障丢失,回放服务器提供下载与回放 |
| 运维 | 配置热重载不踢断客户端,Control API(9997)、Prometheus 指标(9998)、pprof(9999) |
| 安全 | 内置用户、外部 HTTP、JWT 三种认证,支持按路径与 IP 段授权 |
| 部署 | 单可执行文件或 Docker 镜像,覆盖 Linux、Windows、macOS,无外部依赖 |
所谓"全协议"在 MediaMTX 里不是多个服务拼在一起,而是同一条流挂上多个入口:一份mediamtx.yml同时决定谁能发布、谁能读取、录不录制。
⚙️ 内部机制
MediaMTX 把每路流称为一条path。服务器启动时,路径管理器读取paths配置,为每条路径建立对象并做认证。发布端无论使用哪种协议,进入服务器后都由协议层把包解复用为轨道(视频轨、音频轨),交给路径持有。读者连接时,再按该读者需要的协议重新封装发出。录制、转发、代理这些功能,本质上都是路径的"消费者",所以扩展一条路径的成本很低。
三个核心组件:
- 路径管理器:internal/core/path_manager.go 负责路径生命周期、认证与客户端挂载,热重载时在此完成配置对齐
- 协议层:internal/protocols/ 下每个协议目录都有 to_stream/from_stream 一对实现,分别处理"协议包 → 内部轨道"和反向封装
- 录制器:internal/recorder/ 按 part 周期把数据刷盘,进程异常时最多丢失一个 part
单场景实战:RTSP 摄像头接入浏览器,顺带录像
场景:一台 RTSP 摄像头,目标是浏览器低延迟观看,同时保留录像。在mediamtx.yml里只改paths段的两处:
paths: cam1: source: rtsp://user:pass@192.168.1.50:554/stream1 record: yes recordFormat: fmp4source指向摄像头地址,有读者连接时服务器才会去拉流;record开启落盘,文件默认写在./recordings/,一天后自动清理,格式可选 fMP4 或 MPEG-TS。
验证方式有三条:
- 浏览器打开
http://服务器IP:8889/cam1,这是 WebRTC 内置播放页,几秒内出画面 - 查看
recordings/cam1/目录,fMP4 分段文件在按小时滚动生成 - 用
http://服务器IP:8888/cam1/hls.m3u8在 HLS 播放器里验证同一路流的低延迟 HLS 输出
整个过程没有重启服务器、没有引入额外进程,录像与实时播放来自同一条流。
🧯 避坑指南
| 现象 | 原因 | 解决 |
|---|---|---|
| 容器内 WebRTC 一直握手失败 | 握手走 8889/TCP,媒体实际走 8189/UDP,UDP 口没映射 | 映射8189/udp,并用MTX_WEBRTCADDITIONALHOSTS填上客户端能访问到的 IP |
| RTSP over UDP 拉不动流 | Docker 会改写 UDP 包的源地址和端口,摄像头无法回包 | 设MTX_RTSPTRANSPORTS=tcp,或以--network=host方式运行 |
| 苹果设备不播 LL-HLS | 低延迟 HLS 在苹果设备上强制要求 HTTPS | 开启hlsEncryption并配置证书,或将hlsVariant改为mpegts |
| 弱网下卡顿、丢包 | 系统默认 UDP 缓冲区偏小,或载荷过大被分片 | 调大udpReadBufferSize(如 4MB),调小udpMaxPayloadSize(如 1400) |
| 内存占用高于预期 | 每条连接的出站包队列默认 512 | 降低writeQueueSize,吞吐与内存之间取平衡 |
| 录像把磁盘占满 | recordDeleteAfter被设为 0s(关闭了自动删除) | 恢复保留期,如7d,并用recordSegmentDuration控制单文件时长 |
📚 深入方向
- 全部配置项逐项说明:docs/5-references/1-configuration-file.md
- 录制与回放的完整行为:docs/2-features/09-record.md、docs/2-features/10-playback.md
- 架构设计图与组件职责:docs/2-features/02-architecture.md
下一步建议:把仓库自带的mediamtx.yml完整读一遍,每个字段都有注释;然后试着把hlsVariant在lowLatency与mpegts之间切换,用同一播放器观察 2~3 秒与 5 秒以上延迟的差别;生产部署前再看一眼热重载章节,确认改配置不会踢掉在线读者。
把可执行文件下载下来,两条命令就能推上你的第一条流,本文的示例改个摄像头地址即可复用。真正动手时你才会发现,这个服务器能接住的协议组合比配置文件的长度还要多。
【免费下载链接】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),仅供参考