在维护开放、不受阻碍的网络环境的长期战争中,WebRTC 可成为新的战线。
JavaScript 发明者 Brendan Eich
无需插件即可实时通信
想象一下,您的手机、电视和计算机可以在一个通用平台上通信。想象一下,在您的 Web 应用中添加视频聊天和点对点数据共享非常简单。这就是 WebRTC 的愿景。
想试试吗?WebRTC 在桌面设备和移动设备上均可使用,可通过 Google Chrome、Safari、Firefox 和 Opera 使用。建议您从 appr.tc 中的一款简单视频聊天应用着手:
- 在浏览器中打开 appr.tc。
- 点击加入即可加入聊天室,并让应用使用您的摄像头。
- 在新标签页中打开网页末尾显示的网址,最好在其他计算机上打开网址。
快速入门
没时间阅读本文或只想获取代码?
- 如需简要了解 WebRTC,请观看以下 Google I/O 视频或观看这些幻灯片:
- 如果您未使用过
getUserMedia
API,请参阅以 HTML5 格式录制音频和视频和 simpl.info getUserMedia。 - 如需了解
RTCPeerConnection
API,请参阅以下示例和 'simpl.info RTCPeerConnection'。 - 如需了解 WebRTC 如何使用服务器进行信号发送以及防火墙和 NAT 穿越,请参阅 appr.tc 中的代码和控制台日志。
- 迫不及待想立即试用 WebRTC?试用 WebRTC JavaScript API 的 20 多个演示。
- 使用您的计算机和 WebRTC 时遇到了问题?访问 WebRTC 问题排查工具。
或者,您也可以直接跳转到 WebRTC Codelab,这是一份分步指南,介绍了如何构建完整的视频聊天应用,包括一个简单的信令服务器。
WebRTC 简史
网络面临的最后一大挑战之一就是要通过语音和视频实现人类通信,即实时通信(简称 RTC)。在 Web 应用中,RTC 应该和在文本输入中输入文本一样自然。没有它,您在创新和开发新的互动方式方面的能力会受到限制。
长期以来,RTC 一直是企业和复杂的行业,需要内部许可或开发昂贵的音频和视频技术。将 RTC 技术与现有内容、数据和服务集成在一起一直困难且耗时,尤其是在 Web 上。
Gmail 视频聊天从 2008 年开始流行,并于 2011 年推出了环聊,它采用了 Google 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 可能最简单的方法就是大体观察它:
- 在浏览器中,转到 WebRTC 示例
getUserMedia
。 - 打开控制台。
- 检查全局范围内的
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()
的 HTTP 访问权限属于强大的功能,因此 Chrome 已于 2015 年底弃用了该功能。
其意图可能是为任何流式数据源(而不仅仅是摄像头或麦克风)启用 MediaStream
。这将允许从存储的数据或任意数据源(例如传感器或其他输入)进行流式传输。
getUserMedia()
与其他 JavaScript API 和库结合使用,能够真正发挥作用:
- Webcam Toy 是一款 Photobooth 应用,它使用 WebGL 为可在本地分享或保存的照片添加各种奇特的奇妙效果。
- FaceKat 是一款使用 headtrackr.js 构建的面部跟踪游戏。
- ASCII Camera 使用 Canvas API 生成 ASCII 图片。
限制条件
限制条件可用于为 getUserMedia()
设置视频分辨率值。这样还可以支持其他约束条件,例如宽高比;朝向模式(前置或后置摄像头);帧速率、高度和宽度和 applyConstraints()
方法。
如需查看示例,请参阅 WebRTC 示例 getUserMedia
:选择分辨率。
例如,如果请求分辨率不可用,则设置禁止的约束条件值会给出 DOMException
或 OverconstrainedError
。如需查看实际操作,请参阅 WebRTC 示例 getUserMedia
:选择分辨率进行演示。
屏幕和标签页截取
借助 Chrome 应用,您还可以通过 chrome.tabCapture
和 chrome.desktopCapture
API 分享单个浏览器标签页或整个桌面的实时视频。(如需查看演示和更多信息,请参阅通过 WebRTC 共享屏幕。这篇文章是几年前发布的,但仍然很有趣。)
您还可以使用实验性 chromeMediaSource
约束条件在 Chrome 中使用屏幕截图作为 MediaStream
来源。请注意,屏幕截图需要使用 HTTPS,并且只应用于开发,因为此功能是通过命令行标志启用的(如博文中所述)。
信号:会话控制、网络和媒体信息
WebRTC 使用 RTCPeerConnection
在浏览器(也称为对等端)之间传输流式数据,但还需要一种机制来协调通信并发送控制消息,此过程称为信令。WebRTC 不指定信令方法和协议。信号不是 RTCPeerConnection
API 的一部分。
相反,WebRTC 应用开发者可以选择他们偏好的任何消息传递协议(例如 SIP 或 XMPP),以及任何适当的双工(双向)通信通道。appr.tc 示例使用 XHR 和通道 API 作为信号机制。Codelab 使用在 Node 服务器上运行的 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);
}
};
首先,小丽和小刚交换网络信息。(“查找候选定位设置”是指使用 ICE 框架查找网络接口和端口的过程。)
- Alice 创建了一个带有
onicecandidate
处理程序的RTCPeerConnection
对象,该对象会在网络候选网络可用时运行。 - Alice 通过其使用的任何信令信道(如 WebSocket 或其他某种机制)将序列化的候选人数据发送给 Bob。
- 当 Bob 收到来自 Alice 的候选消息时,会调用
addIceCandidate
将该候选者添加到远程对等设备说明中。
WebRTC 客户端(在本例中也称为“对等设备”,或本例中的 Alice 和 Bob)还需要确定和交换本地和远程音频和视频媒体信息,例如分辨率和编解码器功能。系统通过使用会话描述协议 (SDP) 交换报价和应答来发出交换媒体配置信息的信号:
- Alice 运行
RTCPeerConnection
createOffer()
方法。系统会向此字段的返回传递RTCSessionDescription
- Alice 的本地会话说明。 - 在该回调中,Alice 使用
setLocalDescription()
设置本地说明,然后通过 Bob 的信号通道将此会话说明发送给 Bob。请注意,在调用setLocalDescription()
之前,RTCPeerConnection
不会开始收集候选项。这已编码在 JSEP IETF 草案中。 - Bob 使用
setRemoteDescription()
将 Alice 发送给他的说明设置为远程说明。 - Bob 运行
RTCPeerConnection
createAnswer()
方法,向其传递从 Alice 获取的远程说明,以便生成与 Alice 兼容的本地会话。系统会向createAnswer()
回调传递RTCSessionDescription
。Bob 将其设为本地描述并将其发送给 Alice。 - 当 Alice 获得 Bob 的会话说明后,使用
setRemoteDescription
将该说明设置为远程说明。 - ping!
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 实施展示了一段优秀的动画,介绍信令和流式传输过程。)
<ph type="x-smartling-placeholder">信令过程成功完成后,数据可以直接在调用方和被调用方之间以点对点的方式流式传输;如果失败,可通过中间中继服务器流式传输(稍后会详细介绍)。流式传输是 RTCPeerConnection
的工作。
RTCPeerConnection
RTCPeerConnection
是一个 WebRTC 组件,用于处理对等方之间的流式数据之间稳定而高效的通信。
下面的 WebRTC 架构图展示了 RTCPeerConnection
的作用。您会发现,绿色部分很复杂!
从 JavaScript 的角度来看,这个图中需要理解的主要内容是,RTCPeerConnection
可以保护 Web 开发者免受隐含的无数复杂性的侵扰。为了实现实时通信,WebRTC 使用的编解码器和协议做了大量的工作,即使在不可靠的网络上也不例外:
- 丢包隐藏
- 回声消除
- 带宽自适应
- 动态抖动缓冲
- 自动增益控制
- 降噪和抑制
- 图片清理
之前的 W3C 代码从信号角度展示了 WebRTC 的简化示例。以下是两个正常运行的 WebRTC 应用的演示。第一个是一个简单的示例,用于演示 RTCPeerConnection
,第二个是完全可操作的视频聊天客户端。
不使用服务器的 RTCPeerConnection
以下代码取自 WebRTC 示例对等连接,该示例在一个网页上包含本地和远程 RTCPeerConnection
(以及本地和远程视频)。这不会构成任何非常有用的内容(调用方和被调用方位于同一页面上),但确实会使 RTCPeerConnection
API 的运行变得更加清晰,因为页面上的 RTCPeerConnection
对象可以直接交换数据和消息,而无需使用中间信号机制。
在此示例中,pc1
表示本地对等方(调用方),pc2
表示远程对等方(被调用方)。
来电者
- 创建一个新的
RTCPeerConnection
并添加来自getUserMedia()
的流: ```js // Servers 是可选的配置文件。(请参阅稍后关于 TURN 和 STUN 的讨论。) pc1 = 新的 RTCPeerConnection(servers); // ... localStream.getTracks().forEach((track) => { pc1.addTrack(track, localStream); });
- 创建优惠,并将其设置为
pc1
的本地说明和pc2
的远程说明。这可以直接在代码中完成,而无需使用信号,因为调用方和被调用方位于同一页面上:js pc1.setLocalDescription(desc).then(() => { onSetLocalSuccess(pc1); }, onSetSessionDescriptionError ); trace('pc2 setRemoteDescription start'); pc2.setRemoteDescription(desc).then(() => { onSetRemoteSuccess(pc2); }, onSetSessionDescriptionError );
被调用方
- 创建
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 应用所需的后端服务。)
<ph type="x-smartling-placeholder">如果 UDP 失败,ICE 会尝试使用 TCP。如果直接连接失败(特别是由于企业 NAT 穿越和防火墙),ICE 会使用中间(中继)TURN 服务器。换言之,ICE 会先使用 STUN 和 UDP 直接连接对等方,如果连接失败,则会回退到 TURN 中继服务器。“查找候选项”表达式是指查找网络接口和端口的过程。
<ph type="x-smartling-placeholder">WebRTC 工程师 Justin Uberti 在 2013 年 Google I/O WebRTC 演示文稿中详细介绍了 ICE、STUN 和 TURN。(演示文稿幻灯片提供了 TURN 和 STUN 服务器实现的示例。)
简单的视频聊天客户端
appr.tc 中的视频聊天演示是试用 WebRTC 的好地方,该演示具有使用 STUN 服务器的信号实现和 NAT/防火墙遍历功能。此应用使用 adapter.js,一种 shim,用于使应用免受规范变更和前缀差异的影响。
代码被特意记录的详细内容。查看控制台,了解事件的顺序。以下是详细的代码演示。
网络拓扑
目前实现的 WebRTC 仅支持一对一通信,但可用于更复杂的网络场景,例如与多个对等方相互通信,每个对等体相互直接通信,或通过多点控制单元 (MCU) 或多点控制单元 (MCU)。MCU 是一台服务器,可以处理大量参与者并有选择地转发流以及进行音频和视频混音或录制。
<ph type="x-smartling-placeholder">许多现有的 WebRTC 应用仅演示网络浏览器之间的通信,但网关服务器可以让浏览器上运行的 WebRTC 应用与设备(如电话,也称为 PSTN)和 VOIP 系统进行交互。2012 年 5 月,Doubango Telecom 开放了使用 WebRTC 和 WebSocket 构建的 sipml5 SIP 客户端的源代码,该客户端(以及其他潜在用途)支持在 iOS 和 Android 上运行的浏览器与应用之间进行视频通话。在 Google I/O 大会上,Teethr 和 Tropo 以公文包形式展示了灾难通讯框架,该框架使用一个 OpenBTS 单元通过 WebRTC 实现非智能手机和计算机之间的通信。不用运营商服务也能通话!
<ph type="x-smartling-placeholder">RTCDataChannel
API<
除音频和视频外,WebRTC 还支持其他类型的数据的实时通信。
RTCDataChannel
API 支持点对点交换任意数据,并且延迟低、吞吐量高。如需查看单页演示并了解如何构建简单的文件传输应用,请分别参阅 WebRTC 示例和 WebRTC Codelab。
该 API 有许多潜在用例,包括:
- 游戏
- 远程桌面应用
- 实时文字聊天
- 文件传输
- 分散式网络
此 API 有多项功能可充分利用 RTCPeerConnection
并实现强大且灵活的点对点通信:
- 利用
RTCPeerConnection
会话设置 - 按优先级同步多个渠道
- 可靠和不可靠的交付语义
- 内置安全机制 (DTLS) 和拥塞控制
- 能否搭配音频或视频使用
该语法被特意设计为类似于具有 send()
方法和 message
事件的 WebSocket:
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);
};
由于通信是直接在浏览器之间进行的,因此在打孔以应对防火墙和 NAT 失败时,即使需要使用中继 (TURN) 服务器,RTCDataChannel
的速度也可能比 WebSocket 快得多。
RTCDataChannel
支持 Chrome、Safari、Firefox、Opera 和 Samsung Internet。Cube Slam 游戏使用该 API 传达游戏状态。与朋友一起玩,或者扮演小熊!创新平台 Sharefest 通过 RTCDataChannel
和 peerCDN 实现文件共享,让大家可以大致了解 WebRTC 如何实现点对点内容分发。
如需详细了解 RTCDataChannel
,请参阅 IETF 的协议规范草案。
安全
实时通信应用或插件可能会通过多种方式损害安全性。例如:
- 未加密的媒体或数据可能会在浏览器之间或在浏览器与服务器之间被拦截。
- 应用可能会在用户不知情的情况下录制和分发视频或音频。
- 恶意软件或病毒可能会与看似无害的插件或应用一起安装。
WebRTC 有多项功能可以避免这些问题:
- WebRTC 实现使用 DTLS 和 SRTP 等安全协议。
- 所有 WebRTC 组件(包括信令机制)都必须进行加密。
- WebRTC 不是插件。其组件是在浏览器沙盒中运行,而不是在单独的进程中运行。组件不需要单独安装,并且会在浏览器更新时随之更新。
- 必须明确授予摄像头和麦克风使用权限,并且当摄像头或麦克风运行时,界面会清楚地显示此权限。
本文不对流媒体安全性进行全面讨论。有关详情,请参阅 IETF 提出的提议的 WebRTC 安全架构。
总结
WebRTC 的 API 和标准可以普及和分散用于内容创作和通信的工具,包括电话、游戏、视频制作、音乐制作和新闻收集工具。
技术的颠覆性没有比这更明显。
正如博主 Phil Edholm 所说:“WebRTC 和 HTML5 可以实现与原始浏览器在信息通信方面相同的转换。”
开发者工具
- 如需查看正在进行的会话的 WebRTC 统计信息,请访问:
<ph type="x-smartling-placeholder">
- </ph>
- 在 Chrome 中使用 about://webrtc-internals
- Opera 中的 opera://webrtc-internals
- Firefox 中的 about:webrtc <ph type="x-smartling-placeholder">
- 跨浏览器互操作说明
- adapter.js 是适用于 WebRTC 的 JavaScript shim,由 Google 在 WebRTC 社区的帮助下进行维护,该社区对供应商前缀、浏览器差异和规范变更进行抽象化处理。
- 如需详细了解 WebRTC 信号传递过程,请查看控制台的 appr.tc 日志输出。
- 如果工作量太多,建议您使用 WebRTC 框架,甚至是完整的 WebRTC 服务。
- 欢迎您提供错误报告和功能请求: <ph type="x-smartling-placeholder">
了解详情
- Justin Uberti 在 2012 年 Google I/O 大会上的 WebRTC 讲座
- Alan B.Johnston 和 Daniel C.现在,Burnett 在 webrtcbook.com 上发布了第三版印刷版和电子书版 WebRTC 图书。
- webrtc.org 包含 WebRTC 的所有功能,包括演示、文档和讨论。
- aosp-webrtc 是一个用于讨论 WebRTC 技术讨论的 Google 群组。
- @webrtc
- Google Developers Talk 文档详细介绍了 NAT 遍历、STUN、中继服务器和候选人收集。
- GitHub 上的 WebRTC
- Stack Overflow 是寻找 WebRTC 相关解答和提出相关问题的好去处。
标准和协议
- WebRTC W3C 编辑器草稿
- W3C 编辑器草稿:媒体捕获和流(也称为
getUserMedia
) - IETF 工作组章程
- IETF WebRTC 数据通道协议草案
- IETF JSEP 草稿
- IETF 提议的 ICE 标准
- IETF RTCWEB 工作组互联网草案:网络实时通信用例和要求
WebRTC 支持摘要
MediaStream
和 getUserMedia
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 上的 Safari 11.1 及更高版本
- Android 设备上的 UC 11.8 及更高版本
- Samsung Internet 4 及更高版本
RTCPeerConnection
API
- Chrome 桌面版 20 及更高版本;Chrome(Android 29 及更高版本)(无标记)
- Opera 18 及更高版本(默认启用);适用于 Android 20 及更高版本的 Opera(默认开启)
- Firefox 22 及更高版本(默认开启)
- Microsoft Edge 16 及更高版本
- iOS 上的 Safari 11.2 及更高版本以及 MacOS 上的 Safari 11.1 及更高版本
- Samsung Internet 4 及更高版本
RTCDataChannel
API
- Chrome 25 中的实验性版本,但在 Chrome 26 及更高版本中更稳定(以及与 Firefox 交互操作功能);Chrome(Android 29 及更高版本)
- Opera 18 及更高版本中的稳定版(以及与 Firefox 交互操作功能);适用于 Android 20 及更高版本的 Opera
- Firefox 22 及更高版本(默认开启)
如需详细了解针对 API 的跨平台支持(例如 getUserMedia
和 RTCPeerConnection
),请参阅 caniuse.com 和 Chrome 平台状态。
也可以在 webrtc.org 上的文档中找到适用于 RTCPeerConnection
的原生 API。