WebRTC 介绍
- Google 开源
- 跨平台
- 用于浏览器
- 实时传输
- 100ms 延迟 通话质量非常好
- 200ms 延迟 通话质量比较优质
- 500ms 延迟 可以接受
- 超过1s 非常迟滞
- 音视频引擎
WebRTC 应用:
WebRTC 愿景:
学习 WebRTC 的难点:
学习路线:
学习内容:
学习收获:
WebRTC能做啥:
能学到什么:
google webrtc 示例:https://appr.tc/
WebRTC 原理与架构
WebRTC 整体架构:
WebRTC 的目录结构图:
WebRTC 两个基本概念:轨与流
- Track
- MediaStream
WebRTC重要类:
- MediaStream
- RTCPeerConnection
- RTCDataChannel
PeerConnection调用过程:
调用时序图:
对于上图中描述的PeerConnection建立的完整流程进行以下说明(上图是以ClientA主动向ClientB发起连接为例):
- 首先 ClientA 和 ClientB 均通过双向通信方式如 WebSocket 连接到 Signaling Server 上;
- ClientA 在本地首先通 GetMedia 访问本地的 media 接口和数据,并创建 PeerConnection 对象,调用其 AddStream 方法把本地的 Media 添加到 PeerConnection 对象中。对于 ClientA 而言,既可以在与 Signaling Server 建立连接之前就创建并初始化 PeerConnection 如阶段 1,也可以在建立 Signaling Server 连接之后创建并初始化 PeerConnection 如阶段 2;ClientB 既可以在上图的1阶段也可以在 2 阶段做同样的事情,访问自己的本地接口并创建自己的 PeerConnection 对象。
- 通信由 ClientA 发起,所以 ClientA 调用 PeerConnection 的 CreateOffer 接口创建自己的 SDP offer,然后把这个 SDP Offer 信息通过 Signaling Server 通道中转发给 ClientB;
- ClientB 收到 Signaling Server 中转过来的 ClientA 的 SDP 信息也就是 offer 后,调用 CreateAnswer 创建自己的 SDP 信息也就是 answer,然后把这个 answer 同样通过 Signaling server 转发给 ClientA;
- ClientA 收到转发的 answer 消息以后,两个 peers 就做好了建立连接并获取对方 media streaming 的准备;
- ClientA 通过自己 PeerConnection 创建时传递的参数等待来自于 ICE server 的通信,获取自己的 candidate,当 candidate available 的时候会自动回掉 PeerConnection 的 OnIceCandidate;
- ClientA 通过 Signling Server 发送自己的 Candidate 给 ClientB,ClientB 依据同样的逻辑把自己的 Candidate 通过 Signaling Server 中转发给 ClientA;
- 至此 ClientA 和 ClientB 均已经接收到对方的 Candidate,通过 PeerConnection 建立连接。至此 P2P 通道建立。
Web服务器原理与Nodejs搭建
Web服务器选型:
- Nodejs
- Nginx
- Apache
Web服务工作原理:
Nodejs工作原理:
JavaScript解析:
Nodejs 事件处理:
两个V8引擎:
最简单的http服务:
- require 引入http模块
- 创建http服务
- 侦听端口
启动Nodejs服务:
- node app.js
- nohub node app.js
- forever start app.js
- pm2 start app.js
Https基本原理:
Nodejs 搭建 https 服务:
- 生成 HTTPS证书
- 引入 HTTPS模块
- 指定证书位置,并创建 HTTPS 服务
真正的Web服务:
- 引用 express 模块
- 引入 server-index 模块
- 指定发布目录
JavaScript 必备知识回顾
基础知识:
- 变量与类型
- 基本运算
if/else
- for循环
- 函数
- 日志打印
变量与类型:
基本运算:
WebRTC设备管理
enumerateDevices:
JavaScript中的Promise:
WebRTC音视频数据采集
音视频采集API:
getUserMedia的不同实现:
适配置不同浏览器的方法:
https://webrtc.github.io/adapter/adapter-latest.js
WebRTC音视频采集约束:
视频约束详解:
width
height
宽高比例:
4:3
16:9
aspectRatio
frameRate
facingMode
- user - 前置摄像头
- environment - 后置摄像头
- left - 前置左侧摄像头
- right - 前置右侧摄像头
resizeMode
音频约束详解:
- volume -
范围 0 - 1.0
- sampleRate
- sampleSize - 一般16位
- echoCancellation - 回音消除
- autoGainControl - 是否在原有声音基础上增加音量
- noiseSuppression - 降噪
- latency - 延迟大小
- channelCount - 声道 乐器一般是双声道
- deviceID - 作用是多个设备切换
- groupID
WebRTC约束例子:
1 | { |
浏览器视频特效:
- CSS filter,
-webkit-filter/filter
- 如何将 video 与 filter 关联
- OpenGL/Metal/…
支持的特效种类:
保存图片是实现滤镜效果,可以对 canvas.data 进行数据修改。
MediaStream API 获取视频约束:
WebRTC音视频录制实战
WebRTC录制基本知识
MediaRecoder类:
WebRTC 捕获桌面
捕获桌面需要设置Chrome,具体 操作:chrome://flags/#enable-experimental-web-platform-features
- Experimental Web Platform features 设置为 enable
WebRTC信令服务器实现
如果没有信令服务器WebRTC之间是不能通信的。
两个client之间通信必须有两个信息通过信令服务器的:
- 媒体信息, SDP
- 网络信息
- 具体的业务
Socket.IO 发送消息:
给本次连接发送消息
1
socket.emit()
给某个房间内所有人发送消息
1
io.in(room).emit()
除本链接外,给某个房间内所有人发送消息
1
socket.to(room).emit()
除本链接外,给所有人发送消息
1
socket.broadcast.emit()
Socket.IO 客户端处理消息:
发送 action 命令
1
2S: socket.emit('action');
C: socket.on('action', function(){...});发送了一个 action 命令,还有 data 数据
1
2S: socket.emit('action', data);
C: socket.on('action', function(data){...});发送了 action 命令,还有两个数据
1
2S: socket.emit('action', arg1, arg2);
C: socket.on('action', function(arg1, arg2){...});发送了一个 action 命令,在 emit 方法中包含回调函数
1
2S: socket.emit('action', data, function(arg1, arg2){...};
C: socket.on('action', function(data, fn){fn('a', 'b');});
[实战] 通过 socket.io 实现信令服务器
改造服务端的基本流程:
- 安装 socket.io
- 引入 socket.io
- 处理 connection 消息
WebRTC网络基础补充:P2P/STUN/TRUN/ICE知识
WebRTC 网络传输基本知识
WebRTC 传输基本知识:
- NAT(Network Address Translator)
- STUN(Simple Traversal of UDP Through NAT)
- TURN(Travelsal Using Relays around NAT)
- ICE(Interactive Connectivity Establishment)
NAT 产生的原因:
- 由于IPv4的地址不够
- 处于网络安全的原因
NAT 的种类:
- 完全锥型 NAT(Full Cone NAT)
- 地址限制锥型 NAT(Address Restricted Cone NAT)
- 端口限制锥型 NAT(Port Restricted Cone NAT)
- 对称型 NAT(Symmetric NAT)
NAT 打洞原理
NAT 穿越原理:
- C1,C2 向 STUN 发消息
- 交换公网 IP 及 端口
- C1 -> C2,C2 -> C1,甚至是端口猜测
NAT 类型检测
公网 IP:
如果 Client 收到的 IP 和第一次发出去的 IP 是不一样的,则是对称型 NAT,如果是一样的需要进一步判断:
Client 通过 Port2 发送消息到 STUN Port1,STUN Server 通过 Port2 给 Client 回消息,如果 Client 能收到消息,则说明是 IP 限制型的;如果不能收到,则说明是端口限制型的:
【协议规范】STUN 协议一
STUN 介绍:
- STUN 存在的目的就是进行 NAT 穿越
- STUN 是典型的客户端 / 服务器模式。客户端发送请求,服务端进行响应
RFC STUN 规范:
RFC3489/STUN
SImple Traversal of UDP Trough NAT
RFC5389/STUN — 包含UDP和TCP
Session Traversal Utilities for NAT
STUN 协议:
- 包括 20 字节的 STUN header
- Body 中可以有 0 个或多个 Attribute
STUN header(RFC3489):
- 其中 2 个字节(16bit)类型
- 2 个字节(16bit)消息长度,不包括消息头
- 16 个字节(128bit)事物ID,请求与响应事物 ID 相同
STUN header(RFC5389)格式:
M 代表请求值,C 代表分类:
RFC5389 把私密类型去掉了:
【协议规范】STUN 协议二
Inter 机子都是小端模式:
【协议规范】TURN 协议
TURN 介绍:
- 其目的是解决对称 NAT 无法穿越的问题
- 其建立在 STUN 之上,消息格式使用 STUN 格式消息
- TURN Client 要求服务端分配一个公共 IP 和 Port 用于接受 或 发送数据
TURN 发送机制:
- Send 和 Data
- Channel
【协议规范】ICE 框架
Candidate 类型:
- 主机候选者
- 反射侯选者
- 中继候选者
ICE 具体做些什么:
- 收集 Candidate
- 对 Candidate Pair 排序
- 连通性检查
收集 Candidate:
- Host Candidate:本机所有 IP 和指定端口
- Reflexive Candidate:STUN/TURN
- Relay Candidate:TURN
什么是 SDP:
- SDP(Session Description Protocol) 它只是一种信息格式的描述标准,本身不属于传输协议,但是可以被其他传输协议用来交换必要的信息。
形成 Candidate Pair:
- 一方收集到所有候选者后,通过信令传给对方
- 同样,另一方收到候选者后,也做收集工作
- 当双方拿到全部列表后,将侯选者形成匹配对儿
连通性检查:
- 对侯选者进行优先级排序
- 对每个侯选对进行发送检查
- 对每个侯选对进行接收检查
网络协议分析方法 tcpdump 与 wireshark讲解
常用工具:
- Linux 服务端用 tcpdump
- 其它端 WireShark
网络协议分析方法 tcpdump 与 wireshark 实战
vim 打开二进制数据:
1 | :%!xxd |
WireShark 中的逻辑运算:
- 与:and 或 &&
- 或:or 或 ||
- 非:not 或 !
WireShark 中判断语句:
- 等于:eq 或 ==
- 小于:lt 或 <
- 大于:gt 或 >
- 小于等于:le 或 <=
- 大于等于:ge 或 >=
- 不等于:ne 或 !=
WireShark 按协议过滤:
- stun
- tcp
- udp
模拟STUN数据可以使用这个网站中的工具:https://webrtc.github.io/samples
Wireshark 按 IP 过滤:
1 | ip.dst == 192.168.1.2 |
WireShark 按 port 过滤:
1 | tcp.port == 8080 |
WireShark 过滤长度:
1 | udp.length < 30 |
WireShark 过滤内容:
TODO