架构
-
整理分为两层: 应用层、核心层
-
绿色部分是核心部分, 是WebRTC提供的核心功能;
-
紫色部分是浏览器提供的JS的API层; 即 浏览器对WebRTC核心层的C++ API 做了一层封装, 封装成了JS接口;
-
最上面的箭头是
上层应用了,上层应用可以在 浏览器中 直接访问 浏览器提供的API; -
最终调用到核心层【蓝色虚线框、可重载!!】 ###WebRTC核心层
-
C++ API:API数量较少,主要是PeerConnection; (PeerConnection的API又包含传输质量、传输质量报告、各种统计数据、各种流等) 【设计技巧: 对于上层来说,提供的API简单,方便应用层开发; 内部比较复杂;】
-
Session层【上下文管理层】: 如应用创建了音频、视频、非音视频的数据传输, 都可以在Session层做处理,做管理相关的逻辑;
-
【最重要】引擎层/传输层【核心】
-
音频、视频、传输 解耦
-
音频引擎:【Voice Engine】 ISAC/ILBC 编解码; NetEQ 【Buffer】 网络适配、防止网络抖动; 回音消除(echo canceler): 音视频重点,决定产品质量, WebRTC里提供了相关
非常成熟的算法,开发时只需要调节参数即可; 降噪(Noise Reduction)、自动增益; -
视频引擎:【Video Engine】 VP8、openH264 编解码; Video jitter buffer:防止视频抖动; Image enhancements:图像增强;
-
传输【Transport】 底层用的UDP,上层用的SRTP【即安全的、加密后的RTP】; Multiplexing:多个流复用同一个通道; P2P层【包括 STUN+TURN+ICE】; 所有的 音频视频的接收与发送, 都是通过传输层去做的, 传输层包括了泄漏的检测、网络链路质量检测, 根据情况估算网络带宽,根据网络带宽进行
音视频、文件等非音视频的传输;
-
-
硬件层 视频采集、渲染; 音频采集; 网络IO等; WebRTC的核心层中是没有视频的渲染的, 所有的渲染都需要 应用层 或者 浏览器层 自己做;
WebRTC目录结构
- WebRTC代码量大,目录多
- 实际开发中,可能需要我们修改WebRTC的代码,
所以,我们必须知道每个目录的功能、作用是什么;
补充说明
-
call,一个端一个call,多个端多个call;
-
module目录很大,也特别重要, 里边有很多子模块, 每个子模块也都非常重要;
-
pc:【重要目录,上层的一个统一接口层】 Peer Connection,代表一个连接, 连接下边就要有很多相关API了, 如, Stream 流; chain 轨【音频轨、视频轨、桌面轨】 【轨 即 一系列永不相交的平行线(线程), 即音频与视频与桌面处理,都是各自处理,互不交叉的】;
所以在Peer Connection中我们可以拿到流, 通过流我们可以拿到每一个多媒体, 还可以拿到所有媒体的统一信息、传输的统一信息等 -
p2p: 端对端的传输时,需要先检查p2p是否能打通; 相应的协议、工具、API等,放在这里;
-
rtc_base: 不同操作系统,如Window和Linux,之间的系统函数差别就特别大; 但是rtc_base都封装好了, 上层按照规范编写调用逻辑即可, 框架会判断是在哪个平台运行,并执行相应的代码; -
rtc_tool是音视频相关的测试;tool_webrtc是整个框架的测试; -
system_wrappers, 存放操作系统等操作代码, 不同系统不同文件存放;
以上是WebRTC最外层的目录, 下面看WebRTC目录下的Modules子目录 ##WebRTC Modules 目录
-
audio_coding: 上面的WebRTC架构图中 提到的 ISAC/ILBC、VP8等编解码器逻辑, 都是放在这个目录下的;
-
audio_device: 现在的WebRTC文件中关于Android、IOS的部分都放在sdk目录下了, 而之前的话, 所有的设备类型包括
Android、IOS、Window、Mac、Linux的逻辑都是在audio_device目录下的; 现在的话Android、IOS被提取出去, 这里放的是关于Window、Mac、Linux的文件; -
audio_mixer: 混音的概念: 比如现在有几个用户同时在说话, 这样子会产生多个
音频流, WebRTC则会把这几个音频流混合在一起, 这样子在传输的时候就比较方便, 减少了音频流总数; 那这个混音相关的逻辑文件,就放在audio_mixer这里; -
audio_processing: 音频前后处理:指
回音消除、降噪、增益等处理操作; -
bitrate_controller:码率、码流控制;
-
congestion_controller: 当我们检测到网络流量比较高的时候, 我们要做一些流量控制, 防止网络包把带宽打死; 相关处理逻辑 则 放在本文件夹下; -
探测码率之后,对码率做一个均衡的平滑的处理,再发送交互;
-
video_processing: 视频前后处理:指
回音消除、降噪、增益等处理操作; 如增加人脸识别功能也可以放在这个目录下;
WebRTC的运行机制
轨
- Track
- 视频与音频是不相交的,单独存放;
- 两路音频也是两路轨,不相交;
流
- MediaStream
- 借鉴了传统媒体流的概念; 传统媒体流中也包括了音频轨、视屏轨等;
WebRTC重要的类
-
MediaStream 传输媒体数据;
-
RTCPeerConnection【核心】 这个WebRTC中最为重要的类, 是一个大而全的类,包含了很多重要的功能;
设计优势: 在应用层应用时方便, 只需要创建一个RTCPeerConnection连接, 然后把一个MediaStream媒体流搭载上去, 随后的细节就不用管了, 其中所有的传输、寻路等细节, 都由RTCPeerConnection内部封装实现了,底层封装做了很多相关的工作; -
RTCDataChannel 非音视频的数据(如
文本文件、二进制数据等),都通过RTCDataChannel来传输;RTCDataChannel是通过RTCPeerConnection获取的; 传输非音视频的数据时, 应用层要做的, 就是拿到一个RTCDataChannel对象,把数据搭载上去即可;
PeerConnection调用过程
-
Worker 线程、Signaling线程, 创建
PeerConnectionFactory,PeerConnectionFactory可以 创建PeerConnection、LocalMediaStream、LocalVide/AudioTrack等; -
多方进行通讯时, 每一方(每一个参与单位)都是对应一个Stream;
调用时序图
-
首先应用层
Application【注意这里Application本身就是一个PeerConnectionObserver】, 创建出一个PeerConnectionFactory【CreatePeerConnectionFactory】; -
PeerConnectionFactory触发CreatePeerConnection、CreateLocalMediaStream、CreateLocalVideoTrack、CreateLocalAudioTrack创建了PeerConnection、MediaStream等等实例; -
然后通过
AddTrack, 把各种轨(track)加到流(LocalMediaStream)中去, 然后通过AddStream, 把流加到PeerConnection中; -
流加到连接之后, 会通过
CommitStreamChanges提交流的变化; 当流发生变化的时候, 会触发OnSignalingMessage事件,创造出一个offer【SDP描述信息】; -
有了
offer【SDP描述信息】之后, 就会通过应用层【Application】,通过信令, 发送到远端【Send offer to the remote peer】;
【SDP描述信息】内容: 有哪些音视频数据,音视频数据的格式分别是什么,传输地址是什么等;
-
远端收到数据后,则根据
offerSDP, 回复一个answerSDP【Get answer from the remote peer】, 交给本地信令; -
信令收到远端的
answerSDP之后, 会把信息传给本地PeerConnection【ProcessSignalingMessage】, 本地PeerConnection就会拿到对方的媒体流信息、传输端口、传输地址;
至此,远端和本地就打通连接, 可以相互传
媒体数据;
远端数据来的时候,PeerConnection还会将远端的流添加到Application中去; 【OnAddStream(注意区分AddStream)】