本文由ELab技术团队分享,原题“浅谈WebRTC技术原理与利用”,有订正和改变。

1、根本介绍

WebRTC(全称 Web Real-Time Communication),即网页即时通信。 是一个反对网页浏览器进行实时语音对话或视频对话的技术计划。从前端技术开发的视角来看,是一组可调用的API规范。

在WebRTC公布之前,开发实时音视频交互利用的老本是十分低廉,须要思考的技术问题很多,如音视频的编解码问题,数据传输问题,延时、丢包、抖动、回音的解决和打消等,如果要兼容浏览器端的实时音视频通信,还须要额定装置插件。

2010年5月:Google以6820万美元收买VoIP软件开发商Global IP Solutions的GIPS引擎,并改为名为“WebRTC”(见《了不起的WebRTC:生态日趋完善,或将实时音视频技术白菜化》)。旨在建设一个互联网浏览器间的实时通信的平台,让 WebRTC技术成为 H5规范之一。

2012年1月:谷歌曾经把这款软件集成到Chrome浏览器中,Opera初步集成WebRTC。

2013年 6月:Mozilla Firefox[5]公布22.0版本正式集成及反对WebRTC。

2017年11月:W3C WebRTC 1.0 草案正式定稿。

2021年1月:WebRTC 被 W3C 和 IETF 公布为正式规范(见《WebRTC 1.0: Real-Time Communication Between Browsers》)。

(本文已同步公布于:http://www.52im.net/thread-38...)

2、重要意义

WebRTC的呈现、倒退和被业内规范组织(如W3C)等广泛认可,对于当下和将来大前端技术倒退具备重要的意义。

升高在web端的音视频交互开发门槛:

1)以往的音视频交互开发对于Web开发者而言具备肯定技术门槛;
2)当初借助于WebRTC,Web开发者通过调用JS接口,可疾速的实现音视频交互利用。

防止依赖、插件造成的次生问题:

1)以往的音视频交互利用构建依赖于各种插件、软件和服务器等;
2)当初借助于支流浏览器即可造成端到端的音视频交互。

统一化和标准化对传统音视频交互环境差异性的躲避:

1)以往音视频交互须要面对不同的 NAT 、防火墙对媒体 P2P 的建设带来了很大的挑战;
2)当初WebRTC 中有P2P 打洞的开源我的项目 libjingle ,反对 STUN,TURN 等协定。

更高效优化的算法、技术对于音视频交互性能的晋升:

1)WebRTC 通过NACK、FEC技术,防止了通过服务端路由直达,缩小了提早和带宽耗费;
2)还有 TCC + SVC + PACER + JitterBuffer 等技术对于音视频流畅性进行了优化。

3、技术特色

WebRTC内容丰盛,次要的技术特色蕴含以下几点。

1)实时通信:

WebRTC是一项实时通信技术,容许网络应用或者站点,在不借助两头媒介的状况下,建设浏览器之间点对点(Peer-to-Peer)的连贯,实现视频流和(或)音频流或者其余任意数据的传输。

2)无依赖/插件:

WebRTC蕴含的这些规范使用户在无需装置任何插件或者第三方的软件的状况下,创立点对点(Peer-to-Peer)的数据分享和电话会议成为可能。

3)协定栈 泛滥:

WebRTC并不是繁多的协定,蕴含了媒体、加密、传输层等在内的多个协定规范以及一套基于 JavaScript的 API,它包含了音视频的采集、编解码、网络传输、显示等性能。通过简略易用的 JavaScript API ,在不装置任何插件的状况下,让浏览器领有了 P2P音视频和数据分享的能力。

WebRTC依赖泛滥协定栈图:

同时WebRTC 并不是一个孤立的协定,它领有灵便的信令,能够便捷的对接现有的SIP 和电话网络的零碎。

4、兼容笼罩

目前大部分支流浏览器都失常兼容WebRTC:

▲ 上图援用自《WebRTC实时音视频技术的整体架构介绍》

更具体的浏览器及版本兼容状况,能够看看下图:

▲ 上图援用自《https://caniuse.com/rtcpeerco...》

支流浏览器都反对 WebRTC 规范 API ,因而也让浏览器之间无插件化的音视频互通成为可能, 大大降低了音视频开发的门槛,开发者只须要调用 WebRTC API 即可疾速构建出音视频利用。

5、技术框架

如下图所示:的技术框架形容了WebRTC的核心内容和面向不同开发者的API设计。

WebRTC技术框架图:

▲ 上图援用自《零根底入门:基于开源WebRTC,从0到1实现实时音视频聊天性能》

从图中可看到,WebRTC次要面向三类开发者的API设计:

1)对于Web开发者的API:框架蕴含了基于JavaScript 、 通过W3C认证了的一套API规范,使得web开发者能够基于这套API开发基于WebRTC的即时通讯利用;
2)对于浏览器厂商的API:框架同样蕴含了基于C++的底层WebRTC接口,对于浏览器厂商底层的接入非常敌对;
3)浏览器厂商可自定义的局部:框架中还蕴含浏览器厂商可自定义的音视频截取等扩大局部。

6、技术外围

从上节框架中能够看到,WebRTC次要有音频、视频引擎和传输三局部组成,其中又蕴含泛滥的协定和办法等。

1)Voice Engine(音频引擎):

a、Voice Engine蕴含iSAC/iLBC Codec(音频编解码器,前者是针对宽带和超宽带,后者是针对窄带);
b、NetEQ for voice(解决网络抖动和语音包失落);
c、Echo Canceler(回声消除器)/ Noise Reduction(噪声克制)。

2)Video Engine(视频引擎):

a、VP8 Codec(视频图像编解码器);
b、Video jitter buffer(视频抖动缓冲器,解决视频抖动和视频信息包失落);
c、Image enhancements(图像品质加强)。

3)Transport。

7、技术原理

7.1 根本状况
WebRTC次要的技术特色:

1)SRTP:平安的实时传输协定,用于音视频流传输;
2)Multiplexing:多路复用;
3)P2P:STUN+TURN+ICE,用于NAT网络和防火墙穿梭;
4)DTLS:平安传输可能还会用到DTLS(数据报平安传输),用于加密传输和密钥协商;
5)UDP:整个WebRTC通信是基于UDP的。

限于篇幅,本文以下章节将不粗疏介绍音视频采集、编码和解决等内容,仅介绍实时通信的建设过程原理的核心内容。

7.2 公网IP映射:明确网络定位信息
WebRTC是基于浏览器端到端的连贯(P2P)实现的.

因为不须要服务器直达,所以获取连贯对象的网络地址的形式,是借助于ICE、STUN、TURN等辅助内网穿透技术(NAT)失去对应主机的公网网络地址和端口等网络定位信息。

明确网络定位是建设端与端间接通信的根底。

NAT穿透原理图:

STUN服务器用于辅助内网穿透失去对应主机的公网网络地址和端口信息图:

▲ 上图援用自《WebRTC实时音视频技术的整体架构介绍》

7.3 信令服务器:网络协商与信息替换
信令服务器的作用是基于双工通信来直达信息。

直达信息包含公网IP映射后的网络定位信息,比方:公网IP、端口和媒体数据流等。

概念图:

信令服务器信息交互过程图:

7.4 会话形容协定SDP:对立的媒体协商形式
SDP的作用:

1)不同端/浏览器对于媒体流数据的编码格局各异,如VP8、VP9等,参加会话的各个成员的能力不对等、用户环境与配置不统一等;
2)WebRTC通信还须要确定和替换本地和近程音频和视频媒体信息,例如分辨率和编解码器性能。替换媒体配置信息的信令通过应用会话形容协定 (SDP) 替换Offer和Anwser来进行;
3)SDP的替换肯定是先于音视频流替换的。其内容包含会话根本信息、媒体信息形容等。
//SDP的构造体

Session description(会话级别形容)

     v=  (protocol version)     o=  (originator and session identifier)     s=  (session name)     c=* (connection information -- not required ifincluded inall media)     One or moreTime descriptions ("t="and "r="lines; see below)     a=* (zero or moresession attribute lines)     Zero or moreMedia descriptions

Time description

     t=  (timethe session is active)

Media description(媒体级别形容), ifpresent

     m=  (media name and transport address)     c=* (connection information -- optional ifincluded at session level)     a=* (zero or moremedia attribute lines)

一个SDP例子如下:

v=0 //代表版本,目前个别是v=0.

o=- 3883943731 1 IN IP4 127.0.0.1

s=

t=0 0 //会话处于活动状态的工夫

a=group:BUNDLE audio video //:形容服务质量,传输层复用相干信息

m=audio 1 RTP/SAVPF103 104 0 8 106 105 13 126 //...

a=ssrc:2223794119 label:H4fjnMzxy3dPIgQ7HxuCTLb4wLLLeRHnFxh81

7.5 一对一连贯建设过程
以建设一对一的Web RTC连贯过程为例来简要解说。

一对一过程图:

简要过程图:

如上图所示,解释一下:

1)替换SDP,获取各自媒体配置信息;
2)STUN服务器替换网络地址和端口等网络信息;
3)Turn直达音视频媒体流数据。

工作流程图:

如上图所示,解释一下:

1)A和B单方先调用 getUserMedia 关上本地摄像头,作为本地待输入媒体流;
2)向信令服务器发送退出房间申请;
3)Peer B 接管到 Peer A 发送的 offer SDP 对象,并通过PeerConnection的SetLocalDescription办法保留 Answer SDP 对象并将它通过信令服务器发送给 Peer A;
4)在 SDP 信息的 offer/answer 流程中,Peer A 和 Peer B 曾经依据 SDP 信息创立好相应的音频 Channel 和视频 Channel,并开启Candidate 数据的收集,Candidate数据(本地IP地址、公网IP地址、Relay服务端调配的地址);
5)当 Peer A 收集到 Candidate 信息后通过信令服务器发送给 Peer B。同样的过程 Peer B 对 Peer A 也会再发送一次。

7.6 多对多的建设
多对多建设点到点连贯概念图,以三个用户点对点的连贯为例:

7.7 WebRTC的次要JavaScrip接口
getUserMedia():拜访数据流,例如来自用户的相机和麦克风

//申请媒体类型

const constraints = {

video: true

audio:true

};

const video = document.querySelector('video');

//挂载流到相应dom展现本地媒体流

function handleSuccess(stream) {

video.srcObject = stream;

}

function handleError(error) {

console.error('getUserMedia error: ', error);

}

//利用摄像头捕捉多媒体流

navigator.mediaDevices.getUserMedia(constraints).

then(handleSuccess).catch(handleError);

RTCPeerConnection:通过加密和带宽管理工具启用音频或视频通话

// 容许 RTC 服务器配置。

const server = {

"iceServers":        [{ "urls": "stun:stun.stunprotocol.org"}]

};

// 创立本地连接

const localPeerConnection = newRTCPeerConnection(servers);

// 收集Candidate 数据

localPeerConnection.onicecandidate=function(event){

...

}

// 监听到媒体流接入时的操作

localPeerConnection.ontack=function(event){

...

}

RTCDataChannel:反对通用数据的点对点通信,罕用于数据点到点的传输

const pc = newRTCPeerConnection();

const dc = pc.createDataChannel("my channel");

//承受数据

dc.onmessage = function(event) {

console.log("received: "+ event.data);

};

//关上传输

dc.onopen = function() {

console.log("datachannel open");

};

//敞开传输

dc.onclose = function() {

console.log("datachannel close");

};

8、利用案例

这里以WebRTC的多人视频案例为实际来大抵演示一下。

8.1 设计框架
多人视频根本框架图:

8.2 要害代码
8.2.1)媒体捕捉:

获取浏览器视频权限,捕捉本地视频媒体流,在Video元素中附加媒体流,显示本地视频后果。代码如下。

//摄像头兼容性解决

navigator.getUserMedia = ( navigator.getUserMedia ||

           navigator.webkitGetUserMedia ||           navigator.mozGetUserMedia ||           navigator.msGetUserMedia);

// 获取本地音频和视频流

navigator.mediaDevices.getUserMedia({

            "audio": false,            "video": true

}).then( (stream)=> {

//显示本人的输入流,挂到页面Video元素上

document.getElementById("myVido").srcObject=stream

})

捕捉本地视频媒体流的显示后果截图:

为每个新的客户端连贯创立RTCPeerConnection对象:

// stun和turn服务器 const iceServer = {

"iceServers": [{    urls:"stun:stun.l.google.com:19302"}]

};

//为点到点的连贯创立RTCPeerConnection

const peerRTCConn=newRTCPeerConnection(iceServer);

8.2.2)网络协商:

次要工作就是:创立对等连贯,收集ICE候选,期待媒体流接入时挂载到dom。

交互式连通性建设(Interactive Connectivity Establishment — ICE)是一个容许实时对等端发现对方并且彼此连贯的框架。此技术容许对等方发现无关彼此拓扑的足够信息,从而有可能在彼此之间找到一条或多条通信门路。ICE 代理负责:收集本地IP,端口元组候选、在同级之间执行连贯检查和发送连贯放弃流动。(对于ICE的介绍,见《P2P技术之STUN、TURN、ICE详解》)

// 发送ICE候选到其余客户端 peerRTCConn.onicecandidate = function(event){

if(event.candidate) {    //向信令服务器转发收集到的ICE候选          socket.send(JSON.stringify({        "event": "relayICECandidate",        "data": {            'iceCandidate': {                'sdpMLineIndex': event.candidate.sdpMLineIndex,                'candidate': event.candidate.candidate            }        },        "fromID":signalMsg['data']['peerId']    }));}

}

//有媒体流染指就挂载dom peerRTCConn.ontrack=function(event){

let v=document.createElement("video")v.autoplay=truev.style="width:200px"document.getElementById("peer").appendChild(v)v.srcObject=event.streams[0]

}

8.1.3)媒体协商:

发动时创立Offer。peer利用setLocalDescription办法将会话信息加到RTCPeerConnection(),并由信令服务器直达。其余Peer会返回相应的Answer。SDP过程:

//新退出节点发动offer if(canOffer){

peerRTCConn.createOffer(    function(localDescription) {         peerRTCConn.setLocalDescription(localDescription,            function() {                //发送形容信息给信令服务器                         socket.send(JSON.stringify({                    "event":"relaySessionDescription",                    "data":localDescription,                    "fromID":peerId                }))             },            function() { alert("offer failed"); }        );    },    function(error) {        console.log("error sending offer: ", error);    })

}

响应时创立Answer。会话形容包含音视频信息等内容,当发起者向响应者收回offer类型的形容后,响应者会返回answer类型的形容:

//创立Answer会话

peer.createAnswer(

function(_remoteDescription) {

 peer.setLocalDescription(_remoteDescription,    function() {           //发送形容信息给信令服务器                  socket.send(JSON.stringify({                "event":"relaySessionDescription",                "data":_remoteDescription,                "callerID":signalMsg['fromId'],                "fromID":signalMsg['fromId']            }))        },    function() { alert("answer failed"); });

},

function(error) {

console.log("error creating answer: ", error);

});

当收到ICE候选共享后,会把ICE候选增加到近程对等点形容中:

//对应的RTCPeerConnection

const peer = peers[signalMsg["fromID"]];

//ICE候选增加到近程对等点形容

peer.addIceCandidate(newRTCIceCandidate(signalMsg["data"].iceCandidate));

多人视频后果截图<本地模仿成果>:

8.2.4)信令直达:

信令服务局部要害代码:

wss.on('connection', function(ws) {

ws.on('message', function(message) {    let meeageObj=JSON.parse(message)    //替换ICE候选         if (meeageObj['event'] =='relayICECandidate') {             wss.clients.forEach(function (client) {            console.log("send iceCandidate")                client.send(JSON.stringify({                    "event": "iceCandidate",                    "data": meeageObj['data'],                    "fromID": meeageObj['fromID']                }));                 });    }    //替换SDP     if (meeageObj['event'] =='relaySessionDescription') {        console.log(meeageObj["fromID"],meeageObj["data"].type)        wss.clients.forEach(function(client) {            if(client!=ws) {                client.send(JSON.stringify({                    "event": "sessionDescription",                    "fromId":meeageObj["fromID"],                    "data": meeageObj["data"],                }));            }        });    }})

})

9、小结一下

WebRTC的长处次要是:

1)不便:对于用户来说,在WebRTC呈现之前想要进行实时通信就须要装置插件和客户端,然而对于很多用户来说,插件的下载、软件的装置和更新这些操作是简单而且容易呈现问题的,当初WebRTC技术内置于浏览器中,用户不须要应用任何插件或者软件就能通过浏览器来实现实时通信。对于开发者来说,在Google将WebRTC开源之前,浏览器之间实现通信的技术是把握在大企业手中,这项技术的开发是一个很艰难的工作,当初开发者应用简略的HTML标签和JavaScript API就可能实现Web音/视频通信的性能。

2)收费:尽管WebRTC技术曾经较为成熟,其集成了最佳的音/视频引擎,非常先进的codec,然而Google对于这些技术不收取任何费用。

3)弱小的打洞能力:WebRTC技术蕴含了应用STUN、ICE、TURN、RTP-over-TCP的要害NAT和防火墙穿透技术,并反对代理。

WebRTC的毛病次要是:

1)不足服务器计划的设计和部署。

2)传输品质难以保障。WebRTC的传输设计基于P2P,难以保障传输品质,优化伎俩也无限,只能做一些端到端的优化,难以应答简单的互联网环境。比方对跨地区、跨运营商、低带宽、高丢包等场景下的传输品质根本是靠天吃饭,而这恰好是国内互联网利用的典型场景。

3)WebRTC比拟适宜一对一的单聊,尽管性能上能够扩大实现群聊,然而没有针对群聊,特地是超大群聊进行任何优化。

4)设施端适配,如回声、录音失败等问题层出不穷。这一点在安卓设施上尤为突出。因为安卓设施厂商泛滥,每个厂商都会在规范的安卓框架上进行定制化,导致很多可用性问题(拜访麦克风失败)和品质问题(如回声、啸叫)。

5)对Native开发反对不够。WebRTC顾名思义,次要面向Web利用,尽管也能够用于Native开发,然而因为波及到的畛域常识(音视频采集、解决、编解码、实时传输等)较多,整个框架设计比较复杂,API粒度也比拟细,导致连工程项目的编译都不是一件容易的事。

10、参考资料

[1] 开源实时音视频技术WebRTC的现状
[2] 简述开源实时音视频技术WebRTC的优缺点
[3] 访谈WebRTC规范之父:WebRTC的过来、当初和将来
[4] 良心分享:WebRTC 零根底开发者教程(中文)[附件下载]
[5] WebRTC实时音视频技术的整体架构介绍
[6] 新手入门:到底什么是WebRTC服务器,以及它是如何联接通话的?
[7] WebRTC实时音视频技术根底:根本架构和协定栈
[8] 浅谈开发实时视频直播平台的技术要点
[9] 基于开源WebRTC开发实时音视频靠谱吗?第3方SDK有哪些?
[10] 开源实时音视频技术WebRTC在Windows下的扼要编译教程
[11] 网页端实时音视频技术WebRTC:看起来很美,但离生产利用还有多少坑要填?
[12] 了不起的WebRTC:生态日趋完善,或将实时音视频技术白菜化
[13] 零根底入门:基于开源WebRTC,从0到1实现实时音视频聊天性能
[14] P2P技术详解(一):NAT详解——具体原理、P2P简介
[15] P2P技术详解(二):P2P中的NAT穿梭(打洞)计划详解(基本原理篇)

(本文已同步公布于:http://www.52im.net/thread-38...)