2026-06-26 17:55:15 +08:00

249 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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. 方法 Bsystemd 开机自启(生产环境)
```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
- **端口**8554RTSP 标准端口)
- **认证**:无(局域网内部使用,允许任何 IP 推流/拉流)
- **传输方式**TCP更稳定适合工业环境
- **路径**`/live/dronescrew`
如需修改端口或路径:
1. 修改 `mediamtx_dronescrew.yml` 中的 `rtspAddress`
2. 同步修改 DroneScrewServer 配置文件中的 RTSP 端口和路径
### DroneScrewServer 配置
`config/config.xml` 中的 RTSP 相关配置:
```xml
<rtsp_port>8554</rtsp_port>
<rtsp_path>/live/dronescrew</rtsp_path>
```
代码已经硬编码 `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
```
## 性能
- **延迟**<100msmediamtx 中转延迟极低
- **带宽**~4MbpsH.264 CBR1920×1080@30fps
- **CPU**mediamtx 本身几乎不占 CPU纯转发不解码
- **多客户端**支持多个 VLC/CtrlApp 同时拉流mediamtx 自动复制流
## 后续优化(可选)
### 1. 开启 HTTPSRTSPS
修改 `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}`<br>`Start`: 去掉线程,直接调用 `avformat_write_header`<br>`Stop`: 去掉 `join()`<br>`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