stream-deploy/reademe/ZLM/ZLM_Protocols.md

500 lines
14 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.

# 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 播放 = 低延迟直播