文章目录
计划做远程会见,主要功能是实现PC端、移动端音视频通信,监控以及录制。选择了两种方案,一种是集成声网的SDK,另一种是基于WebRTC。关于两种方案都写了一个Demo。第一次接触音视频通信,在这里整理下,希望帮助到更多人。
WebRTC是什么
WebRTC(Web Real-Time Communication)是什么?标准?API?还是一个项目?众说纷纭。那么WebRTC到底是什么呢?
从官网上的描述我们可以知道,WebRTC是一个免费的开放项目,它通过简单的API为浏览器和移动应用程序提供实时通信(RTC)功能。
这是官网给出的WebRTC架构图,其中
- 紫色部分是Web开发者API层;
- 蓝色实线部分是面向浏览器厂商的API层
- 蓝色虚线部分浏览器厂商可以自定义实现。
对于开发人员来说,WebRTC就是一组API。经常有人说WebRTC是JavaScript API的媒体引擎,准确说WebRTC是一个带有JavaScript API的媒体引擎。但这并不是全部。WebRTC并不止仅限于JavaScript。有很多系统是用C,Java,Python,C#,Erlang,Dart,甚至PHP所写。在移动端,原生软件在其客户端WebRTC SDK实现中使用的是Objective-C,Swift或者Java。但是最主要的是JavaScript。
------摘自WebRTC权威指南
W3C和IETF正在制定WebRTC标准,现在处于Draft状态。所以WebRTC是一组标准、协议也没错。只不过处于草案阶段。
如何使用WebRTC
了解了WebRTC的基本概念之后,我们接下来看下如何使用WebRTC。首先我们需要知道的是,使用WebRTC的目的是:建立对等连接,传输媒体捕获的数据从而实现音视频通信。
与传统的C/S或B/S架构不同,建立WebRTC会话的流程如下
WebRTC的通信过程可以看成如下三步:
1.浏览器获取媒体设备(摄像头和麦克风)。
2.通过信令过程,每一个peer和其它所有peer交换信息。
3.发信之后,peers可以直接连接,并开始通信交流。
为了实现这个过程,对于交换信息需要一个信令服务器。同样需要一对STUN/TURN服务器来实现NAT穿透。并且在不能直接通信的情况下传递媒体。
如果你正致力于寻找一个使用WebRTC的应用的实现方法,那么下面这些是你需要处理的:
客户端
WebRTC只适用于浏览器吗?
No, 图一可以看出Chrome、Firefox、Opera、Android、ios都支持WebRTC。事实上,WebRTC不仅可以用于浏览器、Android、ios,甚至可以和sip、Jingle、PSTN建立会话。
所以客户端可以是浏览器、移动应用、PC应用或者嵌入式设备。
如何在Android APP中使用WebRTC呢?
一种方式是引入官网提供的SDK,
https://webrtc.org/native-code/android/
另一种方式是 基于webview加载使用WebRTC的H5页面。
两种方式我都实践过了,都是可行的。
信令
信令的作用
在实时通信中,信令的主要作用体现在四个方面
- 协商媒体功能和设置。
- 标识和验证会话参与者的身份。
- 控制媒体会话、指示进度、更改会话和终止会话。
- 当会话双方同时尝试建立或更改会话时,实施双占用分解。
第1项是必备功能,第2、3、4项是可选功能或只是Web应用程序的一部分。
为了避免出现冗余,并最大限度地提高与已有技术的兼容性,WebRTC标准并没有规定信令方法和协议。JavaScript会话建立协议JSEP概述了这种方式:
WebRTC通话建立的思想是完全指定和控制媒体平面,但是尽可能将信令平面留给应用程序。其原理是,不同的应用程序可能更喜欢使用不同的协议,例如现有的SIP或Jingle呼叫信令协议,或者对于特定应用程序定制的东西,可能是针对新颖的用例。在这种方式中,需要交换的关键信息是多媒体会话描述,其指定了建立媒体平面所必需的传输和媒体配置信息。
信令传输
通常有三种方式用于传输WebRTC信令:HTTP、WebSocket和数据通道。
信令协议
WebRTC信令协议的选择不必局限于所选的信令传输方式。开发人员可选择创建自己的专有信令协议,采用SIP或Jingle等标准信令协议,或者使用通过抽象化处理剥离了信令协议细节的库。
简单来说,如果你只需进行浏览器间通信话,推荐使用node.js作为信令服务器,通过socket.io传输信令。
如果你需要与SIP或Jingle客户端进行互操作,你需要解决两个层面的问题:信令层、媒体层。
两个网络使用的信令机制不同,所以要进行信令的转换,才能完成媒体的协商,建立会话。媒体层要完成编码的转换,以及rtp/srtp转换等功能。这里主要说项信令层面的互通。
以SIP为例,目前sip和webrtc信令上互通有两种解决方案:
- 用JavaScript实现sip协议栈,webrtc应用程序基于这个协议栈开发。这样webrtc client发出的信令就是sip信令,但一般采用websocket为信令传输协议。这样的webrtc client就可以直接注册到支持ws的sip server上了。
jssip 、sipml5 都是这种解决方案。 - 通过转换网关实现协议的转换,从而互通。一个开源的网关项目就是 webrtc2sip。
webrtc2sip是一个功能很完善的网关,既实现了信令层,也实现了媒体层,编码转换功能很强大,也可以直接当做媒体网关,用于编解码,沟通两端的媒体。
NAT穿透
端到端通信的一个主要问题是,在许多情况下,这些端点并不在公共互联网中,而是位于网络(和端口)地址转换器(NAT)后面的专用地址空间中。随着互联网从DARPA项目发展成为全球范围的网络,很快就会明白IPv4的232地址空间早晚会用尽。
在20世纪90年代,开发了多种策略来延迟IPv4地址耗尽的时间,其中之一就是NAT的设计。NAT将端点的真实IP地址隐藏于世界其他地方,这使得端点之间建立端到端直接连接变得困难。这就是协助框架—包括STUN和TURN(或使用中继NAT穿越)—派上用场的地方。
我写Demo时使用的是公共的穿透服务器,但是建议自己搭建NAT穿透服务器。
下面是webRTC中文社区列出的一些第三方NAT穿透服务器。
媒体
媒体服务器不是必需的。那么媒体服务器到底有什么用处呢?
多人参与的视频通话
使用WebRTC我们可以建立对等通信,即P2P通信,那如果要实现多人通信,例如一个视频会议,该怎么做呢?
有三种方案供我们选择
- Mesh(P2P)
网状结构即peer间两两连接,但随着参与者数量的增加,客户端会消耗大量的CPU和带宽。显示情况中,即便是最优的网络环境,参与人数超过5人之后,网状结构的视频通话就很难良好的运行了。这种架构只适合人数比较少的情况。一般建议2-3人使用场景。 - MCU(Multi-point Control Unit)
MCU表示多点控制单元。由使用peer连接变为只需要连接到中心服务器,中心服务器反过来发送消息到其它peers,并且对其它peers也是这样。
通过使用MCU避免了Mesh中的问题。即使用户数量增加,也不会对用户处理能力和带宽产生影响,因为每个用户只需连接到媒体服务器。但是它却把压力从客户端转移到了媒体服务器上了。 - SFU(Selective Forwarding Unit)
SFU表示选择转发单元。SFU可以说是相对于Mesh和MCU的一种折中方案。在SFU结构中,每个peer向媒体服务器发送自己的流,媒体服务器反过来将流引到其它peers。当然,当用户数量增加时,下载带宽会增加。
视频录制
让所有视频流都通过一个媒体服务器的好处之一是我们可以录制媒体并且存储下来以备不时之需。
关于视频录制你可能会有以下几个问题
- 要实现视频录制必须使用媒体服务器吗?
- 不通过媒体服务器进行录制的话,那么录制应该在哪里进行呢?
- 怎么把本地视频流和远程视频流保存到一个文件?
- 录制的视频如何上传到服务器?
其实,实现视频录制有很多种方案,不一定通过媒体服务器实现。我实现的思路是:客户端利用requestAnimationFrame函数进行录制并推送到服务器上,从而减轻服务器的压力。如果录制时间比较长的话,可以设置定时录制并上传服务器,然后在服务器上通过Ffmpeg把这些文件合并为一个文件。
这个链接会对你有所启发:
https://stackoverflow.com/questions/18509385/html-5-video-recording-and-storing-a-stream
这里面提到了Media Recorder API、HTML Media Capture之类的东西。我使用的是RecordRTC,这是它的链接:https://github.com/muaz-khan/WebRTC-Experiment/tree/master/RecordRTC
与其他通信技术的整合
使用媒体服务器的另一个优势是可以与超出网页技术允许范围内的系统相通信,比如说通过SIP中继与PSTN进行通信,或者穿过RTMP流传输到支持它的服务中,比如Facebook Live和YouTube流直播。
媒体流的处理
一些媒体服务器允许以非常低的水平处理音视频流,比如能够在视频上运行机器视觉模型,或者将音频流发送给语音识别引擎,就像Google Speech一样。这些功能将WebRTC提升到了另一个层次;在我看来,它允许在一个普通的通信平台上添加更丰富和创新的互动,会大大提升它的价值。
第三方媒体服务器
------摘自WebRTC中文社区
WebRTC回声消除简介
在语音通话中所指的回声有两种,电路回声和声学回声,随着目前回声消除技术的发展,电路回声已经被很好的解决,所以现在回声消除的工作重心主要放在了解决声学回声消除的方法上。GIPS公司给WebRTC设计的回声消除算法是比较先进且效果较好的一种,我们所熟悉的腾讯QQ中就使用了这项技术,GIPS公司之前一直紧握着这项技术专利,直到Google将GIPS公司收购并且完全开源WebRTC,我们才有机会学习研究回声消除算法。WebRTC源代码中设计了两个回声消除模块,AEC(Acoustic Echo Canceller)和AECM(Acoustic Echo Canceller Mobile),AEC是在电脑端使用的回声消除器,而AECM是在移动端使用。由于电脑与移动设备的差别比较明显,在处理速度上,编解码器的性能上和内存方面都有着较大的差异。
WebRTC还提供了音视频的采集、编解码、网络传输、显示等功能
啸叫(或重音)
特别需要注意的是,对本地的video/audio,要设置一个 muted 属性,这里的意思是指将本地视频流播放时静音,否则,就会出现本地视频流的声音又一次作为音频输入源的循环中,造成我们常说的“啸叫”或者“重音”问题。