关于webrtc:一文详解-WebRTC-基础

48次阅读

共计 7229 个字符,预计需要花费 19 分钟才能阅读完成。

前言

刚开始接触 WebRTC 的时候,容易被一些生僻的概念绕得团团转,在经验一段时间的查阅文章和实际后,本文就具体梳理下无关 WebRTC 入门的基础知识。

本文同步发在我的 Github

RTC

RTC(Real-time Communications)实时通信,是实时音视频的一个简称。

WebRTC 是什么

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

WebRTC 的优缺点

长处

  • 跨平台(Web、Windows、MacOS、Linux、iOS、Android)
  • 收费、免插件、免装置,失去支流浏览器反对
  • 弱小的打洞能力,蕴含 STUN、ICE、TURN 的要害 NAT 和防火墙穿透技术

毛病

  • 不足服务器计划的设计和部署
  • 音频的设施适配问题

利用场景

  • 音视频通话
  • 视频 / 电话会议
  • 近程拜访主机
  • 在线教育(直播连麦,屏幕录制,共享远程桌面)

采集音视频数据

该办法会提醒用户给予应用媒体输出的许可,容许后会拜访到电脑摄像头和麦克风,并拿到一个 MediaStream 对象,把该媒体流赋值给页面的 video 标签,就能看到和听到本人的音视频了,由此也拿到音视频流。

async function createLocalMediaStream() {
  // (非 https/localhost)下 navigator.mediaDevices 会返回 undefined
  const localStream = await navigator.mediaDevices.getUserMedia({
    video: true,
    audio: true,
  })
  document.getElementById('local').srcObject = localStream
}

可查阅:MediaDevices.getUserMedia()

RTCPeerConnection

咱们把发动 WebRTC 通信的两端被称为对等端,即是 Peer。所谓点对点通信(peer-to-peer)则是说两个客户端直连,发送数据不须要两头服务器,建设胜利的连贯则称为PeerConnection,而一次 WebRTC 通信可蕴含多个 PeerConnection

RTCPeerConnection 则是创立点对点连贯的 API,代表一个由本地计算机到远端的 WebRTC 连贯。该接口提供了创立,放弃,监控,敞开连贯的办法的实现。

创立两个连贯实例

const peerA = new RTCPeerConnection()
const peerB = new RTCPeerConnection()

API

  • pc.createOffer:创立 offer 办法,办法会返回 SDP Offer 信息
  • pc.setLocalDescription 设置本地 SDP 形容信息
  • pc.setRemoteDescription:设置远端的 SDP 形容信息,即对方发过来的 SDP 信息
  • pc.createAnswer:远端创立应答 Answer 办法,办法会返回 SDP Offer 信息
  • pc.ontrack:设置完远端 SDP 形容信息后会触发该办法,接管对方的媒体流
  • pc.onicecandidate:设置完本地 SDP 形容信息后会触发该办法,关上一个连贯,开始运转媒体流
  • pc.addIceCandidate:连贯增加对方的网络信息
  • pc.setLocalDescription:将 localDescription 设置为 offer,localDescription 即为咱们须要发送给应答方的 sdp,此形容指定连贯本地端的属性,包含媒体格式
  • pc.setRemoteDescription:扭转与连贯相干的形容,该形容次要是形容有些对于连贯的属性,例如对端应用的解码器

WebRTC 音视频通信根本流程

  1. 一方发动调用 getUserMedia 关上本地摄像头
  2. 媒体协商(信令替换)
  3. 建设通信

媒体协商

媒体协商次要指 SDP 替换。

如上图,为媒体协商的大抵流程:

  1. 发动端 Amy 创立 Offer 并将 Offer 信息,并调用 setLocalDescription 将其保存起来,通过信令服务器传送给接收端 Bob
  2. 接收端 Bob 收到对等端 Amy 的 Offer 信息后调用 setRemoteDescription 办法将其保存起来,并创立 Answer 信息,同理也将 Answer 音讯通过 setLocalDescription 保留,并通过信令服务器传送给呼叫端 Amy
  3. 呼叫端 Amy 收到对等端 Blob 的 Answer 信息后调用 setRemoteDescription 办法将其 Answer 保存起来

首次接触的看到这个流程预计有点懵到底在干嘛,这里我列举一些可能的纳闷点来进行逐个解释:

1. 为什么须要媒体协商?

媒体协商的作用就是让单方找到独特反对的媒体能力,从而能实现彼此之间的音视频通信。比方两个人想聊天,一个人只会讲中文,喜爱探讨前端;一个人只会讲英文,不喜爱前端技术;通过调换材料,发现这没法聊天。但如果呈现另一个人会讲中文,喜爱钻研代码和前端技术,跟第一个人替换信息后,发现这能够聊天。所以发动端与接收端能不能进行通信,

2. 媒体协商是在做什么?

媒体协商就是在 替换 SDP的过程。会话发起者通过创立一个 offer,通过信令服务器发送到接管方,接管方创立answer 并返回给发送方,实现替换。

3. SDP 是什么?

SDP(Session Description Protocol)指 会话形容协定,是一种通用的协定,基于文本,其自身并不属于传输协定,须要依赖其它的传输协定(如 RTP 替换媒体信息。

SDP 次要用来形容多媒体会话,用处包含会话申明、会话邀请、会话初始化等。艰深来讲,它能够示意各端的能力,记录有对于你音频编解码类型、编解码器相干的参数、传输协定等信息。

替换 SDP 时,通信的单方会将承受到的 SDP 和本人的 SDP 进行比拟,取出他们之间的交加,这个交加就是协商的后果,也就是最终单方音视频通信时应用的音视频参数及传输协定。

4. offer 和 answer 是什么?

在单方要建设点对点通信时,发动端发送的 SDP 音讯称为 Offer,接收端发送的 SDP 音讯称为 Answer

所以,offer 和 answer 实质就是存有 SDP 信息的对象,所以也会叫做 SDP Offer 和 SDP Answer。

如下图,打印 offer 和 answer 信息

5. 信令与信令服务器

信令通常指的是为了网络中各种设施协调运作,在设施之间传递的管制信息。

对于 WebRTC 通信来说,发动端发送 Offer SDP 和接收端承受 Answer SDP,要怎么发给对方呢?这个过程还须要一种机制来协调通信并发送管制音讯,这个过程就称为信令。

而信令对应的服务器就叫信令服务器,作为中间人帮忙建设连贯,次要负责:

  • 信令的解决,如媒体协商音讯的传递
  • 治理房间信息。比方用户连贯时通知信令服务器本身的房间号,由信令服务器找到也在该房间号的对等端并开始尝试通信,也告诉用户谁退出了房间和来到了房间,告诉房间人数是否已满等等,所以也叫信令服务器也叫房间服务器。

WebRTC 并没有规定信令必须应用何种实现,目前业界应用较多的是 WebSocket + JSON/SDP 的计划。其中 WebSocket 用来提供信令传输通道,JSON/SDP 用来封装信令的具体内容。

ICE

当媒体协商实现后,WebRTC 就开始建设网络连接,其过程称为 ICE(Interactive Connectivity Establishment)交互式连贯建设。

ICE 不是一种协定,整合了 STUN 和 TURN 两种协定(用于 NAT 穿透)的框架。

ICE 是在各端调用 setLocalDescription() 后就开始了,其操作过程如下:

  1. 收集 Candidate
  2. 替换 Candidate
  3. 按优先级尝试连贯

在说完上述一些生僻的概念,我来逐个解释下波及到的货色

1. 什么是 Candidate?

比方想用 socket 连贯某台服务器,肯定要晓得这台服务器的一些根本信息,如服务器的 IP 地址、端口号以及应用的传输协定。只有晓得了这些信息,能力与这台服务器建设连贯。而 Candidate 正是 WebRTC 用来形容它能够连贯的远端的根本信息,因而 Candidate 是至多包含 IP 地址、端口号、协定的一个信息集。

2. 收集 Candidate

在 WebRTC 中有三种类型的 ICE 候选者(Candidate)

  1. 主机候选者:示意网卡本人的 IP 地址及端口。通过设施网卡获取,优先级最高。在 WebRTC 底层首先会尝试本地局域网内建设连贯。
  2. 反射候选者:示意通过 NAT 之后的外网 IP 地址和端口,由 ICE(STUN)服务器获取,依据服务器的返回状况,来综合判断并晓得本身在公网中的地址。其优先级低于主机候选者,当 WebRTC 尝试本地连接不通时,会尝试通过反射候选者取得的 IP 地址和端口进行连贯。
  3. 中继候选者 :示意的是中继(TURN) 服务器的转发 IP 地址与端口,由 ICE 中继服务器提供。优先级最低,前两个都不行则会按该种形式。

在新建 RTCPeerConnection 时可在构造函数指定 ICE 服务器地址,没有指定的话则意味着这个连贯只能在内网进行。

每次 WebRTC 找到 / 收集一个可用的 Candidate,都会触发一次 icecandidate 事件,为了将收集到的 Candidate 替换给对端,须要给 onicecandidate 办法设置一个回调函数,函数外面调用 addIceCandidate 办法来将候选者增加到通信中。

如下代码,通过该回调函数就能够取得 WebRTC 底层收集到的所有 Candidate 了。同时,还能够在该函数中将收集到的 Candidate 发送给对端。

peer.onicecandidate = (event) => {if (event.candidate) {// ...}
}

// 接管到信令服务器发送过去的候选信息后调用,为本机增加 ICE 代理
peer.addIceCandidate(candidate)

3. 替换 Candidate

WebRTC 收集好 Candidate 后,会通过信令零碎将它们发送给对端。对端接管到这些 Candidate 后,会与本地的 Candidate 造成 CandidatePair(即连贯候选者对)。有了 CandidatePair,WebRTC 就能够开始尝试建设连贯了。这里须要留神的是,Candidate 的替换不是等所有 Candidate 收集好后才进行的,而是边收集边替换。

CandidatePair,候选者对,即一个本地 Candidate,一个远端 Candidate

当 WebRTC 造成 CandidatePair 后,便开始尝试进行连贯。一旦 WebRTC 发现其中有一个能够连通的 CandidatePair 时,它就不再进行前面的连贯尝试了,但发现新的 Candidate 时依然能够持续进行替换。

4. NAT 是什么?

NAT:网络地址转换,它是一种解决专用网络内设施连贯公网的技术。

这里我就不写了,社区已有通俗易懂的文章解释 NAT,举荐大家看完再持续往下看:

  • 家庭网络中的「NAT」到底是什么?

4. STUN 是什么?

STUN(Session Traversal Utilities for NAT, NAT 会话穿梭应用程序)。它容许位于 NAT(或多重 NAT)后的客户端找出本人对应的公网 IP 地址和端口,也就是俗称的 ” 打洞 ”/”NAT 打洞 ”/”NAT 穿梭 ”。

再直白点,STUN 服务器用于 获取计算机的公网 IP 地址

Google 提供了一个测试 STUN/TURN 服务的网址,能够测试对应的 STUN 服务。

打洞怎么了解呢?如果要翻越一座山,就要沿着山路从一遍的山脚到另一边的山脚。但如果山里有条间接能够通过的隧道,就相当于两个点(山脚)间接的进行连贯,这就是 ” 打洞 ”,实现点对点。

从这一点了解,打洞的机制叫 ICE,而帮忙打洞的服务器叫 STUN 服务。

在两个用户通信前,首先会向公网的 STUN 服务发送申请获取本人的公网地址,而后通过服务器将各自的公网地址转发给对等端,这样单方就晓得了对方的公网地址,依据这个公网地址就能够间接点对点通信了。

能够应用谷歌提供的 SUTN 服务器进行配置

const config = {
  iceServers: [
    {urls: 'stun:stun.l.google.com:19302',},
  ],
}

const peer = new RTCPeerConnection(config)

当 STUN 服务遇到对称型 NAT 时(这里如果不懂先去理解上方 NAT 相干的基础知识),就打洞失败了,这时就须要 TURN 服务。

5. TURN 是什么?

TURN(Traversal USing Replays around NAT),即应用中继穿透 NAT,是 STUN 的扩大。

如果 STUN 调配公网 IP 的形式失败,则能够通过 TURN 服务器申请公网 IP 地址作为中继地址,将媒体数据通过 TURN 服务器进行直达,用作 对等连贯失败的中继,属于最终的备选形式。

目标就是 解决对称 NAT 无奈穿梭的问题,不同于其它中继协定在于它容许客户机应用一个中继地址与多个对端同时进行通信。完满补救了 STUN 无奈穿梭对称型 NAT 的问题。

STUN 服务器不同的是,TURN 服务器会作为直达,转发多媒体数据会耗费大量的带宽。

ICE 打洞相干的过程,开发者只需配置好 STUN/TURN 对应的地址,在对应的函数调用就能够了,WebRTC 在底层帮咱们去实现了。

最简易版的点对点通信实际

而如果是局域网本机来实现通信,都无需配置 STUN/TURN 服务。

在浏览器本地模仿最简略的点对点通信,咱们间接本地代码同时新建两个对等端 Peer,这样无需信令服务传递 SDP 信息,不到 50 行 JS 代码就能够实现下图的成果:

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title> 浏览器本地同页面模仿点对点连贯(无信令服务版)</title>
    <style>
      video {
        width: 300px;
        height: 250px;
      }
    </style>
  </head>
  <body>
    我的本地视频:<video id="local" autoplay></video> 近程连贯拿到我的本地视频 <video
      id="local-from-remote"
      autoplay
    ></video>

    <script src="./index.js"></script>
  </body>
</html>
let localStream

const createLocalMediaStream = async () => {
  localStream = await navigator.mediaDevices.getUserMedia({
    video: true,
    audio: false,
  })
  document.getElementById('local').srcObject = localStream
}

const createPeerConnection = async () => {const peerA = new RTCPeerConnection()
  const peerB = new RTCPeerConnection()

  // 增加本地媒体流
  localStream.getTracks().forEach((track) => {peerA.addTrack(track, localStream)
  })

  // 监听 ice 候选项事件
  peerA.onicecandidate = (event) => {if (event.candidate) {peerB.addIceCandidate(event.candidate) // 设置 ice 候选项
    }
  }

  // 监听获取媒体数据(前提是 peerA 已增加了媒体流数据)peerB.ontrack = (event) => {document.getElementById('local-from-remote').srcObject = event.streams[0]
  }
  /**
   * 媒体协商(替换 SDP)*/
  const offer = await peerA.createOffer()
  await peerA.setLocalDescription(offer)

  await peerB.setRemoteDescription(offer)
  const answer = await peerB.createAnswer()
  await peerB.setLocalDescription(answer)

  await peerA.setRemoteDescription(answer)
}

const main = async () => {await createLocalMediaStream()
  await createPeerConnection()}
main()

代码残缺地址

如果看完感觉 OK,能够去试下信令版(socket + 房间治理)的实现,

  • 客户端:webrtc-client
  • 信令服务端:webrtc-server

结语

本文对 WebRTC 流程做了大抵解说,但对相干概念进行具体解释阐明,倡议在学习的过程能够再多看一遍文章会更清晰。

参考资料

  • WenRTC 官网
  • 《WebRTC 音视频实时互动技术》
  • 从 0 到 1 打造一个 WebRTC 利用
  • Why WebRTC |“浅入深出”的工作原理详解
  • WebRTC:一个视频聊天的简略例子
  • 有了 WebRTC,直播能够这样玩!
  • 前端音视频 WebRTC 实时通信的外围
  • # WebRTC: how two browsers agree on voice and video calls

正文完
 0