删除无效备份

This commit is contained in:
孙小云 2025-12-09 15:04:17 +08:00
parent 88e3b3deda
commit 97298b76f9
3 changed files with 1060 additions and 1 deletions

View File

@ -1,4 +1,3 @@
version: '3'
services:
polaris-redis:
image: ${REGISTRY}redis:latest # 使用官方Redis镜像

View File

@ -0,0 +1,561 @@
# ZLMediaKit API 核心概念与使用指南
## 一、核心概念解析
### 1. 流Stream的概念
在 ZLMediaKit 中,**流**是指一个媒体数据源,由四元组唯一标识:
- **schema**: 协议类型rtsp/rtmp/rtc等
- **vhost**: 虚拟主机(通常是 `__defaultVhost__`
- **app**: 应用名(如 live、rtp
- **stream**: 流ID如 test、camera01
**完整流标识**: `schema://vhost/app/stream`
例如: `rtsp://__defaultVhost__/live/test`
### 2. Session会话
**Session** 是指客户端与服务器之间的 **TCP/UDP 连接**
- 每个播放器连接、推流连接都会创建一个 Session
- Session 包含连接ID、本地端口、对端IP、协议类型等信息
- 通过 `getAllSession` 可以查看所有活跃连接
- 通过 `kick_session` 可以断开指定连接
**Session 与 Stream 的关系**
- 一个 Stream 可以有多个 Session多个播放器观看同一个流
- 一个 Session 只对应一个 Stream
### 3. 拉流代理StreamProxy
**拉流代理**是指 ZLMediaKit 作为客户端,从远程服务器拉取流,然后在本地提供服务。
**使用场景**
- 从其他流媒体服务器拉取流到本地
- 协议转换(拉取 RTMP 流,提供 RTSP/HLS 等多协议播放)
- 流的中转和分发
**API**: `addStreamProxy`
```
GET /index/api/addStreamProxy?
secret=xxx&
vhost=__defaultVhost__&
app=live&
stream=test&
url=rtmp://remote.server.com/live/stream
```
**工作原理**
```
远程服务器 --拉流--> ZLMediaKit --提供多协议--> 播放器
(RTMP源) (代理) (RTSP/RTMP/HLS/FLV等)
```
### 4. FFmpeg 拉流代理FFmpegSource
**FFmpeg 代理**是通过调用 FFmpeg 进程来拉取流,支持更多格式和协议。
**与普通拉流代理的区别**
- **StreamProxy**: 使用 ZLMediaKit 内置播放器,性能高,但支持协议有限
- **FFmpegSource**: 使用 FFmpeg支持任意协议/格式,但性能较低,占用资源多
**使用场景**
- 拉取 ZLMediaKit 不支持的协议(如某些特殊 HLS、DASH
- 需要 FFmpeg 的转码能力
- 拉取文件流
**API**: `addFFmpegSource`
```
GET /index/api/addFFmpegSource?
secret=xxx&
src_url=http://example.com/live.m3u8&
dst_url=rtmp://127.0.0.1/live/stream&
timeout_ms=10000
```
### 5. 推流代理StreamPusherProxy
**推流代理**是指将 ZLMediaKit 上的流推送到其他流媒体服务器。
**使用场景**
- 将本地流推送到 CDN
- 多平台分发(同时推送到多个平台)
- 流的备份
**API**: `addStreamPusherProxy`
```
GET /index/api/addStreamPusherProxy?
secret=xxx&
schema=rtmp&
vhost=__defaultVhost__&
app=live&
stream=test&
dst_url=rtmp://cdn.server.com/live/push
```
### 6. 断流close_stream
**断流**是指关闭一个媒体流源,而不是断开客户端连接。
**断流的含义**
- 停止流的源头(推流端或拉流代理)
- 所有观看该流的播放器会断开
- 流从服务器上移除
**与 kick_session 的区别**
- `close_stream`: 关闭流源,影响所有观看者
- `kick_session`: 只断开某个客户端连接,不影响流本身
### 7. RTP 服务器
**RTP 服务器**用于接收 GB28181 设备推送的 RTP 流。
**工作流程**
1. `openRtpServer`: 创建 RTP 接收端口
2. GB28181 设备推送 RTP 流到该端口
3. ZLMediaKit 自动将 RTP 流转换为标准流
4. 可通过 RTSP/RTMP/HLS 等协议播放
---
## 二、完整使用流程示例
### 场景 1: GB28181 设备推流
```bash
# 1. 创建 RTP 服务器(监听端口接收 GB28181 推流)
GET /index/api/openRtpServer?
secret=xxx&
port=10000&
tcp_mode=1&
stream_id=camera01
# 返回: {"code":0, "port":10000}
# 2. GB28181 设备推流到 10000 端口(设备端配置)
# 3. 查看流是否在线
GET /index/api/isMediaOnline?
secret=xxx&
schema=rtsp&
vhost=__defaultVhost__&
app=rtp&
stream=camera01
# 4. 获取流信息(包含所有播放地址)
GET /index/api/getMediaInfo?
secret=xxx&
schema=rtsp&
vhost=__defaultVhost__&
app=rtp&
stream=camera01
# 返回包含:
# - RTSP: rtsp://server:554/rtp/camera01
# - RTMP: rtmp://server:1935/rtp/camera01
# - HTTP-FLV: http://server:80/rtp/camera01.live.flv
# - HLS: http://server:80/rtp/camera01/hls.m3u8
# - WebRTC: webrtc://server/rtp/camera01
```
### 场景 2: RTMP 推流
```bash
# 1. 使用 OBS 或 FFmpeg 推流
ffmpeg -re -i input.mp4 -c copy -f flv rtmp://server:1935/live/mystream
# 推流地址格式: rtmp://服务器IP:端口/app/stream
# - app: 应用名(如 live
# - stream: 流ID如 mystream
# 2. 查看流列表
GET /index/api/getMediaList?secret=xxx
# 返回所有在线流,包含:
# {
# "code": 0,
# "data": [{
# "app": "live",
# "stream": "mystream",
# "vhost": "__defaultVhost__",
# "schema": "rtmp",
# "readerCount": 0, // 观看人数
# "totalReaderCount": 0,
# "originType": 0, // 0=推流1=拉流代理2=点播
# "originUrl": "",
# "createStamp": 1234567890
# }]
# }
# 3. 获取该流的详细信息和播放地址
GET /index/api/getMediaInfo?
secret=xxx&
schema=rtmp&
vhost=__defaultVhost__&
app=live&
stream=mystream
# 4. 播放地址:
# - RTSP: rtsp://server:554/live/mystream
# - RTMP: rtmp://server:1935/live/mystream
# - HTTP-FLV: http://server:80/live/mystream.live.flv
# - HLS: http://server:80/live/mystream/hls.m3u8
# - WebSocket-FLV: ws://server:80/live/mystream.live.flv
```
### 场景 3: 录制流
```bash
# 1. 开始录制MP4 格式)
GET /index/api/startRecord?
secret=xxx&
type=1& # 0=HLS, 1=MP4
vhost=__defaultVhost__&
app=live&
stream=mystream&
max_second=3600 # 每小时切片
# 2. 检查是否正在录制
GET /index/api/isRecording?
secret=xxx&
type=1&
vhost=__defaultVhost__&
app=live&
stream=mystream
# 3. 获取录像文件列表
GET /index/api/getMp4RecordFile?
secret=xxx&
vhost=__defaultVhost__&
app=live&
stream=mystream&
period=2025-12-09 # 指定日期
# 返回:
# {
# "code": 0,
# "data": {
# "paths": [
# "/path/to/record/live/mystream/2025-12-09/10-30-00.mp4",
# "/path/to/record/live/mystream/2025-12-09/11-30-00.mp4"
# ],
# "rootPath": "/path/to/record"
# }
# }
# 4. 停止录制
GET /index/api/stopRecord?
secret=xxx&
type=1&
vhost=__defaultVhost__&
app=live&
stream=mystream
```
### 场景 4: 截图
```bash
# 1. 获取实时截图
GET /index/api/getSnap?
secret=xxx&
url=rtsp://server/live/mystream&
timeout_sec=10&
expire_sec=60 # 缓存时间
# 返回: JPEG 图片数据
# 2. 如果配置了定时截图,查看截图列表
# 截图通常保存在配置的 snap 目录下
# 目录结构: /snap/vhost/app/stream/timestamp.jpg
# 3. 删除截图
GET /index/api/deleteSnapDirectory?
secret=xxx&
vhost=__defaultVhost__&
app=live&
stream=mystream&
file=1234567890.jpg # 可选,不指定则删除整个目录
```
### 场景 5: 下载录像文件
```bash
# 1. 获取录像文件列表见场景3
GET /index/api/getMp4RecordFile?
secret=xxx&
vhost=__defaultVhost__&
app=live&
stream=mystream&
period=2025-12-09
# 2. 下载指定文件
GET /index/api/downloadFile?
file_path=/path/to/record/live/mystream/2025-12-09/10-30-00.mp4&
save_name=mystream_20251209_103000.mp4
# 浏览器会直接下载该文件
```
---
## 三、API 分类与关系图
### 1. 流管理类
```
getMediaList # 获取所有流列表
getMediaInfo # 获取单个流详细信息
isMediaOnline # 检查流是否在线
close_stream # 关闭单个流
close_streams # 批量关闭流
getMediaPlayerList # 获取流的播放者列表
```
### 2. 连接管理类
```
getAllSession # 获取所有TCP/UDP连接
kick_session # 断开单个连接
kick_sessions # 批量断开连接
```
### 3. 代理管理类
```
# 拉流代理
addStreamProxy # 添加拉流代理
delStreamProxy # 删除拉流代理
listStreamProxy # 列出所有拉流代理
getProxyInfo # 获取代理详细信息
# 推流代理
addStreamPusherProxy # 添加推流代理
delStreamPusherProxy # 删除推流代理
listStreamPusherProxy # 列出所有推流代理
getProxyPusherInfo # 获取推流代理信息
# FFmpeg 代理
addFFmpegSource # 添加 FFmpeg 拉流
delFFmpegSource # 删除 FFmpeg 拉流
listFFmpegSource # 列出所有 FFmpeg 拉流
```
### 4. RTP/GB28181 类
```
openRtpServer # 创建 RTP 接收端口
closeRtpServer # 关闭 RTP 端口
connectRtpServer # TCP 主动连接模式
listRtpServer # 列出所有 RTP 服务器
getRtpInfo # 获取 RTP 推流信息
updateRtpServerSSRC # 更新 SSRC 过滤
pauseRtpCheck # 暂停超时检查
resumeRtpCheck # 恢复超时检查
```
### 5. RTP 推流类
```
startSendRtp # 主动模式推送 RTP
startSendRtpPassive # 被动模式推送 RTP
startSendRtpTalk # 双向对讲
stopSendRtp # 停止推送 RTP
listRtpSender # 列出 RTP 发送器
```
### 6. 录制类
```
startRecord # 开始录制
stopRecord # 停止录制
isRecording # 检查录制状态
getMp4RecordFile # 获取录像文件列表
deleteRecordDirectory # 删除录像目录
setRecordSpeed # 设置录像播放速度
seekRecordStamp # 设置录像播放位置
startRecordTask # 事件录制(前后录制)
```
### 7. 截图类
```
getSnap # 获取实时截图
deleteSnapDirectory # 删除截图目录
```
### 8. 文件类
```
loadMP4File # 点播 MP4 文件
downloadFile # 下载文件
```
### 9. 系统管理类
```
getApiList # 获取 API 列表
getServerConfig # 获取服务器配置
setServerConfig # 设置服务器配置
restartServer # 重启服务器
getStatistic # 获取统计信息
getThreadsLoad # 获取网络线程负载
getWorkThreadsLoad # 获取后台线程负载
version # 获取版本信息
```
---
## 四、关键流程图
### 流的生命周期
```
┌─────────────────────────────────────────────────────────┐
│ 流的来源 │
├─────────────────────────────────────────────────────────┤
│ 1. 推流: RTMP/RTSP/WebRTC 推流 │
│ 2. 拉流代理: addStreamProxy │
│ 3. FFmpeg 代理: addFFmpegSource │
│ 4. GB28181: openRtpServer + 设备推流 │
│ 5. 点播: loadMP4File │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 流在 ZLMediaKit 中 │
├─────────────────────────────────────────────────────────┤
│ - 唯一标识: vhost/app/stream │
│ - 自动协议转换: RTSP/RTMP/HLS/FLV/WebRTC 等 │
│ - 可被多个客户端同时播放 │
│ - 可被录制、截图、转推 │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 流的消费 │
├─────────────────────────────────────────────────────────┤
│ 1. 播放: 多协议播放地址 │
│ 2. 录制: startRecord │
│ 3. 截图: getSnap │
│ 4. 转推: addStreamPusherProxy │
│ 5. RTP 推送: startSendRtp │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 流的结束 │
├─────────────────────────────────────────────────────────┤
│ 1. 推流端断开 │
│ 2. 主动关闭: close_stream │
│ 3. 无人观看超时(配置决定) │
│ 4. 删除代理: delStreamProxy/delFFmpegSource │
└─────────────────────────────────────────────────────────┘
```
### GB28181 完整流程
```
1. 创建 RTP 服务器
openRtpServer(port=10000, stream_id=camera01)
2. 配置 GB28181 设备推流到 10000 端口
3. 流自动注册为: rtsp://__defaultVhost__/rtp/camera01
4. 查看流信息
getMediaInfo(schema=rtsp, app=rtp, stream=camera01)
5. 获取所有播放地址并播放
- RTSP: rtsp://server:554/rtp/camera01
- RTMP: rtmp://server:1935/rtp/camera01
- HTTP-FLV: http://server/rtp/camera01.live.flv
- HLS: http://server/rtp/camera01/hls.m3u8
6. 录制/截图/转推
startRecord(app=rtp, stream=camera01)
getSnap(url=rtsp://server/rtp/camera01)
addStreamPusherProxy(app=rtp, stream=camera01, dst_url=...)
7. 关闭流
closeRtpServer(stream_id=camera01)
```
---
## 五、常见问题
### Q1: 如何知道流的 stream_id
**A**:
- **推流时**: stream_id 由推流端指定(推流地址的最后一部分)
- **GB28181**: 在 `openRtpServer` 时指定
- **拉流代理**: 在 `addStreamProxy` 时指定
- **查询**: 使用 `getMediaList` 查看所有在线流
### Q2: 流的各种播放地址如何获取?
**A**: 使用 `getMediaInfo` 接口,返回结果包含所有协议的播放地址。
### Q3: 录像文件保存在哪里?
**A**:
- 默认路径在配置文件中设置(通常是 `./www/record`
- 目录结构: `record/vhost/app/stream/日期/时间.mp4`
- 可通过 `getMp4RecordFile` 查询
### Q4: 如何实现多平台推流?
**A**: 使用 `addStreamPusherProxy`,同一个流可以添加多个推流代理(不同 dst_url
### Q5: 拉流代理和 FFmpeg 代理如何选择?
**A**:
- **优先使用拉流代理**: 性能高,资源占用少
- **使用 FFmpeg 代理的场景**:
- 源协议 ZLMediaKit 不支持
- 需要转码
- 需要 FFmpeg 的特殊功能
### Q6: 如何实现按需拉流?
**A**: 配置 `on_play` hook当有人播放时才调用 `addStreamProxy` 拉取源流。
---
## 六、最佳实践
### 1. 流命名规范
```
app: 按业务分类live, record, vod, gb28181
stream: 使用有意义的IDcamera_01, user_123_live
```
### 2. 录制策略
```
- 重要流: 实时录制startRecord
- 事件流: 使用 startRecordTask前后录制
- 定时录制: 通过配置文件设置
```
### 3. 性能优化
```
- 使用拉流代理而非 FFmpeg 代理
- 合理设置录制切片时间
- 使用 HLS 时注意切片数量
- 监控 getThreadsLoad 和 getWorkThreadsLoad
```
### 4. 安全建议
```
- 修改默认 secret
- 启用推流鉴权on_publish hook
- 启用播放鉴权on_play hook
- 限制 API 访问 IP
```
---
## 七、快速参考
### 推流地址格式
```
RTMP: rtmp://server:1935/app/stream
RTSP: rtsp://server:554/app/stream (需要服务器支持 RTSP 推流)
```
### 播放地址格式
```
RTSP: rtsp://server:554/app/stream
RTMP: rtmp://server:1935/app/stream
HTTP-FLV: http://server:80/app/stream.live.flv
WebSocket-FLV: ws://server:80/app/stream.live.flv
HLS: http://server:80/app/stream/hls.m3u8
HTTP-TS: http://server:80/app/stream.live.ts
HTTP-fMP4: http://server:80/app/stream.live.mp4
WebRTC: webrtc://server/app/stream
```
### 常用 API 速查
```bash
# 查看所有流
curl "http://server:80/index/api/getMediaList?secret=xxx"
# 查看流信息
curl "http://server:80/index/api/getMediaInfo?secret=xxx&schema=rtsp&vhost=__defaultVhost__&app=live&stream=test"
# 开始录制
curl "http://server:80/index/api/startRecord?secret=xxx&type=1&vhost=__defaultVhost__&app=live&stream=test"
# 获取截图
curl "http://server:80/index/api/getSnap?secret=xxx&url=rtsp://server/live/test&timeout_sec=10" -o snap.jpg
# 关闭流
curl "http://server:80/index/api/close_stream?secret=xxx&schema=rtsp&vhost=__defaultVhost__&app=live&stream=test"
```

View File

@ -0,0 +1,499 @@
# WebRTC 与传统流媒体协议对比详解
## 一、协议类型说明
### 1. Schema协议类型在 ZLMediaKit 中的含义
在 ZLMediaKit 中,**schema** 是指流的**传输协议标识**,用于区分同一个流的不同协议版本。
```
完整流标识 = schema://vhost/app/stream
例如:
- rtsp://__defaultVhost__/live/test
- rtmp://__defaultVhost__/live/test
- rtc://__defaultVhost__/live/test ← WebRTC 的 schema 标识
```
**注意**: `rtc` 是 ZLMediaKit 中 WebRTC 协议的 schema 标识。
---
## 二、WebRTC vs 传统协议核心区别
### 对比表格
| 特性 | RTSP | RTMP | HLS | WebRTC (RTC) |
|------|------|------|-----|--------------|
| **传输协议** | TCP/UDP | TCP | HTTP | UDP (SRTP/DTLS) |
| **延迟** | 1-3秒 | 3-5秒 | 10-30秒 | 100-500毫秒 |
| **浏览器支持** | ❌ 需插件 | ❌ 需插件 | ✅ 原生支持 | ✅ 原生支持 |
| **NAT穿透** | ❌ 困难 | ❌ 困难 | ✅ 简单(HTTP) | ✅ 内置(ICE/STUN/TURN) |
| **双向通信** | ❌ 单向 | ❌ 单向 | ❌ 单向 | ✅ 双向 |
| **加密** | 可选(RTSPS) | 可选(RTMPS) | 可选(HTTPS) | ✅ 强制(DTLS-SRTP) |
| **带宽自适应** | ❌ | ❌ | ✅ 切换码率 | ✅ 实时调整 |
| **使用场景** | 监控/录像 | 直播推流 | 点播/直播 | 实时通信/低延迟直播 |
---
## 三、详细对比
### 1. RTSP (Real Time Streaming Protocol)
**特点**
- 专为流媒体设计的应用层协议
- 支持 TCP 和 UDP 传输
- 常用于视频监控、IPTV
**优点**
- 延迟低1-3秒
- 支持精确的流控制(暂停、快进、定位)
- 带宽占用小
**缺点**
- 浏览器不支持(需要插件或转码)
- NAT 穿透困难(特别是 UDP 模式)
- 防火墙不友好
**典型应用**
```bash
# 推流(需要支持 RTSP 推流的客户端)
rtsp://server:554/live/camera01
# 播放VLC、FFplay 等)
ffplay rtsp://server:554/live/camera01
```
---
### 2. RTMP (Real-Time Messaging Protocol)
**特点**
- Adobe 开发,基于 TCP
- 曾是直播行业标准
- Flash 时代的主流协议
**优点**
- 延迟较低3-5秒
- 推流稳定
- 生态成熟OBS、FFmpeg 等支持)
**缺点**
- 浏览器不再支持Flash 已淘汰)
- 只能单向传输
- 需要转码才能在浏览器播放
**典型应用**
```bash
# 推流OBS、FFmpeg
rtmp://server:1935/live/stream
# 播放(需要转为 HTTP-FLV 或 HLS
# 浏览器: http://server/live/stream.live.flv
```
---
### 3. HLS (HTTP Live Streaming)
**特点**
- Apple 开发,基于 HTTP
- 将流切片为小文件(.ts 或 .m4s
- 通过 .m3u8 索引文件播放
**优点**
- 浏览器原生支持
- CDN 友好HTTP 缓存)
- 自适应码率
**缺点**
- 延迟高10-30秒取决于切片大小
- 不适合实时互动
- 服务器需要存储切片文件
**典型应用**
```bash
# 播放地址
http://server/live/stream/hls.m3u8
# 浏览器中使用
<video src="http://server/live/stream/hls.m3u8" controls></video>
```
---
### 4. WebRTC (Web Real-Time Communication)
**特点**
- Google 主导的开放标准
- 专为实时通信设计
- 基于 UDP使用 SRTP 加密
**核心技术栈**
```
应用层: WebRTC API (getUserMedia, RTCPeerConnection)
信令层: SDP (会话描述) + ICE (连接协商)
传输层: SRTP (加密的 RTP) + DTLS (密钥交换)
网络层: UDP + ICE/STUN/TURN (NAT 穿透)
```
**优点**
- ✅ **超低延迟**100-500ms最低可达 100ms
- ✅ **浏览器原生支持**(无需插件)
- ✅ **双向通信**(音视频通话、屏幕共享)
- ✅ **强制加密**DTLS-SRTP
- ✅ **NAT 穿透**ICE/STUN/TURN
- ✅ **带宽自适应**(实时调整码率)
- ✅ **抗丢包**FEC、NACK、JitterBuffer
**缺点**
- ❌ 服务器实现复杂(需要信令服务器)
- ❌ 带宽消耗较大UDP 开销)
- ❌ 不适合大规模单向直播(推荐用 HLS/FLV
- ❌ 需要 HTTPS浏览器安全限制
**典型应用**
```javascript
// 浏览器播放 WebRTC 流
const pc = new RTCPeerConnection();
// 1. 获取 Offer从信令服务器
const offer = await fetch('http://server/webrtc/offer?app=live&stream=test');
// 2. 设置远端描述
await pc.setRemoteDescription(new RTCSessionDescription(offer));
// 3. 创建 Answer
const answer = await pc.createAnswer();
await pc.setLocalDescription(answer);
// 4. 发送 Answer 到服务器
await fetch('http://server/webrtc/answer', {
method: 'POST',
body: JSON.stringify(answer)
});
// 5. 接收媒体流
pc.ontrack = (event) => {
videoElement.srcObject = event.streams[0];
};
```
---
## 四、ZLMediaKit 中的 Schema 使用
### 1. Schema 的作用
在 ZLMediaKit 中,**同一个流可以同时以多种协议提供服务**schema 用于区分:
```bash
# 同一个流的不同协议版本
rtsp://__defaultVhost__/live/test # RTSP 协议
rtmp://__defaultVhost__/live/test # RTMP 协议
rtc://__defaultVhost__/live/test # WebRTC 协议
# 它们共享同一个媒体源,只是传输协议不同
```
### 2. API 中的 Schema 参数
```bash
# 查询流信息时需要指定 schema
GET /index/api/getMediaInfo?
secret=xxx&
schema=rtsp& # 指定协议类型
vhost=__defaultVhost__&
app=live&
stream=test
# 不同 schema 返回的信息可能不同:
# - rtsp: 返回 RTSP 相关信息RTP 统计等)
# - rtmp: 返回 RTMP 相关信息chunk size 等)
# - rtc: 返回 WebRTC 相关信息ICE 状态、DTLS 等)
```
### 3. 关闭流时的 Schema
```bash
# 关闭特定协议的流
GET /index/api/close_stream?
secret=xxx&
schema=rtsp& # 只关闭 RTSP 协议
vhost=__defaultVhost__&
app=live&
stream=test
# 注意:关闭一个 schema 会影响所有协议
# 因为它们共享同一个媒体源
```
---
## 五、WebRTC 在 ZLMediaKit 中的特殊性
### 1. WebRTC 的双重身份
WebRTC 在 ZLMediaKit 中既是**协议**,也是**技术栈**
```
作为协议 (schema=rtc):
- 用于标识 WebRTC 传输的流
- 在 API 中使用 schema=rtc 查询
作为技术栈:
- 包含信令、ICE、DTLS、SRTP 等完整实现
- 需要特殊的 API 端点(/index/api/webrtc
```
### 2. WebRTC 专用 API
ZLMediaKit 为 WebRTC 提供了专门的 API
```bash
# 1. 播放 WebRTC 流(浏览器端)
POST /index/api/webrtc?
app=live&
stream=test&
type=play
# 请求体: SDP Offer
# 返回: SDP Answer
# 2. 推流到 WebRTC浏览器端
POST /index/api/webrtc?
app=live&
stream=test&
type=push
# 3. WebRTC 信令服务器相关
addWebrtcRoomKeeper # 注册到信令服务器
delWebrtcRoomKeeper # 从信令服务器注销
listWebrtcRoomKeepers # 查看注册信息
listWebrtcRooms # 查看房间信息
# 4. 广播消息DataChannel
broadcastMessage # 向所有 WebRTC 播放器广播消息
```
### 3. WebRTC 流的生命周期
```
┌─────────────────────────────────────────────────────┐
│ WebRTC 推流(浏览器 → 服务器) │
├─────────────────────────────────────────────────────┤
│ 1. 浏览器创建 RTCPeerConnection │
│ 2. 生成 SDP Offer │
│ 3. POST /index/api/webrtc?type=push │
│ 4. 服务器返回 SDP Answer │
│ 5. ICE 候选交换 │
│ 6. DTLS 握手 + SRTP 密钥协商 │
│ 7. 媒体流传输UDP/SRTP
│ 8. 流注册为: rtc://__defaultVhost__/live/test │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ 协议自动转换ZLMediaKit 核心能力) │
├─────────────────────────────────────────────────────┤
│ WebRTC 推流后,自动提供多协议播放: │
│ - rtc://server/live/test (WebRTC) │
│ - rtsp://server/live/test (RTSP) │
│ - rtmp://server/live/test (RTMP) │
│ - http://server/live/test.flv (HTTP-FLV) │
│ - http://server/live/test/hls.m3u8 (HLS) │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ WebRTC 播放(服务器 → 浏览器) │
├─────────────────────────────────────────────────────┤
│ 1. 浏览器创建 RTCPeerConnection │
│ 2. 生成 SDP Offer │
│ 3. POST /index/api/webrtc?type=play │
│ 4. 服务器返回 SDP Answer │
│ 5. ICE 候选交换 │
│ 6. DTLS 握手 + SRTP 密钥协商 │
│ 7. 接收媒体流UDP/SRTP
│ 8. 渲染到 <video> 元素 │
└─────────────────────────────────────────────────────┘
```
---
## 六、使用场景选择
### 1. 视频监控系统
```
推荐: RTSP (推流) + HTTP-FLV/HLS (播放)
原因:
- 摄像头通常支持 RTSP
- 浏览器播放用 HTTP-FLV低延迟或 HLS兼容性好
- 不需要 WebRTC 的双向通信能力
```
### 2. 直播平台
```
推荐: RTMP (推流) + HTTP-FLV/HLS (播放)
原因:
- OBS 等工具支持 RTMP 推流
- HTTP-FLV 延迟低3-5秒
- HLS 兼容性好CDN 友好
- 大规模分发WebRTC 成本高
```
### 3. 视频会议/在线教育
```
推荐: WebRTC (双向)
原因:
- 需要双向音视频通信
- 延迟要求极低(<500ms
- 浏览器原生支持,无需插件
- 需要屏幕共享、白板等互动功能
```
### 4. 低延迟直播(电商带货、游戏直播)
```
推荐: WebRTC (播放) + RTMP (推流)
原因:
- 主播用 OBS 推 RTMP 流
- 观众用 WebRTC 播放(延迟 <500ms
- 实现"秒级"互动
- ZLMediaKit 自动协议转换
```
### 5. 录像回放
```
推荐: HLS 或 HTTP-FLV
原因:
- 不需要实时性
- HLS 支持拖拽、快进
- CDN 缓存友好
```
---
## 七、实战示例
### 示例 1: RTMP 推流 + WebRTC 播放(低延迟直播)
```bash
# 1. OBS 推 RTMP 流
推流地址: rtmp://server:1935/live/anchor01
# 2. 流自动注册,支持多协议
rtmp://server/live/anchor01
rtsp://server/live/anchor01
rtc://server/live/anchor01
http://server/live/anchor01.live.flv
http://server/live/anchor01/hls.m3u8
# 3. 浏览器用 WebRTC 播放(超低延迟)
```
```html
<!-- 浏览器端代码 -->
<video id="video" autoplay controls></video>
<script>
async function playWebRTC() {
const pc = new RTCPeerConnection();
// 创建 Offer
const offer = await pc.createOffer({
offerToReceiveAudio: true,
offerToReceiveVideo: true
});
await pc.setLocalDescription(offer);
// 发送 Offer 到服务器
const response = await fetch('http://server/index/api/webrtc?app=live&stream=anchor01&type=play', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
sdp: offer.sdp,
type: offer.type
})
});
const answer = await response.json();
// 设置 Answer
await pc.setRemoteDescription(new RTCSessionDescription({
type: 'answer',
sdp: answer.sdp
}));
// 接收媒体流
pc.ontrack = (event) => {
document.getElementById('video').srcObject = event.streams[0];
};
}
playWebRTC();
</script>
```
### 示例 2: 查询不同协议的流信息
```bash
# 查询 RTSP 协议的流信息
curl "http://server/index/api/getMediaInfo?secret=xxx&schema=rtsp&vhost=__defaultVhost__&app=live&stream=test"
# 返回:
{
"code": 0,
"schema": "rtsp",
"vhost": "__defaultVhost__",
"app": "live",
"stream": "test",
"tracks": [...],
"rtsp_url": "rtsp://server:554/live/test",
"rtp_info": {...}
}
# 查询 WebRTC 协议的流信息
curl "http://server/index/api/getMediaInfo?secret=xxx&schema=rtc&vhost=__defaultVhost__&app=live&stream=test"
# 返回:
{
"code": 0,
"schema": "rtc",
"vhost": "__defaultVhost__",
"app": "live",
"stream": "test",
"tracks": [...],
"webrtc_url": "webrtc://server/live/test",
"ice_servers": [...]
}
```
---
## 八、总结
### Schema 的本质
- **Schema 是协议标识符**,用于区分同一个流的不同传输协议
- 在 ZLMediaKit 中,`rtc` 是 WebRTC 的 schema 标识
- 同一个流可以同时支持多个 schema协议转换
### WebRTC 的特殊性
- **WebRTC 不仅是协议,更是完整的实时通信技术栈**
- 包含信令、NAT 穿透、加密、拥塞控制等完整解决方案
- 适合低延迟、双向通信场景
### 协议选择原则
```
延迟要求 < 500ms WebRTC
需要双向通信 → WebRTC
浏览器播放 + 延迟 3-5秒 → HTTP-FLV
浏览器播放 + 延迟 10秒+ → HLS
监控/录像 → RTSP
推流 → RTMP/RTSP
```
### ZLMediaKit 的优势
- **自动协议转换**: 一次推流,多协议播放
- **统一管理**: 通过 schema 参数区分不同协议
- **灵活组合**: RTMP 推流 + WebRTC 播放 = 低延迟直播