WebRTC源码研究01-WebRTC架构

发布于 2023-04-18 | 作者: 极客雨露 | 来源: CSDN博客 | 转载于: CSDN博客

源码研究(1)WebRTC架构

本人最近主要聚焦于音视频领域的学习,学习了很多相关视频和书籍,目前还在学习中,写的这些博客很多内容都是来源于慕课网李超老师的视频,想学习音视频的强烈建议去购买李超老师的视频,讲的很好,价格不贵 ,购买李超老师的视频点击这里

WebRTC 是一个音视频通信的百宝箱,给音视频处理和即时通讯提供了成熟的解决方案。关键是这个方案的源码是开源的,你可以深入研究这些源码,学习里面的解决疑难问题的算法,应用在你的项目中。 WebRTC是一个非常优秀的多媒体框架,具有跨平台的特性。

更多详情请参考:

1. WebRTC简介

WebRTC,名称源自网页即时通信(英语:Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的API。它于2011年6月1日开源并在Google、Mozilla、Opera支持下被纳入万维网联盟的W3C推荐标准。

WebRTC是为了解决 Web 端无法捕获音视频的能力,并且提供了 peer-to-peer(就是浏览器间)的视频交互。

WebRTC汇集了先进的实时通信技术,包括:先进的音视频编解码器(Opus和VP8/9),强制加密协议(SRTP和DTLS)和网络地址转换器(ICE&STUN)。

  1. WebRTC实现了基于网页的视频会议,标准是WHATWG 协议,目的是通过浏览器提供简单的javascript就可以达到实时通讯(Real-Time Communications (RTC))能力。
  2. WebRTC(Web Real-Time Communication)项目的最终目的主要是让Web开发者能够基于浏览器(Chrome\FireFox…)轻易快捷开发出丰富的实时多媒体应用,而无需下载安装任何插件,Web开发者也无需关注多媒体的数字信号处理过程,只需编写简单的Javascript程序即可实现,W3C等组织正在制定Javascript 标准API,目前是WebRTC 1.0版本,Draft状态;另外WebRTC还希望能够建立一个多互联网浏览器间健壮的实时通信的平台,形成开发者与浏览器厂商良好的生态环境。同时,Google也希望和致力于让WebRTC的技术成为HTML5标准之一,可见Google布局之深远。
  3. WebRTC提供了视频会议的核心技术,包括音视频的采集、编解码、网络传输、显示等功能,并且还支持跨平台:windows,linux,mac,android。

2. WebRTC的能力

根据最初的定义,WebRTC被指定为P2P(peer-to-peer)技术。

自成立以来,WebRTC已经大大降低了Web开发人员通过简单的Java API构建实时通信应用程序的难度。
但要清楚,WebRTC是一种技术,而不是一个完整的应用程序或服务。我们可以认为WebRTC就是音视频领域的一个百宝箱,它并不是一个创新的技术,而是将以往的音视频技术一统江湖,融合在一起,做了一定的优化处理。它里面关于音视频处理的算法很多都可以抠出来用在不同场合。

目前来看,WebRTC在电视会议和直播领域有很大的潜力。

虽然WebRTC最初被设想为纯粹的P2P技术,但许多日常业务应用程序需要集中式媒体功能,通过P2S(peer-to-server)架构提高可靠性、效率或扩展性。
对于P2P和P2S架构之间的问题对于构建WebRTC应用程序很重要。

WebRTC 为了不限制服务器相关技术发展,并没有将信令SDP 等服务器技术统一标准,每个开发者可以根据自己的情况去选择信令服务器。

WebRTC 是一个音视频处理+ 即时通讯的开源库,它是一个非常优秀的多媒体框架,而且还跨平台。在音视频领域有两个泰山北斗级别的开源库,一个是FFmpeg, 另一个就是WebRTC 。他们拥有各自不同的侧重点,优势。FFmepg的侧重点是多媒体的编辑,音视频的编解码等对视频文件的处理。 而对于WebRTC, 它的优势是整个网络中实现音视频的传输,对网络的抖动,丢包,网络的评估,在网络层面的各自算法优化保证了音视频传输的稳定,此外它还可以对网络传输经常发生的回音等问题优化处理,如回音消除,降噪。

总的来说,WebRTC能做下面这些事情:

2.1 抓住属于WebRTC的5G时代风口

2.1.1 浏览器的支持情况

到目前为止,几乎所有主要的浏览器都兼容WebRTC,除了IE浏览器外,WebRTC现在得到了所有主要浏览器的支持和采用,包括谷歌Chrome、苹果Safari、Mozilla Firefox 、QQ浏览器、360浏览器和Microsoft Edge。

2.1.2 大厂的加入

2.1.3 WebRTC应用案例

2.1.3.1 教育行业解决方案

2.1.3.2 互动电商解决方案
2.1.3.3 企业视频协作/OA办公解决方案
2.1.3.4

3. webrtc架构

我们先来看一下网上广为流传的webrtc架构图,这张图来自WebRTC官网,另外可以参考WebRTC中文网

总体上来说看上面图可以知道整个浅绿色部分都属于WebRTC核心架构层,它封装各种提供给web端使用的Web API层接口。紫色的部分属于应用层,使用核心层提供的API。你可以在应用层扩展相关API,调用WebRTC核心层的接口。

WebRTC核心层又分为四层:

WebRTC最核心的三大模块:Voice Engine, Video Engine , Transport,这三个层中Voice Engine只处理音频相关的技术,Video Engine处理视频相关的技术,音频和视频是相互独立的,一个重要的技术:音视频同步并不包含在这里面。

Voice Engine 音频引擎包含3大模块:

Video Engine 视频引擎包含3大模块:

Transport 传输模块包含3大模块:
传输底层用的是UDP 协议,因为音视频传输对及时性要求更高,允许部分丢帧,WebRTC充分利用的UDP的不管控能力,利用各种成熟的算法保证高质量的音视频传输,可以自动适配码率变换。所有音视频的数据的发送,接收都是通过传输层去做的,从图中可以看出来,WebRTC的架构层次是非常清晰的。

整个传输层包括了对线路的检测,网络丢包,抖动,流控 ,NAT穿透打洞等等非常复查的技术都实现了非常成熟的方案。学好这块技术是非常有用的。

WebRTC传输层这块还实现了通过计算去估算你的网络带宽,不仅仅可以实现稳定的音视频传输,还可以传输其他非音视频数据,如文件,文本等二进制数据都可以传输。

需要注意的是,在WebRTC的核心层是没有视频的渲染的,视频的渲染需要应用层去做。

通过上面讲解,我们对WebRTC具备哪些能力,有了一个大致的理解,接下来我们来细分每个模块的功能项,讲解里面涉及的相关技术,知识,最后通过分析源码的方式更深入的理解,这样我们就可以自己编写代码,在项目中实战了。

3.1 Your Web App

Web开发者开发的程序,Web开发者可以基于集成WebRTC的浏览器提供的web API开发基于视频、音频的实时通信应用。

3.2 Web API

面向第三方开发者的WebRTC标准API(Javascript),使开发者能够容易地开发出类似于网络视频聊天的web应用,这些API可分成Network Stream APIRTCPeerConnectionPeer-to-peer Data API三类。WebRTC 标准官方文档

  1. MediaStream:用来表示一个媒体数据流。
  2. MediaStreamTrack: 在浏览器中表示一个媒体源。
  1. RTCPeerConnection: 一个RTCPeerConnection对象允许用户在两个浏览器之间直接通讯。
  2. RTCIceCandidate :表示一个ICE协议的候选者。
  3. RTCIceServer:表示一个ICE Server。
  1. DataChannel:数据通道( DataChannel)接口表示一个在两个节点之间的双向的数据通道 。

3.3 WebRTC Native C++ API

本地C++ API层,使浏览器厂商容易实现WebRTC标准的Web API,抽象地对数字信号过程进行处理。提供给浏览器开发者使用来开发JavaScript API。

3.4 Transport / Session

Session 组件是基于libjingle会话协商 + NAT穿透组件库 )开发
传输/会话层: 会话层组件采用了libjingle库的部分组件实现,无须使用xmpp/jingle协议

3.5 VoiceEngine

音频引擎是包含一系列音频多媒体处理的框架,包括从视频采集卡到网络传输端等整个解决方案。
VoiceEngine是WebRTC极具价值的技术之一,是Google收购GIPS公司后开源的。在VoIP上,技术业界领先.

WebRTC的音频部分,包含设备、编解码(iLIBC/iSAC/G722/PCM16/RED/AVT、NetEQ)、加密、声音文件、声音处理、声音输出、音量控制、音视频同步、网络传输与流控(RTP/RTCP)等功能。

3.5.1 音频、视频图像处理的主要数据结构

定义类型 头文件 简介 路径
Structures common_types.h 列出VoiceEngine & VideoEngine常见的结构
Enumerators common_types.h 列出VoiceEngine和VideoEngine通用的枚举数
Classes common_types.h 列出VoiceEngine和VideoEngine常见的类
class VoiceEngine voe_base.h 如何使用VoiceEngine类中的工厂方法为VoiceEngine分配和释放资源。它还列出了将文件跟踪和/或跟踪作为回调消息启用所需的api
class VideoEngine vie_base.h 如何使用VideoEngine类中的工厂方法为VideoEngine分配和释放资源。它还列出了将文件跟踪和/或跟踪作为回调消息启用所需的api

3.5.2 音频引擎(VoiceEngine)模块 APIs

下表列的是目前在 VoiceEngine中可用的sub APIs

定义类型 头文件 简介 路径
VoEAudioProcessing voe_audio_processing.h 增加对噪声抑制(NS),自动增益控制(AGC)和回声控制(EC)的支持。也包括接收方VAD。
VoEBase voe_base.h 启用全双工VoIP使用G.711。注意:必须始终创建此API
VoECallReport voe_call_report.h 增加对呼叫报告的支持,该报告包含心跳检测的数量、RTT度量和Echo度量。
VoECodec voe_codec.h 增加非默认编解码器(例如iLBC, iSAC, G.722等),语音活动检测(VAD)支持。
VoEDTMF voe_dtmf.h 增加电话事件传输,DTMF音频生成和电话事件检测。(电话事件包括DTMF。)
VoEEncryption voe_encryption.h 增加外部加密/解密支持扩展。
VoEErrors voe_errors.h 声音引擎的错误代码
VoEExternalMedia voe_external_media.h 添加对外部媒体处理的支持,并允许利用外部音频资源。
VoEFile voe_file.h 添加文件回放、文件录制和文件转换功能。
VoEHardware voe_hardware.h 增加声音设备处理,CPU负载监控和设备信息功能。
VoENetEqStats voe_neteq_stats.h 添加缓冲区统计功能。
VoENetwork voe_network.h 增加外部传输,端口和地址过滤,窗口QoS支持和包超时通知。
VoERTP_RTCP voe_rtp_rtcp.h 增加支持RTCP发送者报告,SSRC处理,RTP/RTCP统计,前向错误纠正(FEC), RTCP应用,RTP捕获和RTP保持活着。
VoEVideoSync voe_video_sync.h 添加RTP头修改支持,播放延迟调优和监控。
VoEVolumeControl voe_volume_control.h 添加扬声器音量控制、麦克风音量控制、静音支持和其他立体声缩放方法。

3.6 VideoEngine

VideoEngine是WebRTC视频处理引擎
VideoEngine是包含一系列视频处理的整体框架,从摄像头采集视频到视频信息网络传输再到视频显示整个完整过程的解决方案。

WebRTC的视频部分,包含采集、编解码(I420/VP8)、加密、媒体文件、图像处理、显示、网络传输与流控(RTP/RTCP)等功能。

3.6.1 视频引擎(VideoEngine)模块 APIs

定义类型 头文件 简介 路径
ViEBase vie_base.h 创建VideoEngine实例、通道和VoiceEngine交互的基本功能。
注意:必须始终创建此API。
ViECapture vie_capture.h 添加对捕获设备分配以及捕获设备功能的支持。
ViECodec vie_codec.h 增加非默认编解码器,编解码器设置和包丢失功能。
ViEEncryption vie_encryption.h 增加外部加密/解密支持。
ViEErrors vie_errors.h 视频引擎的错误代码
ViEExternalCodec vie_external_codec.h 增加了对使用外部编解码器的支持。
ViEFile vie_file.h 增加对文件记录,文件播放,背景图像和快照的支持
ViEImageProcess vie_image_process.h 增加效果滤镜,缩小,去噪和色彩增强。
ViENetwork vie_network.h 增加发送和接收功能,外部传输,端口和地址过滤,窗口QoS支持,包超时通知和改变网络设置。
ViERender vie_render.h 增加了渲染功能。
ViERTP_RTCP vie_rtp_rtcp.h 处理RTP/RTCP统计,NACK/FEC,保持活动功能和关键帧请求方法。

4. webrtc源码结构

WebRTC 源码作为 Chromium 的一部分,更新速度非常快,这得益于 Google 对音视频通信的大力推广。WebRTC 源码的结构也变化很快,主要体现在以下几方面:

其实webrtc在每个对应的平台上的源码都不相同,只是整体协议框架是一样的,在每个平台上的实现方式不一样,如android,ios ,js都实现了同样的协议功能,但是编码是使用每个平台自己的特性。

下面看通过知乎大神陈子兴的一个图来了解一下整体结构图如下:

4. 1 目录结构

如果按照通常层次化的思维来组织,从下到上,大概分以下几个层次:

m66 版本的代码为例,目录如下:

目录名 模块内容 简介 路径
api 提供了对外的接口,音视频引擎层和 Module 直接的接口。
audio 音频流的一部分抽象,属于引擎的一部分逻辑。
base 这一部分还没有学习到,属于 Chromium 项目的一部分,貌似 WebRTC 中用的并不多。
build 编译脚本。这里需要注意的是,不同平台的代码在下载的时候,获取的工具集是不一样的。
build_overrides 编译工具。
buildtools 编译工具链。
call 主要是媒体流的接口抽象。为媒体引擎和 codec 层提供桥接。这里说的媒体流是 RTP 流。pc 层也抽象了媒体流,那是编码前、或者解码后。
common_audio 音频算法实现,比如 fft。
common_video 视频算法实现,比如 h264 协议格式。
data 测试数据
examples WebRTC 使用的例子。提供了 peerconnection_client、peerconnection_server、stun、turn 的 demo。
help 帮助信息。
infra 工具。
logging WebRTC 的 log 库。
media 媒体引擎层,包括音频、视频引擎实现。
modules WebRTC 把一些逻辑比较独立的抽象为 Module,利于扩展维护。
ortc 媒体描述协议,类似 sdp 协议。
out build 输出目录,这是 webrtc 官方编译指导中示范目录。
p2p 主要是实现 candidate 收集,NAT 穿越。
pc 实现 jsep 协议。
resources 测试数据
rtc_base 包括 Socket、线程、锁等 OS 基础功能实现。
rtc_tools 网络监测工具、音视频分析工具。很多工具都是脚本实现。
sdk 主要是移动端相关实现。
stats WebRTC 统计模块实现。
style-guide 编码规范说明
system_wrappers OS 相关功能的封装,比如 cpu、clock 等。
test 单元测试代码实现,用 gmock
testing gmock、gtest等源码,属于整个 Chromium 项目。
third_party 第三方库依赖。比如,boringssl,abseil-cpp,libvpx等
tools 公共工具集,整个 Chromium 项目依赖的。
tools_webrtc WebRTC 用到的工具集。比如代码检查 valgrind 的使用。
video 视频 RTP 流的抽象接口,属于视频引擎的一部分。

4.2 核心模块

4.2.1 PeerConnection:

PeerConnection 的主要实现逻辑就是在 WebRTC 源码的 pc 目录下。

一切都从 PeerConnectionFactory 和 PeerConnection 开始,对外提供 PeerConnectionFactoryInterface 和 PeerConnectionInterface 两个接口类。Factory 类,顾名思义就是创建 PeerConnection 的,下来我们只讨论 PeerConnection。

也许你已经非常熟悉 WebRTC 的 JavaScript 接口。比如,RTCPeerConnection,setLocalDescription、setRemoteDescription、createOffer、createAnswer 等,没错这些。JavaScript 接口的 Native 实现就是在 PeerConnection 中完成的,它也有对应的一套接口。JavaScript 这套接口实现规范是JSEP。 可以说是把这套规范的模型都给实现了。

WebRTC 终端之间的通信协议是 ICE 协议,书包格式采用 SDP 协议。PeerConnection 实现了 SessionDescription 的逻辑。

PeerConnection 抽象了 RtpTransceiver,RtpSender、RtpReceiver 模型,对应了 sdp 中描述的媒体的实现。

4.2.2 Module

WebRTC 将逻辑功能独立、内聚性、复用性强的部分单独抽象为模块。模块在 WebRTC 源码的 modules 目录下,主要是音视频设备、codec、流控等。

4.2.3 网络传输模块:libjingle

WebRTC重用了libjingle的一些组件,主要是network和transport组件

5 WebRTC学习资料

5.1 书籍

本书的作者是 艾伦 B.约翰斯顿 (Alan B.Johnston) 丹尼尔 C.伯内特 (Daniel C.Burnett) 。 第三版展示了如何实现浏览器之间直接发送实时文本的数据通道功能。此外,还涉及 浏览器媒体协商过程中的完整描述(Firefox和Chrome的SDP会话描述),如何使用 Wireshark来监控WebRTC协议的注意事项以及例子捕捉。另外,支持NAT和防火墙穿透 的TURN服务器也是第三版新加入的内容。

本书作者是丹·里斯蒂克 (Dan Ristic) (作者)。它更像是一份简单的教程,一步步带你开 发一个简单的应用。并且,在书本中还加入了如果做文件共享功能的示例。

5.2 大神博客

5.3 Demo实例代码

下面几个是WebRTC开发者社区的:

几个跨平台开发中可用的 WebRTC Demo:

webrtc-uwp PeerCC-Sample:这个例子实现的是WebRTC UWP(Universal Windows Platform) App
包含PeerConnection示例WebRTC示例,用于在两个对等点之间建立音频/视频调用。它包括一个预编译的信号服务器,并引用了WebRTC UWP NuGet包,这使它成为在UWP上启动和运行WebRTC的最快方式。这个示例还包括Unity支持以及针对HoloLens和混合现实开发的特性。对于引用完整的WebRTC UWP源代码而不是NuGet包的相同示例,请参见https://github.com/webrtc-uwp/PeerCC。它基于https://webrtc.org的原始PeerConnection示例。

  1. ShareDrop是一个受苹果AirDrop服务启发的web应用程序。它允许你直接在设备之间传输文件,而不需要先将它们上传到任何服务器。它使用WebRTC进行安全点对点文件传输,使用Firebase进行存在管理和WebRTC信号发送。
  2. ShareDrop允许你在没有任何配置的情况下将文件发送到同一本地网络中的其他设备(即具有相同公共IP地址的设备)——只需在所有设备上打开https://www.sharedrop.io,它们就会互相看到。它还允许你在网络之间发送文件——只需点击页面右上角的+按钮,就可以创建一个拥有独特URL的房间,并与你想要发送文件的其他人分享这个URL。一旦他们在自己设备的浏览器中打开这个页面,你就会看到彼此的头像。
  3. ShareDrop和AirDrop的主要区别在于,ShareDrop需要互联网连接才能发现其他设备,而AirDrop则不需要——它在这些设备之间创建特别的无线网络。另一方面,ShareDrop允许你在移动设备(Android)和桌面设备之间以及网络之间共享文件。
  1. Agora Web TypeScript SDK
  2. Web 端 Agora 在线教育场景 Demo
  3. Web 端1对1视频通话 Demo
  4. Web端多人视频通话Demo
  5. Web端集成 Agora 视频 SDK,视频音频自采集
  6. Web端实现屏幕共享Demo
  7. Web端基于Agora实时消息SDK发消息Demo
  8. Web端快速集成 Agora 视频 SDK,实现17人视频直播
  9. Web端实现浏览器远程控制桌面的 Demo

参考:webrtc音视频开发总结——架构分析