写点什么

🏆大势所趋,迈向认识 WebRTC 的第一步,加油!

发布于: 2021 年 06 月 02 日
🏆大势所趋,迈向认识WebRTC的第一步,加油!

每日一句


人生的挑战,无处不在,满怀信心,轻装上路,明天永远是充满希望的战场。

承接上文

承接上文的内容介绍完相关 WebRTC 技术的概念和发展历程后,开始初步摸索一下相关 WebRTC 技术的功能和原理🌺【WebRTC原理探索】未来可期,WebRTC的诞生发展

技术回顾

WebRTC 概念定义

WebRTC 名称源自网页实时通信(Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的技术,是谷歌 2010 年以 6820 万美元收购 Global IP Solutions 公司而获得的一项技术。

WebRTC 功能范畴

  • WebRTC 是一个开源项目,旨在使得浏览器能为实时通信(RTC)提供简单的 JavaScript 接口。

  • WebRTC 不仅可传输视频,也可以传输其他数据例如文本、图片等。需要注意的是,WebRTC 并不是浏览器的一个子集,浏览器只是根据 WebRTC 的标准协议实现了 WebRTC 的原生接口。Android 和 IOS 系统也支持 WebRTC 。

WebRTC 应用包括下面四个主要的概念

  • 信令服务器(Signalling servers)

  • ICE 服务器(ICE servers)

  • 媒体服务器(Media servers)

  • JavaScript 接口 (JavaScript API)

WebRTC 已经纳入 HTML5 标准

目前支持 WebRTC 协议的浏览器有:Chrome、Firefox Opera,IE 不支持~


  • WebRTC 没有指定具体的信令协议,具体的信令协议留给应用程序实现。

  • WebRTC 使用 JSEP 协议建立会话,什么是 JSEP 后面说

  • WebRTC 采用 ICE 实现 NAT 穿越。

  • WebRTC 客户端之间可以进行点对点的媒体传输。

WebRTC 的核心组件

  • 音视频引擎:OPUS、VP8/VP9、H264

  • 传输层协议:底层传输协议为 UDP

  • 媒体协议:SRTP/SRTCP

  • 数据协议:DTLS/SCTP

  • P2P 内网穿透:STUN / TURN / ICE / Trickle ICE

  • 信令与 SDP 协商:HTTP / WebSocket / SIP、 Offer Answer 模型


下图为 WebRTC 内部结构简化图:


  • 最底层是硬件设备

  • 上面是音频捕获模块和视频捕获模块



  • 中间部分为音视频引擎

  • 音频引擎负责音频采集和传输,具有降噪、回声消除等功能。

  • 视频引擎负责网络抖动优化,互联网传输编解码优化。


在音视频引擎之上是一套 C++ API,在 C++ 的 API 之上是提供给浏览器的 Javascript API。

JSEP

  • JSEP(JavaScript Session Establishment Protocol,JavaScript 会话建立协议)是一个信令 API,允许开发者构建更强大的应用程序以及增加在信令协议选择上的灵活性。

  • JSEP 是干什么的呢,一方面提供接口如 createOffer()供 web 应用程序调用生成 SDP,另一方面提供 ICE 功能接口。这些功能都由浏览器实现,浏览器 WebRTC 传输信令(offer/answer)采用 Websocket

  • 建立会话最关键的就是媒体的协商,WebRTC 虽然没有指定具体的信令协议,但是媒体协商采用了 SDP 协议。

  • 如果 web 应用程序不使用额外的信令协议,仅使用 JSEP,两个 WebRTC client(同一个 WebRTC client 程序,两处登陆)之间也是可以建立链接的,即只要应用程序能解析用 WS 传递过来的 Offer/Answer 消息,提取出其中的 SDP 和 ICE 信息就可以了。

  • github 上 codelabdemo 就是不用其他信令协议,直接使用 JSEP 生成 offer/answer 信令,然后采用 ws 协议传输实现的

  • JSEP 并不是信令协议,可以在 JSEP 的基础上引入 SIP 等信令协议,使 WebRTC 应用功能更加完备。

信令服务器

  • 信令服务器主要用于在两个用户之间交换信息。虽然 WebRTC 是点对点通信,但还是需要服务器来初始化连接,并传递一些信息


WebRTC 没有定义用于建立信道的信令的协议,因此可以使用任意的传输方式,例如 WebSocket, XMPP, SIP, AJAX


  • 可以使用实时的传输协议比如 WebSocket 来交换数据,也可以使用简单的 GET/POST 方式轮询服务器来获取数据。

信令服务器传送的数据有
  1. 协商媒体功能和设置

  2. 标识和验证会话参与者的身份

  3. 控制媒体会话指示进度更改会话和终止会话


其中只有第一项的必备功能。其他都可以根据业务需求自由调整。

SDP 协议
  • 媒体协商最重要的功能在于,为参与点对点通信的两个浏览器之间交换会话描述协议「SDP」。

  • 「SDP」包含浏览器的 RTP 媒体栈配置所需的全部信息,包括媒体类型(音频、视频、数据)、所需的编解码器,用于编解码器参数或设置,以及有关带宽的信息。


此外,信令通道还用于交换候选地址,以便进行 ICE 打洞。

信令互通方案

WebRTC 与 SIP 互通

要想让 WebRTC 与 SIP 互通,要解决两个层面的问题:信令层和媒体层。


两个网络使用的信令机制不同,所以要进行信令的转换,才能完成媒体的协商,建立会话。媒体层要完成编码的转换,以及 RTP/SRTP 转换等功能。


这里主要说项信令层面的互通。


目前 SIP 和 WebRTC 信令上互通有两种解决方案:


  • JavaScript 实现 SIP 协议栈,WebRTC 应用程序基于这个协议栈开发。WebRTC Client 发出的信令就是 SIP 信令,但一般采用 websocket 为信令传输协议。

  • 这样 WebRTC client 就可以直接注册到支持 WS 的 SIP Server 上了。jssip 、sipml5 都是这种解决方案。

  • 通过转换网关实现协议的转换,从而互通。一个开源的网关项目就是 WebRTC2SIP。

  • WebRTC2SIP 是一个功能很完善的网关,既实现了信令层,也实现了媒体层,编码转换功能很强大,也可以直接当做媒体网关,用于编解码,沟通两端的媒体

ICE 服务器

  • 实现点对点通信的关键在于两个浏览器之间能直接发送和接收数据包,但一般情况下,浏览器或手机都是通过路由器访问 Internet,所以存在网络地址转换(NAT)。

  • NAT 之内的 IP 地址是私有地址,外部无法访问。分配给 NAT 的 IP 地址才是公共地址。NAT 每次从内部到外部转发数据包时都使用公共地址。

  • 交互式建立连接(ICE)是一种标准穿透协议,它利用 STUN 和 TURN 服务器来建立连接。

  • STUN 服务器可以遍历 NAT,获取浏览器的候选地址,包括私有地址、外层 NAT 的公共 IP 地址等。

  • 通信信令通道可以交换候选地址,浏览器一旦发送并收到了候选地址,就会开始进行连接检查,若检查成功,便使用该候选项发送媒体。

  • 在大多情况下,通过穿透可以建立直接对等连接。但是,若 NAT 或防火墙限制非常严格,无法建立连接,就只能通过 TURN 服务器中继媒体。

媒体服务器

媒体服务器不是必须的,但在多方会话或需要对媒体做额外处理的情况下可以考虑加入。对于有多个浏览器参与的会议,可以采用一个集中式媒体服务器。在这种情况下,美国浏览器都只需与媒体服务器建立单个连接即可,这种结构的优势是额能够扩展非常大的会话,同时可以在最大限度上减少当有新加入者加入会话事美国浏览器所需的处理工作量。同时,媒体服务器也可对媒体进行分析、处理、保存等工作。

JavaScript 接口

getUserMedia

通过调用 navigator.getUserMedia()可以获取视频或音频的数据,constraints 参数可以选择是否获取视频音频。下面是一个简单的示例


var constraints = {  audio: false,  video: true};var video = document.querySelector('video');
function successCallback(stream) {
if (window.URL) { video.src = window.URL.createObjectURL(stream); } else { video.src = stream; }}
function errorCallback(error) { console.log('navigator.getUserMedia error: ', error);}

navigator.getUserMedia(constraints, successCallback, errorCallback);
复制代码

RTCPeerConnection

RTCPeerConnection 是 WebRTC 中最重要的一个接口,用于确定 ICE 服务器、交换 SDP。连接过程如下:

创建 RTCPeerConnection 对象
  1. RTCPeerConnection 的参数用于确定 ICE 服务器,下面是使用了 google 开放的 STUN 服务器


let iceServer = {    "iceServers": [{        "url": "stun:stun.l.google.com:19302"    }]};let pc = new RTCPeerConnection(servers);
复制代码


  1. 将媒体流放入 RTCPeerConnection 对象中


pc.addStream(localStream);
复制代码


通过 offer 和 answer 交换 SDP 描述符


  1. 甲和乙各自建立一个 PC 实例

  2. 甲通过 PC 所提供的 createOffer()方法建立一个包含甲的 SDP 描述符的 offer 信令

  3. 甲通过 PC 所提供的 setLocalDescription()方法,将甲的 SDP 描述符交给甲的 PC 实例

  4. 甲将 offer 信令通过服务器发送给乙

  5. 乙将甲的 offer 信令中所包含的的 SDP 描述符提取出来,通过 PC 所提供的 setRemoteDescription()方法交给乙的 PC 实例

  6. 乙通过 PC 所提供的 createAnswer()方法建立一个包含乙的 SDP 描述符 answer 信令

  7. 乙通过 PC 所提供的 setLocalDescription()方法,将乙的 SDP 描述符交给乙的 PC 实例

  8. 乙将 answer 信令通过服务器发送给甲


甲接收到乙的 answer 信令后,将其中乙的 SDP 描述符提取出来,调用 setRemoteDescripttion()方法交给甲自己的 PC 实例。

ICE 打洞

  1. 当网络候选可用时,通过信令服务器将其发送到对方浏览器


pc.onicecandidate = function(event) {  if (event.candidate) {    sendToServer(event.candidate)  }};
复制代码


  1. 当接受到对方网络候选时,将其加入


let candidate = new RTCIceCandidate(candidate);pc.addIceCandidate(candidate);
复制代码


  1. 监听对方发送的媒体是否可用,并播放媒体


pc.onaddstream = event => {  remoteVideo.src = window.URL.createObjectURL(event.stream);}
复制代码

RTCDataChannel

RTCDataChannel 是 RTCPeerConnectionAPI 的一部分,只有在创建了 RTCPeerConnection 实例后才能创建数据通道。


数据通道可以用于发送文本或是文件。


pc = new RTCPeerConnection();dc =  pc.createDataChannel('dc');dc.onmessage = event => console.log(event.data);dc.send('text');dc.sed(new arraybuffer(32))
复制代码


在另一端可以使用 ondatachannel 获得 RTCDataChannel 对象


pc.ondatachannel = event => dc = event.channel;
复制代码


发布于: 2021 年 06 月 02 日阅读数: 47
用户头像

我们始于迷惘,终于更高水平的迷惘。 2020.03.25 加入

🏆 【酷爱计算机技术、醉心开发编程、喜爱健身运动、热衷悬疑推理的”极客狂人“】 🏅 【Java技术领域,MySQL技术领域,APM全链路追踪技术及微服务、分布式方向的技术体系等】 🤝未来我们希望可以共同进步🤝

评论

发布
暂无评论
🏆大势所趋,迈向认识WebRTC的第一步,加油!