# DroneScrewServer RTSP 推流方案 - MediaMTX 部署指南 ## 背景 FFmpeg 的 RTSP muxer 在 `listen` 模式下无法作为 RTSP 服务器供 VLC 等客户端主动拉流(`listen` 是等 TCP 连接,而 RTSP 协议需要服务器先监听 RTSP 握手)。因此采用 **mediamtx** 作为中转服务器。 ## 架构 ``` DroneScrewServer --推流--> mediamtx --拉流--> VLC/CtrlApp (本地推送) (RTSP服务器) (局域网拉流) rtsp://127.0.0.1:8554 监听 :8554 rtsp://板子IP:8554 ``` ## 部署步骤 ### 1. 准备文件 将以下文件复制到板子上的 `/opt/dronescrew/` 目录(或你选择的目录): ```bash SDK/mediamtx/arm64/mediamtx # mediamtx 可执行文件 GrabBagPrj/mediamtx_dronescrew.yml # mediamtx 配置文件 GrabBagPrj/start_mediamtx.sh # 手动启动脚本 ``` ### 2. 方法 A:手动启动(测试用) ```bash cd /opt/dronescrew chmod +x mediamtx start_mediamtx.sh ./start_mediamtx.sh ``` 看到类似输出表示启动成功: ``` 启动 mediamtx RTSP 服务器... 配置文件: /opt/dronescrew/mediamtx_dronescrew.yml RTSP 端口: 8554 推流地址: rtsp://127.0.0.1:8554/live/dronescrew (DroneScrewServer 内部推流) 拉流地址: rtsp://<板子IP>:8554/live/dronescrew (VLC/CtrlApp 从外部拉流) 按 Ctrl+C 停止服务 [INFO] mediamtx v1.x.x [INFO] RTSP server listening on :8554 ``` ### 3. 方法 B:systemd 开机自启(生产环境) ```bash # 1. 复制文件 sudo mkdir -p /opt/dronescrew sudo cp mediamtx mediamtx_dronescrew.yml /opt/dronescrew/ sudo chmod +x /opt/dronescrew/mediamtx # 2. 安装 systemd service sudo cp GrabBagPrj/mediamtx-dronescrew.service /etc/systemd/system/ # 3. 启用并启动服务 sudo systemctl daemon-reload sudo systemctl enable mediamtx-dronescrew.service sudo systemctl start mediamtx-dronescrew.service # 4. 查看状态 sudo systemctl status mediamtx-dronescrew.service # 5. 查看实时日志 sudo journalctl -u mediamtx-dronescrew.service -f ``` ### 4. 验证 #### 启动 DroneScrewServer ```bash cd /opt/dronescrewserver ./DroneScrewServer ``` DroneScrewServer 启动后会自动推流到 `rtsp://127.0.0.1:8554/live/dronescrew`。 #### 用 VLC 拉流测试 在 PC 上打开 VLC,媒体 → 打开网络串流,输入: ``` rtsp://192.168.10.30:8554/live/dronescrew ``` (将 `192.168.10.30` 替换为板子的实际 IP) 应该能看到实时视频流(1920×1080, 30fps, H.264)。 #### 用 ffplay 测试 ```bash ffplay -rtsp_transport tcp rtsp://192.168.10.30:8554/live/dronescrew ``` ## 配置说明 ### mediamtx_dronescrew.yml - **端口**:8554(RTSP 标准端口) - **认证**:无(局域网内部使用,允许任何 IP 推流/拉流) - **传输方式**:TCP(更稳定,适合工业环境) - **路径**:`/live/dronescrew` 如需修改端口或路径: 1. 修改 `mediamtx_dronescrew.yml` 中的 `rtspAddress` 2. 同步修改 DroneScrewServer 配置文件中的 RTSP 端口和路径 ### DroneScrewServer 配置 `config/config.xml` 中的 RTSP 相关配置: ```xml 8554 /live/dronescrew ``` 代码已经硬编码 `rtspHost = "127.0.0.1"`(推到本地 mediamtx),无需额外配置。 ## 故障排查 ### 1. mediamtx 启动失败 **现象**:`./start_mediamtx.sh` 报错或立即退出 **检查**: ```bash # 端口被占用? sudo netstat -tulnp | grep 8554 # 如果有其他进程占用,kill 它或换个端口 # 权限问题? ls -l mediamtx chmod +x mediamtx ``` ### 2. DroneScrewServer 推流失败 **现象**:日志显示 `avformat_write_header fail -111 (连接被拒绝)` **检查**: ```bash # mediamtx 是否在运行? ps aux | grep mediamtx sudo systemctl status mediamtx-dronescrew.service # 端口是否监听? sudo netstat -tulnp | grep 8554 ``` ### 3. VLC 拉流失败 **现象**:VLC 显示"无法打开 rtsp://..." **检查**: ```bash # DroneScrewServer 是否在推流? # 查看 mediamtx 日志,应该有类似输出: # [INFO] [rtsp] [conn 127.0.0.1:xxxxx] opened # [INFO] [rtsp] [session ...] created by 127.0.0.1:xxxxx # 防火墙是否阻止了 8554? sudo iptables -L -n | grep 8554 # 如需开放: sudo iptables -I INPUT -p tcp --dport 8554 -j ACCEPT # 网络是否通? ping 192.168.10.30 ``` ## 性能 - **延迟**:<100ms(mediamtx 中转延迟极低) - **带宽**:~4Mbps(H.264 CBR,1920×1080@30fps) - **CPU**:mediamtx 本身几乎不占 CPU(纯转发,不解码) - **多客户端**:支持多个 VLC/CtrlApp 同时拉流(mediamtx 自动复制流) ## 后续优化(可选) ### 1. 开启 HTTPS(RTSPS) 修改 `mediamtx_dronescrew.yml`: ```yaml rtspEncryption: optional # 或 strict rtspServerCert: /opt/dronescrew/server.crt rtspServerKey: /opt/dronescrew/server.key ``` 生成自签名证书: ```bash openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt -days 365 -nodes ``` ### 2. 添加认证 修改 `mediamtx_dronescrew.yml`: ```yaml authInternalUsers: - user: admin pass: your_password_here permissions: - action: publish - action: read ``` 同时修改 DroneScrewServer 代码,在 `VrFFPushConfig` 中设置: ```cpp pc.authUser = "admin"; pc.authPass = "your_password_here"; ``` (当前 FFmpeg RTSP muxer 暂不支持 auth,需修改 `initRtspOutput` 添加 `av_dict_set(&opts, "rtsp_user", ...)` 等) ### 3. 录像 修改 `mediamtx_dronescrew.yml`: ```yaml paths: live_dronescrew: record: true recordPath: /opt/dronescrew/recordings/%Y-%m-%d_%H-%M-%S.mp4 ``` ## 代码改动总结 | 文件 | 改动 | |------|------| | `IVrFFMediaPusher.h` | `VrFFPushConfig` 增加 `rtspHost` 字段 | | `CVrFFMediaPusher.h` | 去掉 `m_acceptThread` 和 `m_bStopAccept` | | `CVrFFMediaPusher.cpp` | `initRtspOutput`: URL 改为 `rtsp://{host}:{port}{path}`
`Start`: 去掉线程,直接调用 `avformat_write_header`
`Stop`: 去掉 `join()`
`PushFrame`: 去掉等客户端逻辑 | | `DroneScrewServerPresenter.cpp` | 配置中加 `pc.rtspHost = "127.0.0.1"` | | `DroneScrewCtrlApp/main.cpp` | 增加 FFmpeg stub (`querystring` / `ff_log_level`) | ## 测试清单 - [x] mediamtx 单独启动成功 - [ ] DroneScrewServer 推流成功(日志无 -111 错误) - [ ] VLC 从局域网拉流成功 - [ ] DroneScrewCtrlApp 拉流显示成功 - [ ] 停止推流后 mediamtx 正常释放连接 - [ ] 重启 DroneScrewServer 后能自动重连 ## 参考 - MediaMTX 官方文档: https://github.com/bluenviron/mediamtx - FFmpeg RTSP muxer: https://ffmpeg.org/ffmpeg-formats.html#rtsp