129 lines
3.6 KiB
Markdown
129 lines
3.6 KiB
Markdown
# ZLMediaKit 多路流输出机制
|
||
|
||
## 发现背景
|
||
|
||
在开发 4-5 路并发压测配置时,发现 ZLMediaKit 并非通过多端口监听来实现多路输出,而是通过**单端口 + 多路径**的方式实现。
|
||
|
||
## 机制说明
|
||
|
||
### 传统理解(错误)
|
||
|
||
以为每个 publish 节点需要独立的端口:
|
||
```
|
||
cam1 -> port 8555 -> /live/cam1
|
||
cam2 -> port 8556 -> /live/cam2
|
||
cam3 -> port 8557 -> /live/cam3
|
||
cam4 -> port 8558 -> /live/cam4
|
||
```
|
||
|
||
### 实际机制(正确)
|
||
|
||
ZLMediaKit 采用 **HTTP-like 虚拟主机机制**:
|
||
```
|
||
Single TCP Server: port 8555
|
||
├─ path: /live/cam1 -> stream cam1
|
||
├─ path: /live/cam2 -> stream cam2
|
||
├─ path: /live/cam3 -> stream cam3
|
||
├─ path: /live/cam4 -> stream cam4
|
||
└─ path: /live/cam5 -> stream cam5
|
||
```
|
||
|
||
## 日志验证
|
||
|
||
启动 5 路并发时观察到的日志:
|
||
|
||
```
|
||
# 只启动一次 TCP Server
|
||
TcpServer.cpp:200 start_l | TCP server listening on [::]: 8555
|
||
|
||
# 5 路流共享同一个端口,不同 path
|
||
zlm rtsp server ready: rtsp://0.0.0.0:8555/live/cam1
|
||
zlm rtsp server ready: rtsp://0.0.0.0:8555/live/cam2
|
||
zlm rtsp server ready: rtsp://0.0.0.0:8555/live/cam3
|
||
zlm rtsp server ready: rtsp://0.0.0.0:8555/live/cam4
|
||
zlm rtsp server ready: rtsp://0.0.0.0:8555/live/cam5
|
||
```
|
||
|
||
## 配置示例
|
||
|
||
### 错误的配置(端口冲突)
|
||
|
||
```json
|
||
"outputs": [
|
||
{ "proto": "rtsp_server", "port": 8555, "path": "/live/cam1" }
|
||
]
|
||
```
|
||
|
||
5 个实例分别配置 8555/8556/8557/8558/8559 会导致资源浪费。
|
||
|
||
### 正确的配置(共享端口)
|
||
|
||
```json
|
||
"outputs": [
|
||
{ "proto": "rtsp_server", "port": 8555, "path": "/live/${name}" }
|
||
]
|
||
```
|
||
|
||
所有实例使用相同端口,通过 `${name}` 变量区分不同路径。
|
||
|
||
## 播放地址
|
||
|
||
基于共享端口机制,客户端播放地址为:
|
||
|
||
| 通道 | RTSP 地址 | HLS 地址 |
|
||
|-----|-----------|----------|
|
||
| cam1 | `rtsp://<ip>:8555/live/cam1` | `http://<ip>:9000/hls/cam1/index.m3u8` |
|
||
| cam2 | `rtsp://<ip>:8555/live/cam2` | `http://<ip>:9000/hls/cam2/index.m3u8` |
|
||
| cam3 | `rtsp://<ip>:8555/live/cam3` | `http://<ip>:9000/hls/cam3/index.m3u8` |
|
||
| cam4 | `rtsp://<ip>:8555/live/cam4` | `http://<ip>:9000/hls/cam4/index.m3u8` |
|
||
| cam5 | `rtsp://<ip>:8555/live/cam5` | `http://<ip>:9000/hls/cam5/index.m3u8` |
|
||
|
||
## 优势
|
||
|
||
1. **端口资源节省** - 无论多少路流,只需 1 个端口
|
||
2. **防火墙友好** - 只需开放 1 个端口
|
||
3. **管理简便** - 统一入口,通过路径区分
|
||
4. **扩展性好** - 理论上支持无限路流(受限于系统资源)
|
||
|
||
## 限制
|
||
|
||
1. **单进程限制** - ZLMediaKit 实例是单例的,必须在同一个 media-server 进程内
|
||
2. **路径冲突** - 不同流的路径必须唯一
|
||
3. **端口独占** - 8555 被占用后,其他进程无法使用
|
||
|
||
## 相关配置
|
||
|
||
多路并发压测配置示例:`configs/stress_5ch_cam4_template.json`
|
||
|
||
关键配置片段:
|
||
```json
|
||
{
|
||
"templates": {
|
||
"strict_minio_alarm_pipeline": {
|
||
"nodes": [
|
||
{
|
||
"id": "pub",
|
||
"type": "publish",
|
||
"outputs": [
|
||
{ "proto": "rtsp_server", "port": 8555, "path": "/live/${name}" },
|
||
{ "proto": "hls", "path": "./web/hls/${name}/index.m3u8" }
|
||
]
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"instances": [
|
||
{ "name": "cam1", "template": "strict_minio_alarm_pipeline" },
|
||
{ "name": "cam2", "template": "strict_minio_alarm_pipeline" },
|
||
{ "name": "cam3", "template": "strict_minio_alarm_pipeline" },
|
||
{ "name": "cam4", "template": "strict_minio_alarm_pipeline" },
|
||
{ "name": "cam5", "template": "strict_minio_alarm_pipeline" }
|
||
]
|
||
}
|
||
```
|
||
|
||
## 参考
|
||
|
||
- ZLMediaKit 文档:https://github.com/ZLMediaKit/ZLMediaKit
|
||
- RTSP 协议虚拟主机机制
|