WebRTC 使用入门

WebRTC 是打造开放、顺畅的网络环境的新阵线。

Brendan Eich,JavaScript 发明者

无需插件即可实现实时通信

想象一下,如果您的手机、电视和计算机可以通过一个通用平台进行通信,想象一下,向您的 Web 应用添加视频聊天和点对点数据分享功能非常简单。这就是 WebRTC 的愿景。

想试试吗?WebRTC 适用于桌面设备和移动设备的 Google Chrome、Safari、Firefox 和 Opera。不妨从 appr.tc 这个简单的视频聊天应用入手:

  1. 在浏览器中打开 appr.tc
  2. 点击加入即可加入聊天室,并让应用使用您的摄像头。
  3. 在新标签页中打开网页末尾显示的网址,最好在其他计算机上打开。

快速入门

没时间阅读本文或只想查看代码?

或者,您也可以直接学习 WebRTC Codelab,该 Codelab 是一个分步指南,其中说明了如何构建完整的视频聊天应用,包括简单的信号服务器。

WebRTC 的非常短的历史

网络的最后一个主要挑战之一是通过语音和视频实现人类通信:实时通信,简称 RTC。在 Web 应用中,RTC 应该像在文本输入中输入文本一样自然。如果没有它,您创新和开发新的互动方式的能力就会受到限制。

过去,RTC 一直是企业且十分复杂,需要昂贵的音频和视频技术在内部获得许可或开发。将 RTC 技术与现有的内容、数据和服务集成是一项困难且耗时的工作,尤其是在网页上。

Gmail 视频聊天于 2008 年流行起来,Google 在 2011 年推出了使用 Talk 的环聊(和 Gmail 一样)。Google 收购了 GIPS,这家公司开发了 RTC 所需的许多组件,例如编解码器和回声消除技术。Google 对 GIPS 开发的技术进行了开源,并与互联网工程任务组 (IETF) 和万维网联盟 (W3C) 的相关标准机构进行了合作,以确保行业达成共识。2011 年 5 月,爱立信构建了 WebRTC 的首个实现

WebRTC 针对实时、无插件的视频、音频和数据通信实施了开放标准。需求真的存在:

  • 许多网络服务都使用了 RTC,但需要下载内容、原生应用或插件。这些服务包括 Skype、Facebook 和 Hangouts。
  • 插件的下载、安装和更新过程既复杂又容易出错,也令人厌烦。
  • 插件难以部署、调试、问题排查、测试和维护,可能需要获得许可,并与昂贵的复杂技术集成。通常很难说服用户从一开始就安装插件!

WebRTC 项目的指导原则是,其 API 应是开源、免费、标准化的,内置于网络浏览器中,并且比现有技术更高效。

我们现在位于哪个位置?

WebRTC 用于各种应用,例如 Google Meet。WebRTC 还已与 WebKitGTK+ 和 Qt 原生应用集成。

WebRTC 会实现以下三个 API: - MediaStream(也称为 getUserMedia) - RTCPeerConnection - RTCDataChannel

这两个规范中定义了 API:

Chrome、Safari、Firefox、Edge 和 Opera 在移动设备和桌面设备上均支持这三种 API。

getUserMedia:如需查看演示和代码,请参阅 WebRTC 示例或试用 Chris Wilson 提供的使用 getUserMedia 作为网络音频输入的精彩示例

RTCPeerConnection:如需简单演示和功能齐全的视频聊天应用,请参阅 WebRTC 对等连接示例appr.tc。该应用使用 adapter.js(一个由 Google 在 WebRTC 社区的帮助下维护的 JavaScript shim)来抽象化浏览器差异和规范更改。

RTCDataChannel:如需查看其实际效果,请参阅 WebRTC 示例,查看其中一个数据通道演示。

WebRTC Codelab 介绍了如何使用全部三个 API 构建一款用于视频聊天和文件共享的简单应用。

您的第一个 WebRTC

WebRTC 应用需要执行以下几项操作:

  • 获取流式音频、视频或其他数据。
  • 获取 IP 地址和端口等网络信息,并与其他 WebRTC 客户端(称为对等客户端)交换这些信息,以启用连接,即使通过 NAT 和防火墙也可建立连接。
  • 协调信号通信,以报告错误并发起或关闭会话。
  • 交换有关媒体和客户端功能(例如分辨率和编解码器)的信息。
  • 传输流式传输的音频、视频或数据。

为了获取和通信流式数据,WebRTC 实现了以下 API:

  • MediaStream 可以访问数据流,例如来自用户的摄像头和麦克风的数据流。
  • RTCPeerConnection 支持使用加密和带宽管理功能进行音频或视频通话。
  • RTCDataChannel 支持通用数据的点对点通信。

(稍后会详细介绍 WebRTC 的网络和信号方面。)

MediaStream API(也称为 getUserMedia API)

MediaStream API 表示同步的媒体流。例如,从摄像头和麦克风输入获取的视频流会同步的视频和音轨。(请不要将 MediaStreamTrack<track> 元素混淆,后者在元素上完全不同。)

要了解 MediaStream API,最简单的方式可能是实际查看一下:

  1. 在浏览器中,前往 WebRTC 示例 getUserMedia
  2. 打开控制台。
  3. 检查全局范围内的 stream 变量。

每个 MediaStream 都有一个输入(可能是由 getUserMedia() 生成的 MediaStream)以及一个输出(可以传递给视频元素或 RTCPeerConnection)。

getUserMedia() 方法接受 MediaStreamConstraints 对象参数,并返回解析为 MediaStream 对象的 Promise

每个 MediaStream 都有一个 label,例如 'Xk7EuLhsuHKbnjLWkW4yYGNJJ8ONsgwHBvLQ'getAudioTracks()getVideoTracks() 方法会返回一个 MediaStreamTrack 数组。

对于 getUserMedia 示例,stream.getAudioTracks() 会返回一个空数组(因为没有音频),并且假设连接了有效的摄像头,stream.getVideoTracks() 会返回一个包含 MediaStreamTrack 的数组(代表来自摄像头的信息流)。每个 MediaStreamTrack 都有一个种类('video''audio')、label(类似于 'FaceTime HD Camera (Built-in)'),表示一个或多个音频通道或视频通道。在本例中,只有一个视频轨道且没有音频,但易于想象的用例中有更多音频轨道,例如聊天应用从前置摄像头、后置摄像头和麦克风获取信息流,以及应用共享其屏幕。

通过设置 srcObject 属性,可将 MediaStream 附加到视频元素。以前,这是通过将 src 属性设置为使用 URL.createObjectURL() 创建的对象网址来实现的,但这种方法已废弃

getUserMedia 也可用作 Web Audio API 的输入节点

// Cope with browser differences.
let audioContext;
if (typeof AudioContext === 'function') {
  audioContext = new AudioContext();
} else if (typeof webkitAudioContext === 'function') {
  audioContext = new webkitAudioContext(); // eslint-disable-line new-cap
} else {
  console.log('Sorry! Web Audio not supported.');
}

// Create a filter node.
var filterNode = audioContext.createBiquadFilter();
// See https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#BiquadFilterNode-section
filterNode.type = 'highpass';
// Cutoff frequency. For highpass, audio is attenuated below this frequency.
filterNode.frequency.value = 10000;

// Create a gain node to change audio volume.
var gainNode = audioContext.createGain();
// Default is 1 (no change). Less than 1 means audio is attenuated
// and vice versa.
gainNode.gain.value = 0.5;

navigator.mediaDevices.getUserMedia({audio: true}, (stream) => {
  // Create an AudioNode from the stream.
  const mediaStreamSource =
    audioContext.createMediaStreamSource(stream);
  mediaStreamSource.connect(filterNode);
  filterNode.connect(gainNode);
  // Connect the gain node to the destination. For example, play the sound.
  gainNode.connect(audioContext.destination);
});

基于 Chromium 的应用和扩展程序也可以整合 getUserMedia。向清单添加 audioCapture 和/或 videoCapture 权限后,用户只需在安装时请求和授予一次权限。此后,系统不会要求用户授予摄像头或麦克风使用权限。

对于 getUserMedia(),只需授予一次权限。第一次在浏览器的信息栏中显示“允许”按钮。由于 getUserMedia() 被归类为强大功能,因此 Chrome 已于 2015 年底弃用 HTTP 访问权限。

这样做可能是为任何流式数据源(而不仅仅是摄像头或麦克风)启用 MediaStream。这将实现来自存储的数据或任意数据源(例如传感器或其他输入)的流式传输。

getUserMedia() 可以与其他 JavaScript API 和库一起实际发挥作用:

  • Webcam Toy 是一款 Photobooth 应用,它使用 WebGL 为可分享或保存到本地的照片添加怪异而奇妙的效果。
  • FaceKat 是一款使用 headtrackr.js 构建的面部跟踪游戏。
  • ASCII 相机使用 Canvas API 生成 ASCII 图片。
由 idevelop.ro/ascii-camera 生成的 ASCII 图片
gUM ASCII 图形!

限制条件

约束条件可用于为 getUserMedia() 设置视频分辨率的值。这还有助于支持其他约束条件,例如宽高比;前置或后置摄像头;帧速率、高度和宽度;以及 applyConstraints() 方法。

如需查看示例,请参阅 WebRTC 示例 getUserMedia:选择分辨率

例如,如果未设置所请求的分辨率,设置不允许的约束值时,系统会提供 DOMExceptionOverconstrainedError。如需查看实际操作,请参阅 WebRTC 示例 getUserMedia:选择分辨率演示。

屏幕和标签页截取

借助 Chrome 应用,您还可以通过 chrome.tabCapturechrome.desktopCapture API 分享单个浏览器标签页或整个桌面的实时视频。(如需查看演示和详细信息,请参阅使用 WebRTC 共享屏幕)。这篇文章已经发布好几年了,但仍然很有趣。)

您还可以使用实验性 chromeMediaSource 约束条件在 Chrome 中将屏幕截图用作 MediaStream 源代码。请注意,屏幕截图需要使用 HTTPS,只能用于开发,因为该功能是通过命令行标志启用的,如本博文中所述。

信号:会话控制、网络和媒体信息

WebRTC 使用 RTCPeerConnection 在浏览器(也称为“对等方”)之间传输流式数据,但还需要一种机制来协调通信并发送控制消息,此过程称为“信号”。WebRTC 指定信令方法和协议。信号不是 RTCPeerConnection API 的一部分。

相反,WebRTC 应用开发者可以选择他们喜欢的任何消息传递协议,例如 SIP 或 XMPP 以及任何合适的双工(双向)通信通道。appr.tc 示例使用 XHR 和 Channel API 作为信号机制。Codelab 使用在节点服务器上运行的 Socket.io

信号用于交换三种类型的信息:

  • 会话控制消息:用于初始化或关闭通信并报告错误。
  • 网络配置:对于外界,您计算机的 IP 地址和端口是什么?
  • 媒体功能:您的浏览器和要与之通信的浏览器可以处理哪些编解码器和分辨率?

必须先成功完成通过信号交换的信息,然后才能开始点对点流式传输。

例如,假设小红想要与小鲍沟通。以下是 W3C WebRTC 规范中的代码示例,显示了实际的信令流程。该代码假定存在在 createSignalingChannel() 方法中创建的某种信号机制。另请注意,在 Chrome 和 Opera 上,RTCPeerConnection 目前带有前缀。

// handles JSON.stringify/parse
const signaling = new SignalingChannel();
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
const pc = new RTCPeerConnection(configuration);

// Send any ice candidates to the other peer.
pc.onicecandidate = ({candidate}) => signaling.send({candidate});

// Let the "negotiationneeded" event trigger offer generation.
pc.onnegotiationneeded = async () => {
  try {
    await pc.setLocalDescription(await pc.createOffer());
    // Send the offer to the other peer.
    signaling.send({desc: pc.localDescription});
  } catch (err) {
    console.error(err);
  }
};

// Once remote track media arrives, show it in remote video element.
pc.ontrack = (event) => {
  // Don't set srcObject again if it is already set.
  if (remoteView.srcObject) return;
  remoteView.srcObject = event.streams[0];
};

// Call start() to initiate.
async function start() {
  try {
    // Get local stream, show it in self-view, and add it to be sent.
    const stream =
      await navigator.mediaDevices.getUserMedia(constraints);
    stream.getTracks().forEach((track) =>
      pc.addTrack(track, stream));
    selfView.srcObject = stream;
  } catch (err) {
    console.error(err);
  }
}

signaling.onmessage = async ({desc, candidate}) => {
  try {
    if (desc) {
      // If you get an offer, you need to reply with an answer.
      if (desc.type === 'offer') {
        await pc.setRemoteDescription(desc);
        const stream =
          await navigator.mediaDevices.getUserMedia(constraints);
        stream.getTracks().forEach((track) =>
          pc.addTrack(track, stream));
        await pc.setLocalDescription(await pc.createAnswer());
        signaling.send({desc: pc.localDescription});
      } else if (desc.type === 'answer') {
        await pc.setRemoteDescription(desc);
      } else {
        console.log('Unsupported SDP type.');
      }
    } else if (candidate) {
      await pc.addIceCandidate(candidate);
    }
  } catch (err) {
    console.error(err);
  }
};

首先,Alice 和 Bob 交换网络信息。(表达式“查找候选对象”是指使用 ICE 框架查找网络接口和端口的过程。)

  1. Alice 使用 onicecandidate 处理程序创建了一个 RTCPeerConnection 对象,它会在候选网络可用时运行。
  2. Alice 通过任何信令通道(例如 WebSocket 或某种其他机制)向 Bob 发送序列化的候选数据。
  3. 当 Bob 收到来自 Alice 的候选消息时,他调用 addIceCandidate 以将候选字词添加到远程对等方说明中。

WebRTC 客户端(在本例中也称为“对等设备”或“Alice 和 Bob”)也需要确定并交换本地和远程音频和视频媒体信息,例如分辨率和编解码器功能。系统会使用会话描述协议 (SDP) 交换邀约应答,从而继续发出交换媒体配置信息的信号:

  1. Alice 运行了 RTCPeerConnection createOffer() 方法。返回后,系统会传递一个 RTCSessionDescription,即 Alice 的本地会话描述。
  2. 在该回调中,Alice 使用 setLocalDescription() 设置本地说明,然后通过其信道信道将此会话说明发送给 Bob。请注意,在调用 setLocalDescription() 之前,RTCPeerConnection 不会开始收集候选对象。这一点已编入 JSEP IETF 草案
  3. Bob 使用 setRemoteDescription() 将 Alice 发送给他的说明设置为远程说明。
  4. Bob 运行 RTCPeerConnection createAnswer() 方法,并向其传递他从 Alice 获得的远程描述,以便生成与她的远程描述兼容的本地会话。系统会向 createAnswer() 回调传递一个 RTCSessionDescription。Bob 将该说明设置为本地说明,并将其发送给 Alice。
  5. Alice 收到 Bob 的会话说明后,她使用 setRemoteDescription 将该说明设置为远程说明。
  6. 叮!

RTCSessionDescription 对象是符合会话描述协议 (SDP) 的 blob。在序列化后,SDP 对象将如下所示:

v=0
o=- 3883943731 1 IN IP4 127.0.0.1
s=
t=0 0
a=group:BUNDLE audio video
m=audio 1 RTP/SAVPF 103 104 0 8 106 105 13 126

// ...

a=ssrc:2223794119 label:H4fjnMzxy3dPIgQ7HxuCTLb4wLLLeRHnFxh810

网络和媒体信息的获取和交换可同时完成,但只有在两个过程均完成后,对等设备之间才能开始进行音频和视频流式传输。

之前介绍的邀约/应答架构称为 JavaScript 会话建立协议 (JSEP)。(爱立信演示视频中有一个优秀的动画解释了信令和流式传输的过程,该动画首次实现 WebRTC。)

JSEP 架构图
JSEP 架构

信令过程成功完成后,数据可以在调用方和被调用方之间直接点对点流式传输,或者,如果失败,通过中间中继服务器进行流式传输(稍后会详细介绍)。流式传输是 RTCPeerConnection 的工作。

RTCPeerConnection

RTCPeerConnection 是一个 WebRTC 组件,负责处理对等方之间流式数据的稳定、高效通信。

下图展示了 RTCPeerConnection 的作用。您会发现,绿色部分很复杂!

WebRTC 架构图
WebRTC 架构(来自 webrtc.org

从 JavaScript 的角度来看,从此图中要理解的主要内容是,RTCPeerConnection 保护 Web 开发者免受潜藏的无数复杂性的影响。为了支持实时通信,WebRTC 使用的编解码器和协议做了大量工作,即使通过不可靠的网络也能实现:

  • 丢包隐藏
  • 回声消除
  • 带宽自适应
  • 动态抖动缓冲
  • 自动增益控制
  • 降噪和抑制
  • 图片清理

之前的 W3C 代码从信号的角度展示了 WebRTC 的简化示例。以下是两个正常运行的 WebRTC 应用的演示。第一个是演示 RTCPeerConnection 的简单示例,第二个是功能完备的视频聊天客户端。

没有服务器的 RTCPeerConnection

以下代码取自 WebRTC 对等连接示例,该示例在一个网页上有本地和远程 RTCPeerConnection(以及本地和远程视频)。这对您来说并不实用(调用方和被调用方位于同一页面上),但这确实使 RTCPeerConnection API 的工作原理更加清晰,因为该页面上的 RTCPeerConnection 对象可以直接交换数据和消息,而无需使用中间信号机制。

在此示例中,pc1 表示本地对等方(调用方),pc2 表示远程对等方(被调用方)。

来电者

  1. 创建一个新的 RTCPeerConnection,并添加来自 getUserMedia() 的数据流: ```js // 服务器是一个可选的配置文件。(请参阅稍后关于 TURN 和 STUN 的讨论。) pc1 = new RTCPeerConnection(servers); // ... localStream.getTracks().forEach((track) => { pc1.addTrack(track, localStream); });
  1. 创建优惠,并将其设置为 pc1 的本地说明和 pc2 的远程说明。这可以直接在代码中完成,而无需使用信号,因为调用方和被调用方位于同一页面上: js pc1.setLocalDescription(desc).then(() => { onSetLocalSuccess(pc1); }, onSetSessionDescriptionError ); trace('pc2 setRemoteDescription start'); pc2.setRemoteDescription(desc).then(() => { onSetRemoteSuccess(pc2); }, onSetSessionDescriptionError );

被调用方

  1. 创建 pc2,并在添加来自 pc1 的流后,将其显示在视频元素中:js pc2 = new RTCPeerConnection(servers); pc2.ontrack = gotRemoteStream; //... function gotRemoteStream(e){ vid2.srcObject = e.stream; }

RTCPeerConnection 个 API Plus 版服务器

在现实世界中,WebRTC 需要服务器,尽管如此简单,因此可能会发生以下情况:

  • 用户会相互发现并交换真实生活的详细信息,例如姓名。
  • WebRTC 客户端应用(对等)会交换网络信息。
  • 对等设备会交换有关媒体的数据,例如视频格式和分辨率。
  • WebRTC 客户端应用会遍历 NAT 网关和防火墙。

也就是说,WebRTC 需要四种类型的服务器端功能:

  • 用户发现和沟通
  • 信令
  • NAT/防火墙穿越
  • 点对点通信失败时的中继服务器

NAT 穿越、点对点网络以及构建服务器应用以发现用户和接收信号的要求不在本文讨论范围之内。ICE 框架使用 STUN 协议及其扩展 TURN 来让 RTCPeerConnection 能够应对 NAT 遍历和其他不稳定的网络。

ICE 是一种用于连接对等设备(例如两个视频聊天客户端)的框架。最初,ICE 会尝试通过 UDP 以尽可能最短的延迟时间直接连接对等方。在此过程中,STUN 服务器只有一个任务:让 NAT 后面的对等方能够查找其公共地址和端口。(如需详细了解 STUN 和 TURN,请参阅构建 WebRTC 应用所需的后端服务。)

查找连接候选项
查找候选连接

如果 UDP 失败,ICE 会尝试使用 TCP。如果直接连接失败(特别是由于企业 NAT 穿越和防火墙导致),ICE 会使用中间(中继)TURN 服务器。换言之,ICE 首先将 STUN 与 UDP 结合使用来直接连接对等网络,如果失败,则回退到 TURN 中继服务器。表达式“查找候选对象”是指查找网络接口和端口的过程。

WebRTC 数据路径
WebRTC 数据路径

WebRTC 工程师 Justin Uberti 在 2013 年 Google I/O 大会 WebRTC 演示文稿中提供了有关 ICE、STUN 和 TURN 的更多信息。(演示幻灯片提供了 TURN 和 STUN 服务器实现的示例。)

简单的视频聊天客户端

appr.tc 的视频聊天演示是一个很好的试用平台,WebRTC 还具备使用 STUN 服务器实现信令和 NAT/防火墙穿越功能。此应用使用 adapter.js,这是一个 shim,可保护应用免受规范更改和前缀差异的影响。

代码在日志记录中故意详尽。请查看控制台,了解事件的顺序。以下是对代码的详细演示。

网络拓扑

目前实现的 WebRTC 仅支持一对一通信,但可用于更复杂的网络场景,例如多个对等设备相互直接通信,或通过多点控制单元 (MCU)(可处理大量参与者并选择性地转发音频以及混音或录制音频和视频的服务器)。

多点控制单元拓扑图
多点控制单元拓扑示例

许多现有的 WebRTC 应用仅演示网络浏览器之间的通信,但是网关服务器可以让在浏览器中运行的 WebRTC 应用与设备交互,如电话(也称为 PSTN)和 VOIP 系统。2012 年 5 月,Doubango Telecom 开放了使用 WebRTC 和 WebSocket 构建的 sipml5 SIP 客户端,此客户端(以及其他潜在用途)支持在 iOS 和 Android 上运行的浏览器与应用之间进行视频通话。在 Google I/O 大会上,Tetr 和 Tropo 在公文包中演示了灾难通信框架,该框架使用 OpenBTS 手机来实现功能手机和计算机之间的通过 WebRTC 通信。无运营商支持电话通信!

2012 年 Google I/O 大会上的 Tethr/Tropo 演示
Tethr/Tropo:用公文包形式告知灾难情况

RTCDataChannel API<

除了音频和视频之外,WebRTC 还支持其他类型的数据的实时通信。

RTCDataChannel API 支持点对点交换任意数据,延迟时间短,吞吐量高。如需查看单页演示并了解如何构建简单的文件传输应用,请分别参阅 WebRTC 示例WebRTC Codelab

API 有许多潜在用例,包括:

  • 游戏
  • 远程桌面应用
  • 实时文字聊天
  • 文件传输
  • 分散式网络

此 API 具备几项功能,可充分利用 RTCPeerConnection 并实现强大且灵活的点对点通信:

  • 利用了 RTCPeerConnection 会话设置
  • 多个同时频道具有优先级
  • 可靠和不可靠的交付语义
  • 内置安全 (DTLS) 和拥塞控制
  • 能够使用(无论是否包含音频或视频)

我们特意使用类似于 WebSocket 的语法,该语法具有 send() 方法和 message 事件:

const localConnection = new RTCPeerConnection(servers);
const remoteConnection = new RTCPeerConnection(servers);
const sendChannel =
  localConnection.createDataChannel('sendDataChannel');

// ...

remoteConnection.ondatachannel = (event) => {
  receiveChannel = event.channel;
  receiveChannel.onmessage = onReceiveMessage;
  receiveChannel.onopen = onReceiveChannelStateChange;
  receiveChannel.onclose = onReceiveChannelStateChange;
};

function onReceiveMessage(event) {
  document.querySelector("textarea#send").value = event.data;
}

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

由于是直接在浏览器之间进行通信的,因此 RTCDataChannel 在处理防火墙和 NAT 失败时即使需要使用中继 (TURN) 服务器,速度也会比 WebSocket 快得多。

RTCDataChannel 可在 Chrome、Safari、Firefox、Opera 和 Samsung Internet 上使用。Cube Slam 游戏使用 API 来传达游戏状态。您可以和朋友玩,也可以玩熊!创新的平台 Sharefest 通过 RTCDataChannelpeerCDN 实现了文件共享,展示了 WebRTC 如何实现点对点内容分发。

如需详细了解 RTCDataChannel,请参阅 IETF 的协议规范草稿

安全性

实时通信应用或插件可能会通过多种方式损害安全性。例如:

  • 未加密的媒体或数据可能会在浏览器之间或浏览器与服务器之间拦截。
  • 应用可能会在用户不知情的情况下录制和分发视频或音频。
  • 恶意软件或病毒可能会随明显无害的插件或应用一起安装。

WebRTC 提供了几项功能来避免这些问题:

  • WebRTC 实现使用安全协议,例如 DTLSSRTP
  • 所有 WebRTC 组件(包括信号机制)都必须加密。
  • WebRTC 不是插件。其组件在浏览器沙盒中运行,而不是在单独的进程中运行。组件不需要单独安装,并且会在浏览器更新时更新。
  • 必须明确授予摄像头和麦克风访问权限,并且当摄像头或麦克风运行时,界面会清楚显示这一点。

对流媒体安全性的全面讨论不在本文讨论范围之内。有关详情,请参阅 IETF 建议的 WebRTC 安全架构提案

总结

WebRTC 的 API 和标准可以普及并分散化用于内容创作和通信(包括电话、游戏、视频制作、音乐制作和新闻收集)的工具。

技术的破坏力不会比这更多。

正如博主 Phil Edholm 所说,“或许 WebRTC 和 HTML5 可以像原始浏览器一样实现信息传输的实时通信。”

开发者工具

了解详情

标准和协议

WebRTC 支持摘要

MediaStreamgetUserMedia API

  • Chrome 桌面版 18.0.1008 及更高版本;Chrome(Android 29 及更高版本)
  • Opera 18 及更高版本;适用于 Android 20 及更高版本的 Opera
  • Opera 12、Opera Mobile 12(基于 Presto 引擎)
  • Firefox 17 及更高版本
  • Microsoft Edge 16 及更高版本
  • iOS 上的 Safari 11.2 及更高版本,以及 MacOS 上的 11.1 及更高版本
  • UC 11.8 及更高版本(Android)
  • 三星互联网 4 及更高版本

RTCPeerConnection API

  • Chrome 桌面设备 20 及更高版本;Android 29 及更高版本(无标记)
  • Opera 18 及更高版本(默认启用);适用于 Android 20 及更高版本的 Opera(默认处于启用状态)
  • Firefox 22 及更高版本(默认开启)
  • Microsoft Edge 16 及更高版本
  • iOS 上的 Safari 11.2 及更高版本,以及 MacOS 上的 11.1 及更高版本
  • 三星互联网 4 及更高版本

RTCDataChannel API

  • Chrome 25 中的实验性版本,但在 Chrome 26 及更高版本中更稳定(并与 Firefox 互操作);Chrome(Android 版)29 及更高版本
  • 在 Opera 18 及更高版本中是稳定版(以及与 Firefox 互操作性功能);适用于 Android 20 及更高版本的 Opera
  • Firefox 22 及更高版本(默认开启)

如需详细了解对 API 的跨平台支持(例如 getUserMediaRTCPeerConnection),请访问 caniuse.comChrome 平台状态

如需了解 RTCPeerConnection 的原生 API,请参阅 webrtc.org 上的文档