
一、项目背景与效果
项目需要在浏览器端实时观看香橙派摄像头的画面。之前使用 ffmpeg 推 RTMP 流 + ffplay 拉流 的方案,在局域网内端到端延时高达 5~8 秒,完全无法用于实时遥控或监控。
切换到 MediaMTX 的 WebRTC 播放后,实测端到端延时稳定在 500-800ms ,比 ffmpeg 拉流方式快了近 10 倍,肉眼几乎感觉不到延迟。本文将完整记录安装、配置、设置开机自启的全过程,以及两个典型踩坑的排查与修复。
最终效果
- 浏览器访问
http://板子IP:8889/live/stream0即可看到超低延迟视频 - 板子重启后服务自动运行,无需手动干预
二、环境信息
- 硬件:Orange Pi 5 Ultra(ARM64,aarch64)
- 系统:Armbian / Ubuntu 22.04(root 用户)
- 软件:MediaMTX v1.8.3 官方预编译版
- 推流方式 :板端应用通过 RTMP 推至本机
rtmp://127.0.0.1:1935/live/stream0 - 播放方式:浏览器通过 WebRTC 拉流
三、MediaMTX 安装(极简)
MediaMTX 为 ARM64 提供了静态二进制,无需编译,直接下载解压即可。
bash
# 确认架构(必须输出 aarch64)
uname -m
# 下载 1.8.3 版本(请至 GitHub Releases 确认最新版)
wget https://github.com/bluenviron/mediamtx/releases/download/v1.8.3/mediamtx_v1.8.3_linux_arm64v8.tar.gz
# 解压,得到 mediamtx(可执行文件)和 mediamtx.yml(默认配置)
tar -xzf mediamtx_v1.8.3_linux_arm64v8.tar.gz
为了方便管理并避免后续权限问题,推荐将可执行文件复制到标准路径:
bash
sudo cp mediamtx /usr/local/bin/
sudo chmod +x /usr/local/bin/mediamtx
四、配置文件(低延时的关键)
WebRTC 的低延迟优势必须搭配正确的配置才能发挥。这里我们关闭无关协议,只保留 RTMP 和 WebRTC。
创建配置文件(路径可自定,本例使用 /usr/local/etc/mediamtx.yml):
bash
sudo mkdir -p /usr/local/etc
sudo nano /usr/local/etc/mediamtx.yml
写入以下内容(注意替换 webrtcAdditionalHosts 为板子实际 IP):
yaml
logLevel: info
rtmp: yes
rtmpAddress: :1935
webrtc: yes
webrtcAddress: :8889
webrtcAllowOrigin: '*'
webrtcLocalUDPAddress: :8189
webrtcLocalTCPAddress: :8188
webrtcIPsFromInterfaces: no
webrtcAdditionalHosts: [192.168.137.6] # 请替换为板子实际 IP
rtsp: no
hls: no
srt: no
paths:
live/stream9:
source: publisher
overridePublisher: no
live/stream11:
source: publisher
overridePublisher: no
live/stream0:
source: publisher
overridePublisher: no
配置说明:
- 仅开启 RTMP 推流和 WebRTC 播放,降低资源占用。
webrtcAdditionalHosts必须填写板子在局域网中的实际 IP,否则浏览器无法获取 ICE 候选,导致连接失败。- 如果你的场景需要 WebRTC 通过 STUN/TURN 跨网络,还请额外添加相应配置。
五、设置 systemd 开机自启
为了让服务在板子启动后自动运行,我们编写 systemd 单元文件。
bash
sudo nano /etc/systemd/system/mediamtx.service
内容如下:
ini
[Unit]
Description=MediaMTX streaming server
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/mediamtx /usr/local/etc/mediamtx.yml
Restart=on-failure
RestartSec=5
User=root
[Install]
WantedBy=multi-user.target
然后执行:
bash
sudo systemctl daemon-reload
sudo systemctl enable mediamtx
sudo systemctl start mediamtx
验证服务状态:
bash
systemctl status mediamtx
应显示 active (running),否则需根据错误信息排查(下一节即为典型错误)。
检查端口监听:
bash
ss -lntup | grep -E '1935|8889'
ss -lunp | grep 8189
正常情况下可看到 RTMP (1935)、WebRTC TCP (8889) 和 UDP (8189) 端口均在监听。
六、踩坑一:status=200/CHDIR 错误导致服务无法启动
现象
systemctl status mediamtx 显示:
Active: activating (auto-restart) (Result: exit-code)
Process: 1234 ExecStart=/usr/local/bin/mediamtx /root/mediamtx/mediamtx.yml (code=exited, status=200/CHDIR)
原因
CHDIR 表示进程尝试切换工作目录失败。这里的错误在于 ExecStart 中配置文件路径 /root/mediamtx/mediamtx.yml 的父目录 /root/mediamtx 不存在或不是目录。
常见情况:之前不小心把解压出的 mediamtx 二进制直接放在了 /root/ 下并命名为 mediamtx,导致 /root/mediamtx 是一个 文件 而非目录,服务自然会失败。
解决办法
统一文件路径,确保二进制与配置文件路径都正确存在。我们的推荐已经将二进制放在 /usr/local/bin/mediamtx,配置文件放在 /usr/local/etc/mediamtx.yml。只要 ExecStart 写为:
ini
ExecStart=/usr/local/bin/mediamtx /usr/local/etc/mediamtx.yml
就不会再出现 CHDIR。如果你的历史文件比较混乱,请先运行以下命令确认实际位置:
bash
which mediamtx # 查看二进制位置
ls -l /usr/local/etc/ # 查看配置文件是否存在
然后修正服务文件并 systemctl daemon-reload 重启。
七、踩坑二:修改了配置文件但 WebRTC 端口不生效
现象
已经确认 mediamtx.yml 中 webrtc: yes,并重启了服务,但 ss -lntup 只能看到 1935 端口,8889 端口始终不存在。
原因
MediaMTX 加载的配置文件可能并不是你编辑的那一个。可以通过以下命令查看实际运行参数:
bash
ps aux | grep mediamtx
# 或
cat /proc/$(pidof mediamtx)/cmdline | tr '\0' ' '
你会看到类似 /usr/local/bin/mediamtx /usr/local/etc/mediamtx.yml 的输出。如果这里显示的配置文件路径与你编辑的不一致,比如你编辑的是 /root/mediamtx/mediamtx.yml,但进程加载的是 /usr/local/etc/mediamtx.yml,自然修改无法生效。
解决办法
保持 systemd 服务文件中的配置文件路径与你实际修改的文件一致。修改后务必执行:
bash
sudo systemctl daemon-reload
sudo systemctl restart mediamtx
之后再次检查端口,8889 应该就会出现。
八、验证开机自启的常用命令
bash
# 查看是否已设置为开机启动
systemctl is-enabled mediamtx # 输出 enabled 即成功
# 在所有服务列表中查找
systemctl list-unit-files --type=service | grep mediamtx
# 最可靠的验证方法:直接重启板子
sudo reboot
# 重启后立即连接,查看服务状态
systemctl status mediamtx
九、延时实测:比 ffmpeg 拉流快近 10 倍
部署完成后,在同一局域网内:
- ffmpeg 拉流方式 :
ffplay rtmp://板子IP/live/stream0,画面比实际动作延迟 5~8 秒 - MediaMTX WebRTC 方式 :Chrome 浏览器访问
http://192.168.137.6:8889/live/stream0,用手机秒表同框测试,延时稳定在 500-800ms,通常仅 600ms 左右
近 10 倍的延时缩减,使得远程监控、机器人遥控等场景真正变得可用。
注:实际延时受网络环境、编码器参数等影响,本文数据基于 H.264 编码、720P 分辨率,局域网有线连接。
十、经验萃取(下次直接套用)
| 问题场景 | 核心教训 | 快速排查方法 |
|---|---|---|
服务启动失败 CHDIR |
ExecStart 中配置文件路径的父目录必须是一个真实存在的目录 ,不能是文件;建议统一将配置放在 /usr/local/etc/ |
ls -ld /配置文件父目录路径 |
| 修改配置不生效 | 用 ps 或 /proc/PID/cmdline 确认进程实际加载的配置文件路径,不要想当然 |
`ps aux |
| 隐藏文件通过 scp 复制失败 | 隐藏文件(以 . 开头)不会自动补全,容易打错名字;先用 ls -a 确认 |
ls -a 源目录 |
| WebRTC 端口不监听 | 确认配置文件中 webrtc: yes 且进程确实使用了该文件;还需检查防火墙是否放行 8889 和 8189 |
`ss -lntup |
| 忘记放行防火墙 | 如果端口已监听但外部无法访问,可能是防火墙拦截 | sudo ufw allow 8889/tcp 等 |
十一、总结
在 Orange Pi 5 Ultra 这样的小型 ARM 板子上,利用 MediaMTX 可以轻松搭建超低延时的 WebRTC 流媒体服务。整个过程只需下载一个二进制、写一份配置文件、建一个 systemd 服务。尽管过程中可能会遇到 CHDIR 错误或配置不生效的坑,但只要搞清文件路径一致性 和进程实际加载的配置这两个关键点,很快就能解决问题。
最终延时从 5~8 秒骤降至 500-800ms,比局域网 ffmpeg 拉流快了近 10 倍,为后续实时视频应用打下了坚实基础。
如果这篇踩坑记录对你有帮助,欢迎 点赞、收藏、评论,一起交流 ARM 板上的实时音视频技术!