架构
整理分为两层:
应用层、核心层绿色部分是核心部分,
是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描述信息】内容:
有哪些音视频数据,音视频数据的格式分别是什么,传输地址是什么等;
远端收到数据后,则根据
offer
SDP,
回复一个answer
SDP【Get answer from the remote peer】,
交给本地信令;信令收到远端的
answer
SDP之后,
会把信息传给本地PeerConnection
【ProcessSignalingMessage
】,
本地PeerConnection
就会拿到对方的媒体流信息
、传输端口、传输地址;
至此,远端和本地就打通连接,
可以相互传媒体数据
;
-
远端数据
来的时候,
PeerConnection
还会将远端的流
添加到Application
中去;
【OnAddStream(注意区分AddStream)】
参考自: