From 310fd066e91f454b990372ffa30e803cc8120975 Mon Sep 17 00:00:00 2001 From: Florian Merz Date: Thu, 11 Feb 2021 12:56:40 +0100 Subject: unslug zh-cn: move --- .../web/api/webrtc_api/architecture/index.html | 18 -- files/zh-cn/web/api/webrtc_api/overview/index.html | 23 -- .../web/api/webrtc_api/session_lifetime/index.html | 88 +++++++ .../web/api/webrtc_api/webrtc_basics/index.html | 263 --------------------- 4 files changed, 88 insertions(+), 304 deletions(-) delete mode 100644 files/zh-cn/web/api/webrtc_api/architecture/index.html delete mode 100644 files/zh-cn/web/api/webrtc_api/overview/index.html create mode 100644 files/zh-cn/web/api/webrtc_api/session_lifetime/index.html delete mode 100644 files/zh-cn/web/api/webrtc_api/webrtc_basics/index.html (limited to 'files/zh-cn/web/api/webrtc_api') diff --git a/files/zh-cn/web/api/webrtc_api/architecture/index.html b/files/zh-cn/web/api/webrtc_api/architecture/index.html deleted file mode 100644 index 5f37d83529..0000000000 --- a/files/zh-cn/web/api/webrtc_api/architecture/index.html +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: WebRTC 架构概览 -slug: Web/API/WebRTC_API/Architecture -tags: - - WebRTC 架构概览 -translation_of: Web/API/WebRTC_API/Protocols -translation_of_original: Web/API/WebRTC_API/Architecture ---- -

{{WebRTCSidebar}}

- -

用来创建WebRTC连接的API底层使用了一系列的网络协议和连接标准。这篇文章涵盖了这些标准。

- -

为了让WebRTC正常工作,需要的协议、标准和API比较繁多。因此对于初学者来说可能会比较难以理解。当你一旦上手,你会惊喜地发现原来这一切都是如此的优雅和简单易懂。至于你信不信,反正我是信了。

- - - - -

重定向 WebRTC 协议介绍

diff --git a/files/zh-cn/web/api/webrtc_api/overview/index.html b/files/zh-cn/web/api/webrtc_api/overview/index.html deleted file mode 100644 index da693553b8..0000000000 --- a/files/zh-cn/web/api/webrtc_api/overview/index.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: WebRTC API overview -slug: Web/API/WebRTC_API/Overview -translation_of: Web/API/WebRTC_API#WebRTC_concepts_and_usage -translation_of_original: Web/API/WebRTC_API/Overview ---- -

{{WebRTCSidebar}}

- -

WebRTC是由一些关联的API和协议一起协作,支持两个或多个终端之间交换数据和媒体信息的技术。这篇文章提供了这些APIs的介绍和提供的功能。

- -

RTCPeerConnection

- -

在媒体能够交换,或者数据通道建立之前,你需要把两个终端连接起来。这个连接过程的完成就是使用{{domxref("RTCPeerConnection")}} 接口。

- -

MediaStream

- -

{{domxref("MediaStream")}}接口描述了终端之间传输的媒体流。这个流由一个或多个媒体通道信息;通常这是一个音频通道或者视频通道信息。一个媒体流能够传输实时的媒体(例如音频通话或者视频会议等)或者已存的媒体(例如网上电影)。

- -

RTCDataChannel

- -

WebRTC支持在建立连接的两个终端之间相互的传输二进制数据。这个过程通过{{domxref("RTCDataChannel")}}接口。

- -

这个接口可以作为数据的反向通道,甚至作为主要的数据通道去交换各种数据。例如在游戏应用中,通过这个接口可以实现多玩家支持,相互传送玩家的动作更新之类的数据。

diff --git a/files/zh-cn/web/api/webrtc_api/session_lifetime/index.html b/files/zh-cn/web/api/webrtc_api/session_lifetime/index.html new file mode 100644 index 0000000000..86ddf25b47 --- /dev/null +++ b/files/zh-cn/web/api/webrtc_api/session_lifetime/index.html @@ -0,0 +1,88 @@ +--- +title: WebRTC 介绍 +slug: WebRTC/介绍 +translation_of: Web/API/WebRTC_API/Session_lifetime +--- +
+

此页面正在建设中,部分内容会移至其他页面,因为WebRTC指导资料已经建成。

+ +

WebRTC允许您将任意数据,音频或视频(或其任何组合)的点对点通信构建到浏览器应用程序中。 在本文中,我们将介绍一个WebRTC会话的生命周期,从建立连接到不再需要时关闭连接。

+
+ +

创建连接

+ +

互联网很大 很大。 那么多年以前,聪明的人看到它有多大,增长速度有多快,32位IP寻址系统的局限性,并意识到有些事情要做,所以他们开始设计一个新的 64位寻址系统。 但是他们意识到,完成转换需要更长时间才能持续32位地址,所以其他一些机智的人们想出了让多台计算机共享同一个32位IP地址的方法。 网络地址转换(NAT)是通过操纵LAN上的所有设备的数据出入的路由来支持这种地址共享的标准,所有这些设备都共享同一个WAN(全局)IP地址。

+ +

用户的问题是互联网上的每台个人计算机不再一定具有唯一的IP地址,实际上,每个设备的IP地址也会变,不仅可能由于设备从一个网络移动到另一个网络,也可能被NAT和/或DHCP改变。 对于尝试进行点对点网络的开发人员,这引入了一个难题:没有每个用户设备的唯一标识符,不可能立即自动地知道如何连接到Internet上的特定设备。 即使你知道你想谈论的人,你不一定知道如何到达他们,甚至也不知道他们的地址。

+ +

这就像您尝试向您的朋友Michelle发送一个包裹,但您只在这个包裹上贴了一个写着“Michelle”的标签,而您并不知道她的地址。 您得查到她的地址并将其包装在包中,要不然她会在想为什么你又忘记她的生日了。

+ +

这就是信令(Signaling)的由来。

+ +

信令

+ +

信令是在两个设备之间发送控制信息以确定通信协议、信道、媒体编解码器和格式以及数据传输方法以及任何所需的路由信息的过程。 关于WebRTC的信令流程最重要的一点是:信令在规范中并没有定义。所以开发者需要自己决定如何实现这个过程。开发者可以为应用程序引擎选择任意的信息协议(如SIP或XMPP),任意双向通信信道(如WebSocket或XMLHttpRequest)与持久连接服务器的API(如Google Channel API)一起工作。

+ +

你可能会想,为什么这么一个对于建立WebRTC连接至关重要的基本过程居然没有定义在规范里? 答案很简单:由于两个设备无法直接相互联系,规范无法预测WebRTC的所有可能用例,因此更明智的做法就是让开发人员们自己选择合适的网络技术和消息传递协议。

+ +

尤其是如果一个开发人员已经有了一个连接两个设备的方法,那也没有必要强迫他们就为了WebRTC使用另一个规范定义的方法。 由于WebRTC没有生活在真空中,所以可能还有其他的连接,因此,如果可以使用已有的连接通道,就可以避免添加额外的连接通道。

+ +

为了交换信令信息,您可以选择通过WebSocket连接来回发送JSON对象,或者您可以在适当的通道(Channel)上使用XMPP或SIP,或者您可以通过HTTPS使用XMLHttpRequest进行轮询或者其他任何你可以想出来的技术组合。你甚至可以使用电子邮件作为信号通道。

+ +

还值得注意的是,用于执行信令的信道甚至不需要通过网络。 一个Peer可以输出一个数据对象,这个数据对象可以被打印出来,然后物理携带(步行或由信鸽)直到进入另一个设备,然后由该设备输出响应,并以同种方式返回, 直到WebRTC对等连接打开。 这将带来非常高的延迟,但也是可以做到的。

+ +

信令期间交换的信息

+ +

信令期间需要交换的信息有三种基本类型:

+ + + +

只有在信令成功完成之后,打开WebRTC对等连接的过程才真正开始。

+ +

值得注意的是,在信令期间,信令服务器实际上不需要理解两个设备之间交换的数据或者对这些数据做任何处理。 信令服务器本质上就是一个中继器:两端连接的公共点,两端都知道它们的信令数据可以通过这个点来传输。 服务器不需要以任何方式对此信息做出反应。

+ +

信令过程

+ +

为了开启一个WebRTC会话,以下事件需要依次发生:

+ +
    +
  1. 每个Peer创建一个RTCPeerConnection对象,用来表示其WebRTC会话端。
  2. +
  3. 每个Peer建立一个icecandidate事件的响应程序,用来在监测到该事件时将这些candidates通过信令通道发送给另一个Peer。
  4. +
  5. 每个Peer建立一个track事件的响应程序,这个事件会在远程Peer添加一个track到其stream上时被触发。这个响应程序应将tracks和其消受者联系起来,例如{{HTMLElement("video")}}元素。
  6. +
  7. 呼叫者创建并与接收者共享一个唯一的标识符或某种令牌,使得它们之间的呼叫可以由信令服务器上的代码来识别。此标识符的确切内容和形式取决于您。
  8. +
  9. 每个Peer连接到一个约定的信令服务器,如WebSocket服务器,他们都知道如何与之交换消息。
  10. +
  11. 每个Peer告知信令服务器他们想加入同一WebRTC会话(由步骤4中建立的令牌标识)。
  12. +
  13. 描述,候选地址等 -- 之后会有更多
  14. +
+ +

ICE 重连

+ +

有时,在WebRTC会话的整个生命周期内,网络条件会发生变化。 其中一个用户可能会从蜂窝网络转移到WiFi网络,或者网络可能会变得拥塞。 当这种情况发生时,ICE代理可以选择执行ICE重连。 在这个过程中网络连接会进行重新协商,与执行初始ICE协商的方式完全相同,除了:媒体继续流过原始网络连接直到新的开始运行。 然后媒体转移到新的网络连接,旧的关闭。

+ +

不同的浏览器支持在不同情况下的进行ICE重连。 例如,并不是所有的浏览器都会因为网络拥塞执行ICE重连。

+ +

ICE重连有两个级别:全ICE重连会导致会话中的所有媒体流重新协商。 部分ICE重连允许ICE重新协商特定媒体流,而不是所有媒体流进行重新协商。 然而,有些浏览器还不支持部分ICE重启。 <<<你如何触发每一个?>>>

+ +

如果您需要以某种方式更改连接的配置(例如更改为不同的ICE服务器集),您可以调用RTCPeerConnection.setConfiguration()设置新的RTCConfiguration字典,然后重新启动ICE。

+ +

要明确触发ICE重新启动,只需通过调用RTCPeerConnection.createOffer()启动一个协商过程,同时指定iceRestart选项为true。 然后就像平时那样处理连接过程即可。

+ +

发送

+ +

getUserMedia(获取用户媒体)

+ +

LocalMediaStream object

+ +

接收

+ +

WebRTC 在Firefox浏览器的偏好选择选项是隐藏的。可以到 about:config 这个页面设置 'media.navigator.enabled' 为 'true'。

+ +
+

在Source tree 中有一些测试文件可以提供给您关于WebRTC如何工作的一个想法。具体例子请查看: dom/media/tests/local_video_test.html。您也可以尝试 服务器demo ,源代码: server source

+
+ +

 

diff --git a/files/zh-cn/web/api/webrtc_api/webrtc_basics/index.html b/files/zh-cn/web/api/webrtc_api/webrtc_basics/index.html deleted file mode 100644 index 67464bdbd1..0000000000 --- a/files/zh-cn/web/api/webrtc_api/webrtc_basics/index.html +++ /dev/null @@ -1,263 +0,0 @@ ---- -title: WebRTC basics -slug: Web/API/WebRTC_API/WebRTC_basics -translation_of: Web/API/WebRTC_API/Signaling_and_video_calling -translation_of_original: Web/API/WebRTC_API/WebRTC_basics ---- -

{{WebRTCSidebar}}

- -
-

当你理解 WebRTC 架构之后, 你就可以阅读本篇文章了。本篇文章将带领你贯穿整个跨浏览器 RTC 应用的创建过程。到本章结束的时候,你就拥有了一个可以运行的点对点的数据通道和媒体通道。

-
- -
-

本页的案例过期了! 不要再尝试他们了。

-
- -

注意

- -

由于近期 API 做了一些修改,一些比较老的案例需要修复,暂时不可用。

- - - -

当前可以正常工作的的案例是:

- - - -

正确的实现方式或许可以从标准中推断出来。

- -

本页包含的其余的过期的信息,在 bugzilla

- -

Shims

- -

就像你想的那样,这样前卫的 API 肯定需要浏览器前缀才可以,然后再将它转换成通用的变量。

- -
var RTCPeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
-var IceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate;
-var SessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription;
-navigator.getUserMedia = navigator.getUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
- -

RTCPeerConnection

- -

这是使用 peer 创建连接的起始点。它接收一个配置选项,其中配置了用来创建连接的 ICE 服务器信息。

- -
var pc = new RTCPeerConnection(configuration);
- -

RTCConfiguration

- -

 {{domxref("RTCConfiguration")}} 对象包含了一些信息,这些信息是关于用来做 ICE 的 TURN 和 / 或 STUN 服务器的。这是用来确保大多数用户可以避免因 NAT 和防火墙导致的无法建立连接。

- -
var configuration = {
-    iceServers: [
-        {urls: "stun:23.21.150.121"},
-        {urls: "stun:stun.l.google.com:19302"},
-        {urls: "turn:numb.viagenie.ca", credential: "webrtcdemo", username: "louis%40mozilla.com"}
-    ]
-}
- -

Google 运行了一个我们可以使用的公共 STUN 服务器。我也在 http://numb.viagenie.ca/ 创建了一个免费的可以访问 TURN 服务器的账户。可能你也想这么做,你只要替换到你自己的许可证书就可以了。

- - - -

ICECandidate

- - - -

创建好 PeerConnection 并传入可用的 STUNTURN 之后,当 ICE 框架找到可以使用 Peer 创建连接的 “候选者”,会立即触发一个事件(onicecandidate)。这些 “候选者” 就是 ICECandidate, 而且他们会在 PeerConnection#onicecandidate 事件中执行一个回调函数。

- -
pc.onicecandidate = function (e) {
-    // candidate exists in e.candidate
-    if (!e.candidate) return;
-    send("icecandidate", JSON.stringify(e.candidate));
-};
- -

回调函数执行之后,我们必须使用信令通道 (signal channel) 将候选发送到其他的点。在 Chrome 中,ICE 框架一般会找到重复的候选者,所以,我一般只发送第一个,然后将处理函数删除。Firfox 中将候选者包含在了 Offer SDP 中。

- -

Signal Channel

- -

现在我们有了 ICE 候选,然后需要将它发送到我们的另一端,以让它知道如何跟我们建立连接。然而,现在有一个先有鸡还是先有蛋的问题。我们想要 PeerConnection 发送数据到另一端,但是在那之前我们需要先把元数据发送过去……

- -

现在就是用到信令通道(Signal Channel)的时候了。它的任何一个数据传输方法都允许两个端点之间交换信息。在本文中,我们将使用 FireBase。因为它设置起来灰常简单,并且不需要任何主机或者服务器端的代码编写。

- -

现在我们想象只有两个两个方法:send(), 它将使用一个键,然后将数据赋值给它;recv() ,当一个键有值的时候会调用一个处理函数。

- -

数据库的结构就像下面这样:

- -
{
-    "": {
-        "candidate:": …
-        "offer": …
-        "answer": …
-    }
-}
- -

连接会被 roomId 分割,然后会保存四条信息:发起者 (oferer) 的 ICE 候选、应答者 (answerer) 的 ICE 候选、offer SDP 和 answer SDP.

- -

Offer

- -

Offer SDP 是用来向另一端描述期望格式(视频, 格式, 解编码, 加密, 解析度, 尺寸 等等)的元数据。

- -

一次信息的交换需要从一端拿到 offer,然后另外一端接受这个 offer 然后返回一个 answer。

- -
pc.createOffer(function (offer) {
-    pc.setLocalDescription(offer, function() {
-        send("offer", JSON.stringify(pc.localDescription));
-    }, errorHandler);
-}, errorHandler, options);
- -

errorHandler

- -

创建 offer 的过程如果出现问题,就会执行这个函数,并且将错误的详细信息作为第一个参数。

- -
var errorHandler = function (err) {
-    console.error(err);
-};
- -

options

- -

Offer SDP 的选项.

- -
var options = {
-    offerToReceiveAudio: true,
-    offerToReceiveVideo: true
-};
- -

offerToReceiveAudio/Video 告诉另一端,你想接收视频还是音频。对于 DataChannel 来说,这些是不需要的。

- -

offer 创建好之后,我们必须将本地 SDP 设置进去,然后通过信令通道将它发送到另一端,之久就静静地等待另一端的 Answer SDP 吧.

- -

Answer

- -

Answer SDP 跟 offer 是差不多的,只不过它是作为相应的。有点像接电话一样。我们只能在接收到 offer 的时候创建一次 Answer.

- -
recv("offer", function (offer) {
-    offer = new SessionDescription(JSON.parse(offer))
-    pc.setRemoteDescription(offer);
-
-    pc.createAnswer(function (answer) {
-        pc.setLocalDescription(answer, function() {
-            send("answer", JSON.stringify(pc.localDescription));
-        }, errorHandler);
-    }, errorHandler);
-});
- -

DataChannel

- -

我将首先阐述如何将 PeerConnection 用在 DataChannels API 上,并且如何在 peers 之间传输任意数据。

- -

注意:撰写这篇文章的时候,DataChannels 在 Chrome 和 Firefox 之间是无法互用的。Chrome 支持了一个类似的私有协议,这个协议将在不久被标准协议支持。

- -
var channel = pc.createDataChannel(channelName, channelOptions);
- -

offer 的创建者和 channel 的创建者应该是同一个 peer。 answer 的创建者将在 PeerConnection 的 ondatachannel 回调中接收到 这个 channel。你必须在创建了这个 offer 之后立即调用 createDataChannel()。

- -

channelName

- -

这个字符串会作为 channel 名字的标签。注意:确保你 Channel 的名字中没有空格,否则在 Chrome 中调用 createAnswer() 将会失败。

- -

channelOptions

- -
var channelOptions = {};
- -

当前 Chrome 还不支持这些选项,所以你可以将这些选项留空。检查 RFC 以获取更多关于这些选项的信息。

- -

Channel 事件和方法

- -

onopen

- -

当连接建立的时候会被执行。

- -

onerror

- -

连接创建出错时执行。第一个参数是一个 error 对象。

- -
channel.onerror = function (err) {
-    console.error("Channel Error:", err);
-};
- -

onmessage

- -
channel.onmessage = function (e) {
-    console.log("Got message:", e.data);
-}
- -

这是连接的核心。当你接收到消息的时候,这个方法会执行。第一个参数是一个包含了数据、接收时间和其它信息的 event 对象。

- -

onclose

- -

当连接关闭的时候执行。

- -

绑定事件

- -

如果你是这个 channel 的创建者(offerer), 你可以直接在通过 createChannel 创建的 DataChannel 上绑定事件。如果你是 answerer 你必须使用 PeerConnection 的 ondatachannel 回调去访问这个 channel。

- -
pc.ondatachannel = function (e) {
-    e.channel.onmessage = function () { … };
-};
- -

这个 channel 可以在传递到回调函数中的 event 对象中以 e.channel 的方式访问。

- -

send()

- -
channel.send("Hi Peer!");
- -

这个方法允许你直接传递数据到 peer!令人惊奇。你必须传递确保传递的数据是 String, Blob, ArrayBuffer 或者 ArrayBufferView 中的一种类型,所以,确保字符串化对象。

- -

close()

- -

在连接应该中止的时候关闭 channel。推荐在页面卸载的时候调用。

- -

Media

- -

现在我们将会涉及到如何传递诸如音视频的媒体的话题。要显示音视频,你必须在文档中加入包含 autoplay 属性的  <video> 标签。

- -

Get User Media

- -
<video id="preview" autoplay></video>
-
-var video = document.getElementById("preview");
-navigator.getUserMedia(constraints, function (stream) {
-    video.src = URL.createObjectURL(stream);
-}, errorHandler);
- -

constraints

- -

约定你想从用户获取到的媒体类型。

- -
var constraints = {
-    video: true,
-    audio: true
-};
- -

如果你只想进行音频聊天,移除 video 成员。

- -

errorHandler

- -

当返回请求的媒体错误时被调用

- -

Media Events and Methods

- -

addStream

- -

将从 getUserMedia 返回的流加入 PeerConnection。

- -
pc.addStream(stream);
- -

onaddstream

- -
<video id="otherPeer" autoplay></video>
-
-var otherPeer = document.getElementById("otherPeer");
-pc.onaddstream = function (e) {
-    otherPeer.src = URL.createObjectURL(e.stream);
-};
- -

当连接建立并且其它的 peer 通过 addStream 将流加入到了连接中时会被调用。你需要另外的 <video> 标签去显示其它 peer 的媒体。

- -

第一个参数是包含了其它 peer 流媒体的 event 对象。

-- cgit v1.2.3-54-g00ecf