# 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 # 浏览器中使用 ``` --- ### 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. 渲染到