[ffmpeg][mediamtx]RTSP视频流仿真
使用 FFmpeg + MediaMTX 搭建 RTSP 视频流仿真平台,覆盖认证、传输模式、多路推流,以及海康摄像头 URL 仿真。
1. 概念说明
1.1 FFmpeg
FFmpeg 是跨平台的多媒体处理工具集,覆盖音视频的采集、编解码、转封装、推流全流程。它由三个核心库和一组命令行工具组成:
| 组件 | 作用 |
|---|---|
libavcodec |
编解码(H.264/H.265/VP9/AAC 等) |
libavformat |
封装/解封装(MP4/MKV/RTSP/RTMP 等) |
libavfilter |
音视频滤镜(缩放/裁剪/水印等) |
ffmpeg |
主要命令行工具:转码、推流 |
ffprobe |
流信息探测 |
ffplay |
简易播放器 |
本文使用 ffmpeg 将本地视频文件以 RTSP 协议推送到流媒体服务器。
1.2 MediaMTX
MediaMTX(原名 rtsp-simple-server)是一个轻量级的流媒体服务器/代理,支持多协议接入与分发:
- 协议支持:RTSP、RTMP、HLS、WebRTC、SRT
- 核心能力:接收一路推流,以多种协议分发给多个客户端
- 部署特点:单二进制文件,零外部依赖,内存占用极低
- 适用场景:视频仿真、流媒体中转、NVR 后端
在本文的仿真架构中,MediaMTX 作为 RTSP 服务器——接收 FFmpeg 的推流,对外提供标准 RTSP 拉流地址。
1.3 RTSP 协议
RTSP(Real Time Streaming Protocol,RFC 2326)是应用层流媒体控制协议,负责建立和管理媒体会话,但媒体数据的实际传输由 RTP/RTCP 完成。
| 协议 | 定位 | 延迟 | 适用场景 |
|---|---|---|---|
| RTSP | 实时流控制 | 低 | 安防摄像头、局域网直播 |
| RTMP | 实时消息传输 | 低 | 直播推流(已被 HLS/WebRTC 取代趋势) |
| HLS | HTTP 自适应码率 | 高(秒级) | 大规模分发、移动端播放 |
| WebRTC | 点对点实时通信 | 极低 | 视频会议、交互式直播 |
RTSP 支持两种传输模式:TCP(可靠,可穿透防火墙)和 UDP(低开销,适合局域网)。
1.4 整体架构
1 | 本地视频文件 (.mp4) |
2. 环境安装
2.1 FFmpeg 安装
方式一:apt 安装(推荐,Ubuntu 22.04+)
1 | sudo apt update |
验证:
1 | ffmpeg -version |
方式二:静态编译版本(无需安装,解压即可)
从 John Van Sickle 静态编译 下载预编译二进制:
1 | wget https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz |
静态版本内置了所有常见编解码器(libx264、libx265 等),无需额外安装编码库。
2.2 MediaMTX 安装
从 GitHub Release 下载最新二进制:
1 | 下载(替换版本号为最新) |
启动:
1 | ./mediamtx |
默认监听端口:RTSP 8554、RTMP 1935、HLS 8888、WebRTC 8889。
配置 systemd 自启动(可选):
1 | sudo tee /etc/systemd/system/mediamtx.service << 'EOF' |
3. MediaMTX 配置详解
MediaMTX 的配置文件为 mediamtx.yml,格式清晰,注释详尽。以下只提取与 RTSP 仿真相关的核心配置。
3.1 端口与地址
1 | # mediamtx.yml |
3.2 认证配置
MediaMTX 支持两种认证方式:
- Basic(明文传输,仅在可信网络使用)
- Digest(摘要认证,推荐,密码不直接传输)
1 | # mediamtx.yml — 全局认证(所有发布点生效) |
readUser/readPass:拉流认证(客户端播放需要提供)publishUser/publishPass:推流认证(FFmpeg 推流需要提供)
按路径单独配置认证:
1 | # mediamtx.yml — 按发布点配置 |
3.3 传输模式(TCP/UDP)
控制 RTSP 媒体数据传输方式:
1 | # mediamtx.yml |
- TCP:媒体数据通过 RTSP 连接隧道传输,能穿透大多数 NAT/防火墙
- UDP:RTP 数据走独立 UDP 端口,延迟更低但防火墙不友好
- 当客户端和服务器同属局域网时,UDP 可减少 TCP 拥塞控制的抖动
3.4 按需推流 vs 常驻推流
MediaMTX 支持两种自动推流触发模式:
1 | # mediamtx.yml |
runOnDemand:省资源,适合偶尔访问的场景runOnReady:推流始终在线,客户端随时拉取,仿真调试首选
4. FFmpeg 推流参数详解
4.1 输入控制
1 | ffmpeg \ |
-re 是仿真推流最重要的参数——FFmpeg 默认会在 CPU 允许范围内以最快速度读帧,没有 -re 的话 1 分钟的短视频几秒钟就推完了,完全失去仿真意义。
4.2 编解码控制
1 | 视频编码 |
编码 vs 复制:
-c copy:不重编码,CPU 几乎无负载,但要求源文件编码格式兼容 RTSP(H.264/H.265 + AAC)-c:v libx264:重编码为 H.264,保证最大兼容性,但有 CPU 开销
preset 对照:
| preset | 速度 | 质量 | 适用场景 |
|---|---|---|---|
| ultrafast | 最快 | 一般 | 实时推流首选,CPU 最低 |
| veryfast | 较快 | 较好 | 推流次选,码率略优 |
| medium | 中等 | 好 | 离线转码 |
| slow/veryslow | 慢 | 最好 | 归档压缩 |
4.3 传输控制
1 | -rtsp_transport tcp \ # RTSP 传输方式:tcp 或 udp |
传输方式选择:
| 参数 | 可靠性 | 延迟 | 防火墙穿透 | 推荐场景 |
|---|---|---|---|---|
-rtsp_transport tcp |
高 | 略高 | 好 | 生产环境、跨网段 |
-rtsp_transport udp |
中 | 低 | 差 | 局域网、低延迟需求 |
4.4 高级推流参数详解
以下参数在推流仿真中同样重要:
-tune zerolatency(低延迟优化)
告诉 libx264 编码器不要为了压缩率而缓存多帧,每编码完一帧立即输出。没有此参数时,编码器可能缓存数帧以做参考,引入几百毫秒的额外延迟。实时推流场景强烈建议加入。
-profile:v baseline -level 3.1(H.264 档次与级别)
| 参数 | 作用 |
|---|---|
baseline |
禁用 B 帧等高级特性,所有设备(含老旧解码器)都能播放。海康摄像头默认 Baseline |
level 3.1 |
约束视频复杂度上限(宏块数/秒),确保解码器不超负荷。1080p@25fps 刚好在此范围内 |
未指定时,libx264 默认使用 high profile,部分低端解码器可能不支持。
-g <N> -keyint_min <N>(关键帧控制)
-g N:每 N 帧一个关键帧(IDR 帧),也称 GOP 大小-keyint_min N:最小关键帧间隔
关键帧是解码器随机寻址的唯一入口点,视频分析、切片、seek 都依赖它。
| 场景 | 推荐 GOP | 说明 |
|---|---|---|
| 视频分析 | fps×2(如 50@25fps) | 分析响应快,关键帧间隔不超过 2s |
| 直播 | fps×2~fps×5 | 兼顾压缩率和随机访问 |
| 存档 | fps×10 | 压缩率优先 |
未指定时 libx264 默认 GOP 250(~10s@25fps),对实时分析偏长。
-pix_fmt yuv420p(像素格式)
绝大多数播放器和解码设备只支持 yuv420p。ffmpeg 可能默认使用 yuv444p 或其他格式以获得更好质量,但会导致兼容性问题。推流时始终显式指定此参数。
-maxrate / -bufsize(VBV 码率控制)
1 | -b:v 4M -maxrate 4M -bufsize 8M |
VBV(Video Buffer Verifier)约束码率峰值,防止场景切换时码率瞬间冲高导致网络拥塞或接收端丢帧:
-b:v:目标平均码率-maxrate:允许的瞬时最大码率-bufsize:编码器码率控制缓冲大小(通常为 maxrate 的 2 倍)
-pkt_size 1316(RTP 包大小)
限制 RTP 包最大为 1316 字节,避免超过网络 MTU(1500 字节)导致 IP 分片。IP 分片会显著增加丢包率和重传开销。所有 RTSP 推流都建议设置此参数。
-fflags nobuffer(最小化输入缓冲)
减少 ffmpeg 内部的输入缓冲,配合 -re 进一步降低端到端延迟。适合对延迟敏感的场景。
4.5 完整推流命令模板
1 | ffmpeg \ |
5. 仿真 RTSP 视频流实战
5.1 场景一:TCP 方式推流
MediaMTX 配置(mediamtx.yml):
1 | protocols: [tcp] |
启动 MediaMTX:
1 | ./mediamtx mediamtx.yml |
FFmpeg 推流:
1 | ffmpeg \ |
推流成功后,MediaMTX 日志输出:
1 | INF [RTSP] [conn 127.0.0.1:52134] opened |
5.2 场景二:UDP 方式推流
将 protocols 和 rtspTransport 切换为 udp:
1 | # mediamtx.yml |
1 | FFmpeg 推流参数调整 |
UDP 方式下,RTP 媒体数据走独立 UDP 端口,延迟更低。但如果客户端在公网或跨 VLAN,建议优先用 TCP。
5.3 多路推流
同时模拟多路摄像头:
1 | 终端 1 — 通道 1 |
每条流对应 MediaMTX 上的一个发布点路径(/cam1、/cam2、/cam3),路径无需预先在 mediamtx.yml 中声明——MediaMTX 默认支持动态创建发布点。
6. 验证 RTSP 视频流
6.1 ffprobe 探测流信息
1 | ffprobe -v quiet -print_format json -show_format -show_streams \ |
输出示例:
1 | { |
duration: N/A 是正常的——RTSP 实时流没有固定时长。
6.2 ffplay 命令行播放
1 | ffplay rtsp://admin:admin123@localhost:8554/stream |
弹出播放窗口,验证视频内容和流畅度。
6.3 VLC 播放验证
- 打开 VLC → 媒体 → 打开网络串流
- 输入
rtsp://admin:admin123@localhost:8554/stream - 点击播放
6.4 OpenCV 拉流验证
1 | import cv2 |
注意:cv2.CAP_FFMPEG 明确指定使用 FFmpeg 后端解码 RTSP 流。
6.5 curl 调用 MediaMTX API
MediaMTX 内置 HTTP API,可查看发布点状态:
1 | 列出所有活跃的发布点 |
返回 JSON 包含推流状态、读者数量、字节统计等信息:
1 | { |
6.6 curl 验证 RTSP 流(含认证)
RTSP 协议基于文本,可以通过 curl 发送原始 RTSP 请求来验证流状态和认证配置,无需依赖专用播放器:
1 | OPTIONS——查看服务器支持的 RTSP 方法 |
参数说明:
| 参数 | 作用 |
|---|---|
-v |
显示完整的请求/响应头,便于调试 |
-u user:pass |
提供用户名密码,curl 自动选择认证方式 |
--digest |
强制使用 Digest 摘要认证 |
-X DESCRIBE |
发送 RTSP DESCRIBE 请求 |
-X OPTIONS |
查询服务器支持的方法集合 |
-H "Accept: application/sdp" |
声明接受的 SDP 格式 |
认证成功时,响应包含 SDP 描述信息:
1 | RTSP/1.0 200 OK |
SDP 中 m=video 0 RTP/AVP 96 表示该流包含一路 H.264 视频轨道,a=rtpmap:96 H264/90000 确认编码格式和时间戳时钟频率(90 kHz)。
注意:当 MediaMTX 配置 authMethod: digest 时,curl 需加 --digest 参数。不带此参数时,curl 会先发送无认证请求(收到 401),再尝试 Basic 认证;加上 --digest 后直接使用 Digest 摘要流程。
7. 仿真海康摄像头 RTSP 流
7.1 海康 RTSP URL 格式
海康 RTSP 标准 URL 格式:
1 | rtsp://<username>:<password>@<ip>:<port>/Streaming/Channels/<channel><streamType> |
| URL 组件 | 含义 | 示例 |
|---|---|---|
/Streaming/Channels/101 |
通道 1 主码流(高清) | 常用视频分析输入 |
/Streaming/Channels/102 |
通道 1 子码流(低清) | 预览、多路预览 |
/Streaming/Channels/201 |
通道 2 主码流 | 多通道摄像头 |
完整示例:
1 | rtsp://admin:hik12345@192.168.1.64:554/Streaming/Channels/101 |
7.2 仿真配置
在 MediaMTX 中创建一个海康格式的发布点路径:
1 | # mediamtx.yml |
推流命令:
1 | ffmpeg \ |
拉流验证(URL 与真实海康摄像头一致):
1 | ffplay rtsp://admin:hik12345@localhost:8554/Streaming/Channels/101 |
7.3 多通道仿真
模拟一台双通道摄像头(主码流 + 子码流):
1 | 主码流(高清 1080p,仿真海康主码流参数) |
这样下游的视频分析系统就可以像接入真实海康摄像头一样进行联调测试。
8. IP 地址说明
在搭建 RTSP 仿真环境时,经常遇到连接不上或只能本机访问的问题,根源往往在于 IP 地址选择不当。以下说明常见 IP 地址的区别。
8.1 127.0.0.1(回环地址)
- 含义:指向本机的回环接口
- 特点:数据不经过物理网卡,仅在内核层面完成收发
- 服务端绑定:监听
127.0.0.1:8554时,只有本机能连接 - 适用场景:服务端和客户端都在同一台机器上的开发调试
8.2 localhost
- 含义:一个域名,通常由
/etc/hosts解析为127.0.0.1(也可能解析为::1IPv6 地址) - 与 127.0.0.1 的关系:绝大多数情况下等价,但
localhost依赖 DNS 解析(或 NSS 配置),而127.0.0.1是直接 IP 寻址 - 注意:如果
/etc/hosts被修改或存在代理拦截,localhost可能指向其他地址
8.3 0.0.0.0(通配地址)
- 含义:绑定到所有网络接口,包括回环接口(127.0.0.1)和所有物理/虚拟网卡(如 192.168.x.x)
- 服务端绑定:监听
0.0.0.0:8554时,本机通过127.0.0.1可以访问,局域网其他机器通过192.168.x.x也能访问 - 适用场景:需要局域网其他设备访问服务
- 重要限制:客户端不能以
0.0.0.0作为目标地址发起连接——它仅用于服务端表示”绑定所有接口”
8.4 局域网 IP(192.168.x.x / 10.x.x.x / 172.x.x.x)
- 含义:内网接口的真实 IP 地址(RFC 1918 私有地址段)
- 特点:数据经过物理网卡,同网段的其他设备可路由到达
- 服务端绑定:监听
192.168.1.100:8554时,仅通过该网卡的流量能到达 - 适用场景:跨设备联调时,客户端应使用此地址
8.5 对比总结
| 地址/域名 | 服务端绑定含义 | 本机能否访问 | 局域网能否访问 | 客户端能否使用 |
|---|---|---|---|---|
127.0.0.1 |
仅监听回环接口 | 能 | 不能 | 能,仅本机 |
localhost |
同 127.0.0.1(通常) |
能 | 不能 | 能,仅本机 |
0.0.0.0 |
监听所有接口 | 能(通过 127.0.0.1) | 能(通过局域网 IP) | 不能作为目标 |
192.168.x.x |
监听指定网卡 | 能 | 能(同网段) | 能(跨设备) |
8.6 在 RTSP 仿真中的应用
1 | # mediamtx.yml |
推流/拉流地址选择:
1 | 本机访问(MediaMTX 监听 0.0.0.0 或 127.0.0.1 均可) |
常见问题:MediaMTX 监听 127.0.0.1:8554 时,局域网其他机器无法连接;改为 0.0.0.0:8554 或具体的局域网 IP 即可解决。
9. 参考资源
文档
- FFmpeg Documentation
- FFmpeg Wiki — H.264 Encoding Guide
- MediaMTX GitHub
- MediaMTX Configuration Reference