关注微信公众号(瓠悠笑软件部落),一起学习,一起摸鱼
huyouxiao.com
本文是Google开源大会对WebRTC的讲解。自己看视频做的笔记。英文好的同学,建议直接看视频。原视频地址
如果访问不了,可以访问我的公众号。里面有视频:视频带文字版
喜欢的话,别忘了点击好看。谢谢你的支持。

WebRTC 的三种任务

  • 获取音频和视频
  • 传达音频和视频
  • 传达任意数据

三种主要的JavaScript APIs

  • MediaStream(aka getUserMedia)
  • RTCPeerConnection
  • RTCDataChannel

MediaStream

  • 代表一种 音频 或者/和 语音流.
  • 可以包含多个 “tracks”
  • 通过 navigator.getUserMedia() 获取一个 MediaStream
    MediaStream

MediaStream

aka getUserMedia

var constraints = {video: true};

function successCallback(stream) {
var video = document.querySelector("video");
video.src = window.URL.createObjectURL(stream);
}

function errorCallback(error) {
  console.log("navigator.getUserMedia error:", error);
}

navigator.getUserMedia(constraints, successCallback, errorCallback);

在线二进制摄像头

在线摄像头

Constraints

  • Controls the contents of the MediaStream
  • Media type, resolution, frame rate
video: {
  mandatory: {
    minWidth: 640,
    minHeigh: 360
  },
  optional [{
    minWidth: 1280,
    minHeigth: 720
  }]
}

getUserMedia + Web Audio

// success callback when requesting audio input stream
function gotStream(stream) {
   var audioContext = new webkitAudioContext();
   // create an AudioNode from the stream
   var mediaStreamSource = audioContext.createMediaStreamSource(stream);

 // connect it to the destination or any other node for processing!
 mediaStreamSource.connect(audioContext.destination);
}

确保打开了Chrome 浏览器里面 about:flags 里面的 Web Audio Input

获取用户切图 gUM screencapture

var constraints = {
  video: {
    mandatory: {
       chromeMediaSource: 'screen'
    }
  }
}
navigator.webkitGetUserMedia(constraints, gotStream);

RTCPeerConnection

audio 和 video 点到点之间的链接通信

Communicate Media Streams

Communicate Media Streams

RTCPeerConnection 做了很多

  • 信令处理
  • 解码操作
  • 端到端的通信
  • 安全
  • 带宽控制

WebRTC 架构

WebRTC architecture

RTCPeerConnection 样例

pc = new RTCPeerConnection(null);
pc.onaddstream = gotRemoteStream;
pc.addStream(localStream);
pc.createOffer(gotOffer);

function gotOffer(desc) {
  pc.setLocalDescription(desc);
  sendOffer(desc);
}

function getAnswer(desc) {
  pc.setRemoteDescription(desc);
}

function getRemoteStream(e) {
  attachMediaStream(remoteVideo, e.stream);
}

RTCDataChannel

端到端之间的任意数据的双向通信
Communicate arbitrary data

RTCDataChannel

  • Same API as WebSocket
  • Ultra-low lantency 超低延迟
  • Unreliable or reliable 根据应用场景选择是速度重要,还是可靠性重要。比如传文件,需要搞可靠性。而传游戏数据,数度更重要。
  • Secure 保证传输的数据在接收后能够以正确的方式解码。

RTCDataChannel API

var pc = new webkitRTCPeerConnection(servers, {optional: [{RtpDataChannels: true}]};

pc.ondatachannel = function(event) {
   receiveChannel = event.channel;
   receiveChannel.onmessage = function(event) {
      document.querySelector("div#receive").innerHTML = event.data;
   };
};

sendChannel = pc.createDataChannel("sendDataChannel", {reliable: false});

document.querySelector("button#send").onclick = function() {
  var data = document.querySelector("textarea#send").value;
  sendChannel.send(data);
  };

github ShareFest

Servers and Protocols

Peer to Peer - 但是我们需要服务器.

Abstract Signaling

  • 需要交换 ‘session description’ objects.
    • 我支持什么样的格式,我想要发送什么
    • 端到端之间建立链接时,需要的网络信息
  • 可以使用任意 messaging mechanism,比如: web sockets, Google Cloud Messaging, XHR
  • 可以使用任意 messaging protocol . 比如:JSON,或者标准的协议: SPI XMPP。

Signaling Diagram

Signaling Diagram

An RTCSessionDescription

An RTCSessionDescription

STUN and TURN

P2P in the age of firewalls and NATs
端到端之间 session 完整的路径。

在很早以前,这不是问题。人们知道对方的公网IP地址就可以直接连接进行通信
An idea world

但后来有了NAT, NAT分发所谓的私有IP地址.而私有IP地址不能用于建立链接通信。我们就无法建立真正的端到端通信。除非我们有公共地址。所以引入了STUN技术。
The real world

STUN

  • 告诉我我的公网IP地址是多少. 当一个request 发送到STUN Server的时候,STUN Server查看这个请求的来源地址,并把地址放到 packet里面,然后发回去。所以现在WebRTC 知道 Peer 的公网IP地址了,之后STUN server 就不会参与到 Peer 与 Peer 之间的通信链路中去了。也就不需要转发 media。
  • 一个简单的 Server,运行成本低
  • Data flows peer-to-peer
    STUN
    通常情况下,是可以建立通信的,但不是在所有的情况下都能正常工作。所以引入了TURN 技术。

TURN

  • 如果 peer-to-peer 通信失败的话,提供一个 cloud fallback.
    当无法建立端到端的链接时,转而调用云服务中的 relay。请求:给我一个公共的IP地址。由于这个公共地址是在云服务上。任何人都可以和他建立链接。也就以为着这个call可以建立起来。即使你在一个受限制的网络环境中,甚至在一个网络代理后面。
  • 数据是通过 server 发送的,使用 server 的带宽
    缺点是,由于数据实际上是通过服务器中继的,因此会产生运营成本。但这意味着这个通话可以在几乎所有的网络环境下正常的工作。
  • 确保 call 可以在绝大数网络环境下正常工作。
    TURN

现在,一方面,我们有STUN,它超级便宜,但面对复杂的网络环境,会不可用。我们有TURN。他通常都可用。但会占用服务器的带宽。这两种方案,如何选择最好的方案呢?

先尝试使用STUN Server 建立链接,如果不行,我们无法穿透NATs. s所以,我们回过头来,接着我们唯一能用的是TURN,把 media 数据从我们的发起 peer, 经过NAT, 再经过 TURN server 发送给另一端的 peer. 这些都是通过 ICE 技术实现的。

ICE

  • ICE: 一个用于链接 Peers 的框架。
  • 尝试为每一个 call 找到最佳的通信路径。
  • 绝大多数 calls 都可以使用 STUN(webrtcstats.com);
    Video Calls

部署 STUN/TURN

  • stun.l.google.com:19302
  • WebRTC stunserver, turnserer 建议取名的时候,取一个长长的名字以确保唯一性。
  • rfc5766-turn-server 他有 Amazon VM 镜像。你可以下载下来,部署到云服务器上去,你就可以给你的用户提供 TURN server 了。
  • restund 另外一个 TURN server,我们使用过,效果很好。
    WebRTC code package 里面有 STUN 和 TURN 的源代码。

安全 Security

在WebRTC开始的时候,就考虑了安全问题

  • 强制加密 media 和 data . 所有传输的数据都使用标准的 AES 加密。
  • Secure UI, explicit opt-in . 只有用户明确地选择了使用麦克风和摄像头,WebRTC才可以用这些功能。
  • Sanboxed, no plugins. WebRTC 运行在Chrome 浏览器的 沙盒 里面。
    所以即使有人试图攻击chrome里面的webRTC. 浏览器和用户都会得到完整的保护。
  • WebRTC Security Architecture WebRTC 安全架构

Secure pathways 安全的传输方式

  • Signaling 用HTTPS加密
  • Audio/Video 使用SRTP加密
  • Data 使用DTLS(Datagram TLS) 加密

Secure pathways

Architecutres

如果有多个call,比如一个多方会议,我应该如何构建我的应用程序?

Peer to Peer: 1 对 1 的 call

one-to-one-call

Mesh(网孔):小型的多方会议.

Mesh 表示每一个peer 都会连接到另外所有的其他peer。

small-n-way-call
这样也很简单,因为他们之间的链接不涉及服务器服务器和其他东东,比如信令。但有缺点: 假设有N个Peer参与通信,每一个Peer要发送的数据,必须将数据复制N-1分,分别发送给其他N-1个Peer. 这将有对应的CPU和带宽消耗。所以这取决于你要发送的media类型。对于Audio,开销要大一些。对应Video,开销要小一些。拓扑图中参与通话的Peers数量因此会收到限制. 如果某一个Peer是手机设备。CPU和带宽吃紧。限制更明显。
为了解决这个问题,引入另外一种架构。

Star: medium N-way call 星形架构

star artitecture
从所有peer里面找到一个性能最强的。由它从当会话的中心角色。我们称之为 the focus for the call. foucs 实际负责接收数据,复制并转发给所有其他Peers 或者 endpoints. 但是我们要处理多方的高清视频流(HD video streams). focus 的任务就有点吃不消了。所以对于大型的多方会话,需要使用MCU。

MCU multipoint control unit. 多点控制单元

large N-way call
MCU 是一个为传递大量音频和视频而定制的服务器。它可以做各种事情. 它可以选择 stream 并转发. 它实际上可以混合音频或视频数据。它还能录制。如果一个Peer 掉线了,MCU不会中断整个会议,因为MCU要负责所有的Peer的会话,而不单单是某一个Peer。

Beyong browers 不仅仅限制于在浏览器中使用。

Phones and more

  • 容易和非浏览器设备集成
  • sipML5 开源的 JavaScript SPI client. 可以用于标准的SIP设备。
  • Phono 开源的 JavaScript phone API
  • Zingaya embeddable phone widget
    Zingaya PSTN

创建一个 WebRTC app

chrome://webrtc-internals
在这里可以看到webRTC API 调用的日志,你可以debug.
webrtc-internals

adapter.js

让你在所有版本的浏览器里面使用同样的代码

  • 移除了厂商前缀(vendor prefixes)
  • 将 Chrome/Firefox 的差异做了抽象处理。
  • 最大限度地减少规范流失的影响(minimizes effects of spec chrun)
    实际上 webRTC 规范的更新频率非常快,对于一个特定的浏览器,这些API 不能一直匹配最新版本的规范。adapter.js可以帮助Web开发人员隔离浏览器之间的差异和版本之间的差异。因此我们确保adapter.js始终实现最新的规范,然后向下发送到版本支持的任何内容。所以新的API发布的时候,不需要更改开发人员的代码,只需要更新一下adapter.js 文件就可以了。

JavaScript frameworks

  • Video chat:
  • Peer-to-peer data:
    • PeerJS
    • Sharefest
SimpleWebRTC

很方便的 peer-to-peer 视频和语音

var webrtc = new WebRTC ({
  localVideoEl:  'localVideo',
  remoteVideosEl: 'remoteVideos',
  autoRequestMedia: true 
});

webrtc.on('readyToCall', function (){
  webrtc.joinRoom('My room name');
});
PeerJS

方便的 peer-to-peer data

var peer = new Peer('someid', {key: 'apikey'});
peer.on('connection', function(conn) {
   conn.on('data', function(data) {
   // will print 'hi!'
   console.log(data);
   });
});


// connecting peer
var peer = new Peer('anotherid', {key: 'apikey'});
var conn = peer.connect('someid');
conn.on('open', function() {
   conn.send('hi!');
});   

javascript 并不用关心产品方面的服务特性,比如 信令,STUN 和 TURN 服务。幸运的是,OpenTok 和 vLine 为我们提供了这些服务。你只需要注册这些服务,获取API key, 就可以使用他们的产品功能发起 call. 触达世界的每个角落。他们还制作了可以轻松放入WebRTC应用程序的UI小部件.所以你能快速的开发和运行 WebRTC app.

Services

  • 完成 video services:
    • OpenTok (acuqired by Telefonica Digital)
    • vLine

最新版chrome 已经支持 HD video quality 和 full-band audio quality.

更多信息:
webrtcbook.com
io13webrtc.appspot.com

原视频地址

webRTC

Logo

致力于链接即构和开发者,提供实时互动和元宇宙领域的前沿洞察、技术分享和丰富的开发者活动,共建实时互动世界。

更多推荐