WebRTC 概览
优点
- 跨平台:可以在Web、Android、iOS、Windows、MacOS、Linux环境下运行WebRTC应用。
- 实时传输:传输速度快,延迟低,适合实时性要求较高的应用场景。
- 音视频引擎:强大的音视频处理能力。
- 免插件:不需要安装任何插件,打开浏览器即可使用。
- 免费:虽然WebRTC技术已经较为成熟,集成了最佳的音视频引擎和十分先进的Codec,但仍是免费的。
- 强大的打洞能力:WebRTC技术包含了使用STUN、ICE、TURN、RTP-over-TCP的关键NAT和防火墙穿透技术,并支持代理。
- 主流浏览器支持:包括Chrome、Safari、Firefox、Edge等。
注意:
- WebRTC不是web的协议, iOS 和 Android同样适用
- 不是仅用来传输音视频的, 也能通过流传递文本数据, 文件
整体架构
- 第一个模块 Voice Engine(音频引擎), Voice Engine是一个包含了系列音频处理功能的框架,如音频采集、音频编解码、音频优化(包括降噪、回声消除等)等一系列的音频功能。
- 第二个模块Video Engine(视频引擎),Video Engine是一个包含了系列视频处理功能的框架,如视频采集、视频编解码、根据网络抖动动态修改视频传输质量、图像处理等。
- 第三个模块Transport(传输模块),在WebRTC中,数据传输除了音视频等流媒体数据之外,还可以传输文件、文本、图片等其他二进制数据,这些功能就是这个模块所提供的。
Web应用
Web API是面向第三方开发者的WebRTC标准API(JavaScript),使开发者能够容易地开发出类似于网络视频聊天的Web应用,最新的技术进展可以参考W3C的WebRTC文档,主要的
Web API
Web API是面向第三方开发者的WebRTC标准API(JavaScript),使开发者能够容易地开发出类似于网络视频聊天的Web应用,最新的技术进展可以参考W3C的WebRTC文档,主要的API如下:
- MediaStream:媒体数据流,如音频流、视频流等,允许你访问输入设备,如麦克风/web摄像机。
- RTCPeerConnection:该类很重要,提供了应用层的调用接口。允许用户在两个浏览器之间直接通讯。你可以通过网络将捕获的音频和视频流实时发送到另一个WebRTC端点。
- RTCDataChannel:传输非音视频数据,如文字、图片等。
WebRTC的API接口非常丰富,更多详细的API可以参考WebRTC_API,该文档提供了中文说明。
C++ API
底层API使用C++语言编写,使浏览器厂商容易实现WebRTC标准的Web API,抽象地对数字信号过程进行处理。如RTCPeerConnection API是每个浏览器之间点对点连接的核心,RTCPeerConnection是WebRTC组件,用于处理点对点间流数据的稳定和有效通信。
Session Management
Session Management是一个抽象的会话层,提供会话建立和管理功能。该层协议留给应用开发者自定义实现。对于Web应用,建议使用WebSocket技术来管理信令Session。信令主要用来转发会话双方的媒体信息和网络信息。
Transport
Transport为WebRTC的传输层,涉及音视频的数据发送、接收、网络打洞等内容,可以通过STUN和ICE组件来建立不同类型的网络间的呼叫连接。
SRTP
-
SRTP属于传输模块中的内容,在了解SRTP之前我们先来了解一下RTP。
-
RTP 是(Real Time Protocol)提供了具有实时特征的、端到端的数据传送服务协议。而我们通常所说的RTCP等则是对RTP的控制协议。
-
RTP不像http和ftp等可完整的下载整个影视文件,它是以固定的数据格式在网络上发送数据,如果RTP的头部几个字节表示什么,音频数据或者视频数据包含在RTP中那几个字节中等等。
-
在RTP中,并未考虑到数据传输的安全性,比如没有加密功能,所以不符合安全性要求较高的应用需求,因此为了解决此问题,SRTP应运而生。
-
SRTP(SecureReal-time Transport Protocol)是在RTP的基础上加入了安全机制的传输协议,SRTP为数据提供了加密、消息认证、完整性保证和重放保护等功能,最大程度保障了数据传输的安全性。
所以RTP与SRTP的关系大概就是http与https的关系。
Multiplexing
Multiple exing,通道复用,即多个流数据传输共用一个通道, 以此提高传输效率。目前也不知道啥原理怎么复用。
P2P STUN+TURN+ICE
WebRTC是一种基于P2P的通信技术。而STUN、TURN、ICE这些则是实现P2P的一些关键技术。
STUN、TURN、ICE又成为NAT穿透,在现实生活中不同局域网中的内外ip是无法直接通信的,比如说局域网A中192.168.2.1与局域网B中192.168.2.2是无法互相直接发送消息的, 那么如果要在两个不同的局域网中建立起可以直接通信的通道就得依靠STUN+TURN+ICE这些技术。
而STUN、TURN和ICE又是使用不同方案进行穿透的,三言两语也说不清,待补充更详细的。
STUN/TURN服务器
STUN和TURN都是网络协议。基于这个协议搭建的服务器,就简单称STUN/TURN服务器。 STUN(Session Traversal Utilities for NAT)用于得到终端的外网IP&端口!让终端之间,尝试能否根据外网IP&端口直接通信。当然了,STUN并不是每次都能成功的为需要NAT的通话设备分配IP地址,如果失败了,则需要下面的TURN做辅助。 TURN(Traversal Using Relays around NAT)用于终端之间,无法直接P2P通信的时候,做一个中继服务!简单的说,终端A把音视频传递给TURN服务器,终端B从TURN服务器读取A的音视频数据。
ICE
ICE(Interactive Connectivity Establishment, 综合性NAT穿越技术)框架整合各种NAT穿越技术如STUN、TURN(Traversal Using Relay NAT,中继NAT实现的穿透),ICE先使用STUN尝试建立一个基于UDP的连接,失败后实用TCP(先尝试HTTP然后尝试HTTPS),若依然失败,ICE就会使用中继的TURN服务器。
VoiceEngine
VoiceEngine(音频引擎)是包含一系列音频多媒体处理的框架,包括从音频采集到网络传输端等整个解决方案。VoiceEngine是WebRTC极具价值的技术之一,是Google收购GIPS公司后开源的,目前在VoIP技术上处于业界领先地位。主要模块如下:
- iSAC(Internet Speech Audio Codec)是针对VoIP和音频流的宽带和超宽带音频编解码器,是WebRTC音频引擎的默认编解码器。
- iLBC(Internet Low Bitrate Codec)是VoIP音频流的窄带语音编解码器。
- NetEQ For Voice是针对音频软件实现的语音信号处理元件。NetEQ算法是自适应抖动控制算法以及语音包丢失隐藏算法,该算法能够快速且高解析度地适应不断变化的网络环境,确保音质优美且缓冲延迟最小,是GIPS公司独特的技术,能够有效地处理网络抖动和语音包丢失时对语音质量产生的影响。NetEQ也是WebRTC中一个极具价值的技术,对于提高VoIP质量有明显效果,与AEC、NR、AGC等模块集成使用效果更好。
- Acoustic Echo Canceler(AEC,回声消除器)是一个基于软件的信号处理元件,能实时地去除Mic采集到的回声。
- Noise Reduction(NR,噪声抑制)也是一个基于软件的信号处理元件,用于消除与相关VoIP的某些类型的背景噪声(如嘶嘶声、风扇噪音等)。
VideoEngine
VideoEngine是WebRTC视频处理引擎,包含一系列视频处理的整体框架,从摄像头采集视频到视频信息网络传输再到视频显示,是一个完整过程的解决方案。主要模块如下:
- VP8是视频图像编解码器,也是WebRTC视频引擎默认的编解码器。VP8适合实时通信应用场景,因为它主要是针对低延时而设计的编解码器。VPx编解码器是Google收购ON2公司后开源的,现在是WebM项目的一部分,而WebM项目是Google致力于推动的HTML5标准之一。
- Video Jitter Buffer(视频抖动缓冲器)模块可以降低由于视频抖动和视频信息包丢失带来的不良影响。
- Image Enhancements(图像质量增强)模块对网络摄像头采集到的视频图像进行处理,包括明暗度检测、颜色增强、降噪处理等功能,用来提升视频质量。
webRTC连接过程
两个设备之间建立 webRTC 需要什么?
- 需要两个设备之间交换地址(ICE),知道互相的存在,不然没办法联系上对方。这个在webrtc中是基于ICE的。
- 需要两个设备之间交换描述连接的多媒体内容标准(SDP),(例如分辨率,格式,编解码器,加密等)。方便一旦数据传输了,两个设备之间就可以相互理解。这里只是描述内容的元数据,而不是媒体内容本身。
但是ICE和SDP都没有办法自己传递,两个设备之间还不知道彼此的存在,因此需要中间的服务器(信令服务器)传递信息。
建立链接只需要经过3大步骤:
- 创建数据来源 createOffer
- 创建数据接收 createAnswer 完成SDP交换
- 交换 Candidate 完成ICE通信
大家可以看MDN 信令与视频通话上的流程
SDP 交换过程
- Naomi 通过createOffer生成SDP信息
- Naomi 通过setLocalDescription,设置本地描述信息
- Naomi 通过信令服务器将SDP发送给 Priya
- Priya 通过setRemoteDescription,设置远端描述信息
- Priya 通过createAnswer创建自己的SDP信息
- Priya 通过setLocalDescription,设置本地描述信息
- Priya 通过信令服务器将SDP发送给 Naomi
- Naomi 通过setRemoteDescription,设置远端描述信息
- 以上步骤就完成了SDP的交换。
这里思考一个问题:完成SDP交换以后
- Naomi 和 Priya 的通信链路打通了吗?怎么证明?
- 是在什么时候触发的 Naomi 和 Priya 链路打通的呢?怎么证明?
我们查看 webrtc 的例子 发现在 Naomi 和 Priya 交换了 SDP 信息后,两端的数据并没有打通。但这个时候出发了icecandidate事件,单纯触发了时间也并没有打通两端。这个时候只要将candidate getOtherPc(pc).addIceCandidate(event.candidate) 信息给到双端,双端就能通信了。 所以SDP交换后双端并没有打通,把candidate信息给到ICE后才会打通双端。
这里思考一个问题:
- 需要把candidate信息给到ICE一端就能打通,还是双端都需要设置呢?
candidate 信息包含了自身的IP,端口等。
ICE 候选交换过程
- Naomi 生成SDP后触发
icecandidate事件,包含了由SDP字符串表示的ICE候选 - Naomi 将候选信息通过信令服务器发送给 Priya
- Priya 创建一个候选信息对象
// 只是例子 const candidate = { candidate: candidateInfo.candidate, sdpMid: candidateInfo.id, sdpMLineIndex: candidateInfo.label, } - Priya 通过addIceCandidate将候选信息对象发送给ICE
- Priya 开始往 Naomi 发送数据
- Priya 生成SDP后触发
icecandidate事件,包含了由SDP字符串表示的ICE候选 - Priya 将候选信息通过信令服务器发送给 Naomi
- Naomi 创建一个候选信息对象
- Naomi 通过addIceCandidate将候选信息对象发送给ICE
- Naomi 开始往 Priya 发送数据
ICE 候选交换过程 ICE 层接收候选时,都会将其发送给另一方;不存在轮流或成批的候选。一旦两端就一个候选达成一致,双方就都可以用此候选来交换媒体数据,媒体数据就开始流动。即使在媒体数据已经开始流动之后,每一端都会继续向候选发送消息,直到他们没有选择的余地。这样做是为了找到比最初选择的更好的选择。
这里思考一个问题:
- 如果我想更改码率等信息怎么办?那么就需要重新构建交换SDP信息。
- 如果明白了SDP和ICE链接,那么应该可以看懂RTS信令协议规范
webRTC SDP和ICE详解
入门知识资料
WebRTC bilibili: www.bilibili.com/video/BV1BU…
LATM 参考:Application-Bulletin_AAC-Transport-Format
音频编码参考:csclub.uwaterloo.ca/~ehashman/I…
AAC 协议族:www.indexcom.com/wp-content/…
SDP 协商:www.rfc-editor.org/rfc/rfc4566
webrtc 官方中文入门文档:webrtc.org/getting-sta…
webrtc官方demo: github.com/webrtc/samp…
MDN 上webrtc 信令与视频通话连接过程:developer.mozilla.org/zh-CN/docs/…
captureStrea官方文档:developer.mozilla.org/en-US/docs/…