开始使用 WebRTC

488 阅读21分钟

WebRTC 是开放和不受阻碍的网络长期战争中的新战线。

Brendan Eich,JavaScript 的发明者

无需插件的实时通信#

想象一个您的手机、电视和计算机可以在一个通用平台上进行通信的世界。想象一下,将视频聊天和点对点数据共享添加到您的 Web 应用程序很容易。这就是 WebRTC 的愿景。 想试试吗?WebRTC 可在 Google Chrome、Safari、Firefox 和 Opera 的桌面和移动设备上使用。appr.tc上的简单视频聊天应用程序是一个很好的起点:

  1. 在浏览器中打开appr.tc。
  2. 单击加入以加入聊天室并让应用程序使用您的网络摄像头。
  3. 在新选项卡中打开页面末尾显示的 URL,或者更好的是,在另一台计算机上打开。

或者,直接跳转到WebRTC 代码实验室,这是一个分步指南,它解释了如何构建一个完整的视频聊天应用程序,包括一个简单的信号服务器。

WebRTC 的简短历史#

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

从历史上看,RTC 一直是公司化的和复杂的,需要在内部获得许可或开发昂贵的音频和视频技术。将 RTC 技术与现有内容、数据和服务集成起来既困难又耗时,尤其是在 Web 上。

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

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

  • 许多 Web 服务使用 RTC,但需要下载、本机应用程序或插件。其中包括 Skype、Facebook 和环聊。
  • 下载、安装和更新插件很复杂、容易出错并且很烦人。
  • 插件难以部署、调试、故障排除、测试和维护 - 并且可能需要许可和与复杂、昂贵的技术集成。通常很难说服人们首先安装插件! WebRTC 项目的指导原则是其 API 应该是开源的、免费的、标准化的、内置于 Web 浏览器中,并且比现有技术更高效。

我们现在在哪?#

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 示例 Peer connectionappr.tc。这个应用程序使用了adapter.js ,一个由谷歌在WebRTC社区的帮助下维护的JavaScript shim ,来抽象出浏览器的差异和规范的变化。

RTCDataChannel:要查看此操作,请参阅WebRTC 示例以查看其中一个数据通道演示。

WebRTC 代码实验室展示了如何使用所有三个 API 来构建用于视频聊天和文件共享的简单应用程序。

你的第一个 WebRTC #

WebRTC 应用需要做几件事:

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

为了获取和传输流数据,WebRTC 实现了以下 API:

  • MediaStream访问数据流,例如来自用户的摄像头和麦克风。
  • RTCPeerConnection使用加密和带宽管理设施启用音频或视频通话。
  • RTCDataChannel实现通用数据的点对点通信。 (稍后将详细讨论 WebRTC 的网络和信令方面。)

MediaStreamAPI(也称为getUserMediaAPI)#

MediaStreamAPI表示同步的媒体流。例如,从摄像头和麦克风输入获取的流具有同步的视频和音频轨道。(不要MediaStreamTrack<track>元素混淆,这是完全不同的东西。)

理解MediaStreamAPI 的最简单方法可能是在野外查看它:

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

每个MediaStream都有一个输入,它可能是由MediaStream生成的getUserMedia(),还有一个输出,它可能被传递给一个视频元素或一个RTCPeerConnection.

getUserMedia()方法采用MediaStreamConstraints对象参数并返回Promise解析为MediaStream对象的 a。

每个MediaStream都有一个label,例如'Xk7EuLhsuHKbnjLWkW4yYGNJJ8ONsgwHBvLQ'MediaStreamTracks的数组由getAudioTracks()andgetVideoTracks()方法返回。

例如getUserMediastream.getAudioTracks()返回一个空数组(因为没有音频),并且假设连接了一个工作网络摄像头,则stream.getVideoTracks()返回一个MediaStreamTrack表示来自网络摄像头的流的数组。每个MediaStreamTrack都有一个种类('video''audio'),一个label(类似于'FaceTime HD Camera (Built-in)'),并代表一个或多个音频或视频通道。在这种情况下,只有一个视频轨道,没有音频,但很容易想象还有更多的用例,例如从前置摄像头、后置摄像头、麦克风获取流的聊天应用程序,以及共享其屏幕。

AMediaStream可以通过设置srcObject属性附加到视频元素。以前,这是通过将src属性设置为使用 创建的对象 URL 来完成的URL.createObjectURL(),但这已被弃用

image.png 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()。第一次,浏览器的信息栏中会显示一个允许按钮。HTTP 访问getUserMedia()在 2015 年底被 Chrome 弃用,因为它被归类为强大的功能

其目的可能是MediaStream为任何流数据源启用 a,而不仅仅是相机或麦克风。这将支持从存储的数据或任意数据源(例如传感器或其他输入)进行流式传输。

getUserMedia()真正与其他 JavaScript API 和库结合使用:

约束#

约束可用于设置视频分辨率的值getUserMedia()。这也允许支持其他约束,例如纵横比;面向模式(前置或后置摄像头);帧速率、高度和宽度;和一种applyConstraints()方法。

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

image.png

设置不允许的约束值会给出一个DOMException或一个OverconstrainedError如果,例如,请求的解决方案不可用。要查看此操作,请参阅WebRTC 示例getUserMedia:为演示选择分辨率。

屏幕和选项卡捕获#

Chrome 应用程序还可以通过API共享单个浏览器选项卡或整个桌面的实时视频chrome.tabCapturechrome.desktopCapture(有关演示和更多信息,请参阅Screensharing with WebRTC。这篇文章已有几年历史了,但它仍然很有趣。)

也可以使用实验约束MediaStream在 Chrome 中使用屏幕截图作为来源。chromeMediaSource请注意,屏幕截图需要 HTTPS,并且只能用于开发,因为它是通过命令行标志启用的,如本文所述

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

WebRTC 用于RTCPeerConnection在浏览器(也称为对等点)之间传递流数据,但也需要一种机制来协调通信和发送控制消息,这一过程称为信令。WebRTC未指定信令方法和协议。信令不是RTCPeerConnectionAPI 的一部分。

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

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

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

通过信令的信息交换必须在点对点流传输开始之前成功完成。

例如,假设 Alice 想与 Bob 通信。这是来自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 创建一个RTCPeerConnection带有onicecandidate处理程序的对象,该处理程序在网络候选可用时运行。
  2. Alice 通过他们使用的任何信号通道(例如 WebSocket 或其他一些机制)将序列化的候选数据发送给 Bob。
  3. 当 Bob 从 Alice 那里得到一条候选消息时,他调用addIceCandidate将候选添加到远程对等点描述中。 WebRTC 客户端(在本例中也称为peers或 Alice 和 Bob)还需要确定和交换本地和远程音频和视频媒体信息,例如分辨率和编解码器能力。交换媒体配置信息的信令通过使用会话描述协议 (SDP)交换提议答案来进行:
  4. Alice 运行该RTCPeerConnection createOffer()方法。来自此的返回被传递一个RTCSessionDescription- Alice 的本地会话描述。
  5. 在回调中,Alice 设置本地描述使用setLocalDescription(),然后通过他们的信令通道将此会话描述发送给 Bob。请注意,在被调用RTCPeerConnection之前不会开始收集候选人。setLocalDescription()这在JSEP IETF 草案中进行了编纂。
  6. Bob 使用 将 Alice 发送给他的描述设置为远程描述setRemoteDescription()
  7. Bob 运行该RTCPeerConnection createAnswer()方法,将他从 Alice 那里得到的远程描述传递给它,这样就可以生成一个与她兼容的本地会话。回调createAnswer()传递一个. RTCSessionDescriptionBob 将其设置为本地描述并将其发送给 Alice。
  8. 当 Alice 获得 Bob 的会话描述时,她将其设置为远程描述,使用setRemoteDescription.
  9. 平!

image.png 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 实现的演示视频中,有一个很好的动画解释了信令和流式传输的过程。)

image.png 一旦信令过程成功完成,数据就可以在调用者和被调用者之间直接点对点地流式传输——或者,如果失败,则通过中间中继服务器(稍后将详细介绍)。流媒体是RTCPeerConnection.

RTCPeerConnection #

RTCPeerConnection是 WebRTC 组件,用于处理对等点之间流数据的稳定高效通信。

下面是一个 WebRTC 架构图,展示了RTCPeerConnection. 您会注意到,绿色部分很复杂!

image.png 从 JavaScript 的角度来看,从这个图表中要理解的主要内容是,它使RTCPeerConnectionWeb 开发人员免受潜伏在下面的无数复杂性的影响。WebRTC 使用的编解码器和协议做了大量工作以使实时通信成为可能,即使在不可靠的网络上也是如此:

  • 丢包隐藏
  • 回声消除
  • 带宽适应性
  • 动态抖动缓冲
  • 自动增益控制
  • 降噪和抑制
  • 图像清理 前面的 W3C 代码从信令的角度展示了 WebRTC 的简化示例。以下是两个工作 WebRTC 应用程序的演练。第一个是一个简单的演示示例,RTCPeerConnection第二个是一个完全可操作的视频聊天客户端。

没有服务器的 RTCPeerConnection #

以下代码取自WebRTC 示例 Peer connection ,它在一个网页上具有本地远程(以及本地和远程视频)。RTCPeerConnection这并不构成任何非常有用的东西——调用者和被调用者在同一个页面上——但它确实使RTCPeerConnectionAPI 的工作更加清晰,因为RTCPeerConnection页面上的对象可以直接交换数据和消息,而无需使用中间信号机制。

在本例中,pc1代表本地对等点(调用者)并pc2代表远程对等点(被调用者)。

来电者#

  1. 创建一个新RTCPeerConnection的并从以下位置添加流getUserMedia()
// Servers is an optional configuration file. (See TURN and STUN discussion later.)\
pc1 = new RTCPeerConnection(servers);\
// ...\
localStream.getTracks().forEach((track) => {\
    pc1.addTrack(track, localStream);\
});
  1. 创建报价并将其设置为 的本地描述pc1和远程描述pc2。这可以直接在代码中完成,无需使用信号,因为调用者和被调用者都在同一页面上:
pc1.setLocalDescription(desc).then(() => {\
    onSetLocalSuccess(pc1);\
},\
    onSetSessionDescriptionError\
);\
trace('pc2 setRemoteDescription start');\
pc2.setRemoteDescription(desc).then(() => {\
    onSetRemoteSuccess(pc2);\
    },\
    onSetSessionDescriptionError\
);

被调用者#

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

RTCPeerConnectionAPI 加服务器#

在现实世界中,无论多么简单,WebRTC 都需要服务器,因此可能会发生以下情况:

  • 用户发现彼此并交换真实世界的详细信息,例如姓名。
  • WebRTC 客户端应用程序(对等)交换网络信息。
  • 对等点交换有关媒体的数据,例如视频格式和分辨率。
  • WebRTC 客户端应用程序遍历NAT 网关和防火墙。

换句话说,WebRTC 需要四种类型的服务器端功能:

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

NAT 遍历、对等网络以及为用户发现和信令构建服务器应用程序的要求超出了本文的范围。可以说,ICE框架使用STUN协议及其扩展TURN来应对 NAT 遍历和其他网络变幻莫测。RTCPeerConnection

ICE 是一个用于连接对等点的框架,例如两个视频聊天客户端。最初,ICE 尝试通过 UDP 以尽可能低的延迟直接连接对等点。 在这个过程中,STUN 服务器有一个任务:使 NAT 后面的对等点能够找到它的公共地址和端口。(有关 STUN 和 TURN 的更多信息,请参阅构建 WebRTC 应用程序所需的后端服务。)

image.png 如果 UDP 失败,ICE 会尝试 TCP。如果直接连接失败 - 特别是由于企业 NAT 穿越和防火墙 - ICE 使用中间(中继)TURN 服务器。换句话说,ICE 首先使用 STUN 和 UDP 直接连接对等点,如果失败,则回退到 TURN 中继服务器。寻找候选的表达是指寻找网络接口和端口的过程。

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

一个简单的视频聊天客户端#

appr.tc上的视频聊天演示是一个尝试 WebRTC 的好地方,其中包含使用 STUN 服务器的信令和 NAT/防火墙穿越。这个应用程序使用了adapter.js,一个 shim 将应用程序与规范更改和前缀差异隔离开来。

该代码在其日志记录中故意冗长。检查控制台以了解事件的顺序。以下是代码的详细演练。

image.png

网络拓扑#

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

image.png 许多现有的 WebRTC 应用程序仅演示 Web 浏览器之间的通信,但网关服务器可以使运行在浏览器上的 WebRTC 应用程序能够与设备(例如电话(也称为PSTN)和VOIP系统)进行交互。2012 年 5 月,Doubango Telecom 开源了使用 WebRTC 和 WebSocket 构建的sipml5 SIP 客户端,它(以及其他潜在用途)支持在 iOS 和 Android 上运行的浏览器和应用程序之间的视频通话。在 Google I/O 上,Tethr 和 Tropo使用OpenBTS 单元在公文包中展示了灾难通信框架 ****通过 WebRTC 实现功能手机和计算机之间的通信。无需运营商的电话通讯!

image.png

RTCDataChannelAPI< #

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

RTCDataChannelAPI 支持以低延迟和高吞吐量对任意数据进行点对点交换。有关单页演示并了解如何构建简单的文件传输应用程序,请分别参阅WebRTC 示例WebRTC 代码实验室。 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);
};

通信直接发生在浏览器之间,因此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 统计信息可以在以下位置找到:

    • Chrome 中的 about://webrtc-internals
    • Opera 中的 opera://webrtc-internals
    • 关于:Firefox 中的 webrtc

image.png

了解更多#

标准和协议#

WebRTC 支持总结#

MediaStreamgetUserMediaAPI #

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

RTCPeerConnection接口#

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

RTCDataChannel接口#

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

有关 API 的跨平台支持(例如getUserMedia和)的更多详细信息RTCPeerConnection,请参阅caniuse.comChrome 平台状态

RTCPeerConnection也可以在webrtc.org 上的文档中找到本机 API 。

原文连接: web.dev/webrtc-basi…

原文改进地址: github.com/GoogleChrom…