日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

开始使用WebRTC

發(fā)布時間:2024/3/13 编程问答 58 豆豆
生活随笔 收集整理的這篇文章主要介紹了 开始使用WebRTC 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Get Started with WebRTC??機翻

原文:Get Started with WebRTC - HTML5 Rocks

無需插件即可進行實時通信

想象一下,在這樣一個世界中,您的手機、電視和計算機可以在一個通用平臺上進行通信。想象一下,將視頻聊天和對等數(shù)據(jù)共享添加到 Web 應用很容易。這就是WebRTC的愿景。

想試試嗎?WebRTC可在桌面和移動設備上使用Google Chrome,Safari,Firefox和Opera。一個好的起點是?appr.tc?的簡單視頻聊天應用程序:

  • 在瀏覽器中打開?appr.tc。
  • 單擊"加入"以加入聊天室,并讓應用使用您的網(wǎng)絡攝像頭。
  • 在新選項卡中打開頁面末尾顯示的 URL,或者更好的是,在其他計算機上打開 URL。
  • 快速入門

    沒有時間閱讀本文或只想要代碼?

  • 要獲得WebRTC的概述,請觀看以下Google I / O視頻或查看這些幻燈片:

  • 如果尚未使用 API,請參閱在 HTML5 中捕獲音頻和視頻,simpl.info getUserMedia。getUserMedia
  • 若要了解 API,請參閱以下示例和?RTCPeerConnection simpl.info。RTCPeerConnection
  • 要了解 WebRTC 如何使用服務器進行信令以及防火墻和 NAT 遍歷,請參閱?appr.tc?中的代碼和控制臺日志。
  • 迫不及待,現(xiàn)在只想嘗試WebRTC?嘗試?20 多個演示中的一些,這些演示演示了 WebRTC JavaScript API。
  • 您的機器和 WebRTC 遇到問題?訪問?WebRTC 疑難解答。
  • 或者,直接跳轉到WebRTC代碼實驗室,這是一個分步指南,解釋了如何構建一個完整的視頻聊天應用程序,包括一個簡單的信令服務器。

    WebRTC的非常短的歷史

    網(wǎng)絡面臨的最后一個主要挑戰(zhàn)之一是通過語音和視頻實現(xiàn)人類通信:實時通信或簡稱RTC。RTC 在 Web 應用中應與在文本輸入中輸入文本一樣自然。沒有它,你創(chuàng)新和開發(fā)新互動方式的能力就會受到限制。

    從歷史上看,RTC一直是企業(yè)和復雜的,需要昂貴的音頻和視頻技術在內部許可或開發(fā)。將 RTC 技術與現(xiàn)有內容、數(shù)據(jù)和服務集成既困難又耗時,尤其是在 Web 上。

    Gmail視頻聊天在2008年開始流行,2011年,谷歌推出了使用Talk的Hangouts(Gmail也是如此)。谷歌收購了GISP,該公司開發(fā)了RTC所需的許多組件,例如編解碼器和回聲消除技術。Google 開源了 GIPS 開發(fā)的技術,并與互聯(lián)網(wǎng)工程任務組 (IETF) 和萬維網(wǎng)聯(lián)盟 (W3C) 的相關標準機構合作,以確保行業(yè)共識。2011年5月,愛立信構建了WebRTC的第一個實現(xiàn)。

    WebRTC為實時,無插件的視頻,音頻和數(shù)據(jù)通信實施了開放標準。需求是真實的:

    • 許多 Web 服務使用 RTC,但需要下載、本機應用或插件。其中包括Skype,Facebook和Hangouts。
    • 下載,安裝和更新插件很復雜,容易出錯并且很煩人。
    • 插件難以部署、調試、故障排除、測試和維護,并且可能需要許可和與復雜、昂貴的技術集成。首先,通常很難說服人們安裝插件!

    WebRTC項目的指導原則是,其API應該是開源的,免費的,標準化的,內置于Web瀏覽器中,并且比現(xiàn)有技術更有效。

    我們現(xiàn)在在哪里?

    WebRTC用于各種應用程序,例如Google Meet。WebRTC還與WebKitGTK+和Qt原生應用程序集成。

    WebRTC實現(xiàn)了以下三個API:

    • MediaStream(也稱為getUserMedia)
    • RTCPeerConnection
    • RTCDataChannel

    API 定義在以下兩個規(guī)范中:

    • WebRTC
    • getUserMedia

    Chrome,Safari,Firefox,Edge和Opera在移動設備和桌面上都支持這三個API。

    getUserMedia:有關演示和代碼,請參閱?WebRTC 示例或嘗試 Chris Wilson 用作 Web 音頻輸入的驚人示例。getUserMedia

    RTCPeerConnection:有關簡單的演示和功能齊全的視頻聊天應用程序,請參閱?WebRTC 示例分別對等連接和?appr.tc。這個應用程序使用適配器.js,一個由谷歌在WebRTC社區(qū)的幫助下維護的JavaScript填充程序,以抽象出瀏覽器的差異和規(guī)格變化。

    RTCDataChannel:若要查看實際效果,請參閱?WebRTC 示例以查看其中一個數(shù)據(jù)通道演示。

    WebRTC codelab?展示了如何使用所有三個 API 來構建一個簡單的應用程序,用于視頻聊天和文件共享。

    您的第一個 WebRTC

    WebRTC應用程序需要做幾件事:

    • 獲取流式音頻、視頻或其他數(shù)據(jù)。
    • 獲取網(wǎng)絡信息,例如 IP 地址和端口,并將其與其他 WebRTC 客戶端(稱為對等方)交換以啟用連接,甚至通過?NAT?和防火墻。
    • 協(xié)調信令通信以報告錯誤并啟動或關閉會話。
    • 交換有關媒體和客戶端功能的信息,如分辨率和編解碼器。
    • 傳輸流式音頻、視頻或數(shù)據(jù)。

    為了獲取和通信流數(shù)據(jù),WebRTC 實現(xiàn)了以下 API:

    • MediaStream?可以訪問數(shù)據(jù)流,例如來自用戶的攝像頭和麥克風。
    • RTCPeerConnection?支持音頻或視頻通話,并提供加密和帶寬管理功能。
    • RTCDataChannel?支持通用數(shù)據(jù)的對等通信。

    (稍后將詳細討論WebRTC的網(wǎng)絡和信令方面。

    MediaStream接口(也稱為接口)getUserMedia

    MediaStream?API?表示同步的媒體流。例如,從攝像頭和麥克風輸入中獲取的流具有同步的視頻和音頻軌道。(不要與<track>元素混淆,這是完全不同的東西。MediaStreamTrack

    理解API的最簡單方法可能是在野外查看它:MediaStream

  • 在瀏覽器中,導航到?WebRTC 示例?getUserMedia。
  • 打開控制臺。
  • 檢查全局范圍內的變量。stream
  • 每個都有一個輸入(可能是由 生成的),還有一個輸出(可能傳遞給視頻元素或 )。MediaStreamMediaStreamgetUserMedia()RTCPeerConnection

    該方法采用?MediaStreamConstraints?對象參數(shù),并返回解析為對象的 參數(shù)。getUserMedia()PromiseMediaStream

    每個都有一個 ,例如 。由 and 方法返回 s 數(shù)組。MediaStreamlabel'Xk7EuLhsuHKbnjLWkW4yYGNJJ8ONsgwHBvLQ'MediaStreamTrackgetAudioTracks()getVideoTracks()

    對于?getUserMedia?示例,返回一個空數(shù)組(因為沒有音頻),并且假設連接了一個工作正常的網(wǎng)絡攝像頭,則返回一個數(shù)組,該數(shù)組表示來自網(wǎng)絡攝像頭的流。每個都有一個種類 ( 或 ),a(類似于 ),并表示音頻或視頻的一個或多個通道。在這種情況下,只有一個視頻軌道,沒有音頻,但很容易想象用例中還有更多,例如從前置攝像頭,后置攝像頭,麥克風獲取流的聊天應用程序以及共享其屏幕的應用程序。stream.getAudioTracks()stream.getVideoTracks()MediaStreamTrackMediaStreamTrack'video''audio'label'FaceTime HD Camera (Built-in)'

    可以通過設置?srcObject?屬性將 A?附加到視頻元素。以前,這是通過將屬性設置為使用 創(chuàng)建的對象 URL 來完成的,但這已被棄用。MediaStreamsrcURL.createObjectURL()

    正在主動使用相機,這會占用資源,并使相機保持打開狀態(tài)并打開相機燈亮。當您不再使用軌道時,請確保呼叫以關閉攝像機。MediaStreamTracktrack.stop()

    getUserMedia也可以用作 Web 音頻 API 的輸入節(jié)點:

    <span style="color:white"><span style="background-color:#444444"><span style="color:#aeaeae"><em>// Cope with browser differences.</em></span><span style="color:#ffffff"> let audioContext</span><span style="color:#ffffff">;</span> <span style="color:#e28964">if</span> <span style="color:#ffffff">(</span><span style="color:#e28964">typeof</span> <span style="color:#89bdff">AudioContext</span> <span style="color:#ffffff">===</span> <span style="color:#65b042">'function'</span><span style="color:#ffffff">)</span> <span style="color:#ffffff">{</span><span style="color:#ffffff">audioContext </span><span style="color:#ffffff">=</span> <span style="color:#e28964">new</span> <span style="color:#89bdff">AudioContext</span><span style="color:#ffffff">();</span> <span style="color:#ffffff">}</span> <span style="color:#e28964">else</span> <span style="color:#e28964">if</span> <span style="color:#ffffff">(</span><span style="color:#e28964">typeof</span><span style="color:#ffffff"> webkitAudioContext </span><span style="color:#ffffff">===</span> <span style="color:#65b042">'function'</span><span style="color:#ffffff">)</span> <span style="color:#ffffff">{</span><span style="color:#ffffff">audioContext </span><span style="color:#ffffff">=</span> <span style="color:#e28964">new</span><span style="color:#ffffff"> webkitAudioContext</span><span style="color:#ffffff">();</span> <span style="color:#aeaeae"><em>// eslint-disable-line new-cap</em></span> <span style="color:#ffffff">}</span> <span style="color:#e28964">else</span> <span style="color:#ffffff">{</span><span style="color:#ffffff">console</span><span style="color:#ffffff">.</span><span style="color:#ffffff">log</span><span style="color:#ffffff">(</span><span style="color:#65b042">'Sorry! Web Audio not supported.'</span><span style="color:#ffffff">);</span> <span style="color:#ffffff">}</span><span style="color:#aeaeae"><em>// Create a filter node.</em></span> <span style="color:#e28964">var</span><span style="color:#ffffff"> filterNode </span><span style="color:#ffffff">=</span><span style="color:#ffffff"> audioContext</span><span style="color:#ffffff">.</span><span style="color:#ffffff">createBiquadFilter</span><span style="color:#ffffff">();</span> <span style="color:#aeaeae"><em>// See https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#BiquadFilterNode-section</em></span><span style="color:#ffffff"> filterNode</span><span style="color:#ffffff">.</span><span style="color:#ffffff">type </span><span style="color:#ffffff">=</span> <span style="color:#65b042">'highpass'</span><span style="color:#ffffff">;</span> <span style="color:#aeaeae"><em>// Cutoff frequency. For highpass, audio is attenuated below this frequency.</em></span><span style="color:#ffffff"> filterNode</span><span style="color:#ffffff">.</span><span style="color:#ffffff">frequency</span><span style="color:#ffffff">.</span><span style="color:#ffffff">value </span><span style="color:#ffffff">=</span> <span style="color:#3387cc">10000</span><span style="color:#ffffff">;</span><span style="color:#aeaeae"><em>// Create a gain node to change audio volume.</em></span> <span style="color:#e28964">var</span><span style="color:#ffffff"> gainNode </span><span style="color:#ffffff">=</span><span style="color:#ffffff"> audioContext</span><span style="color:#ffffff">.</span><span style="color:#ffffff">createGain</span><span style="color:#ffffff">();</span> <span style="color:#aeaeae"><em>// Default is 1 (no change). Less than 1 means audio is attenuated</em></span> <span style="color:#aeaeae"><em>// and vice versa.</em></span><span style="color:#ffffff"> gainNode</span><span style="color:#ffffff">.</span><span style="color:#ffffff">gain</span><span style="color:#ffffff">.</span><span style="color:#ffffff">value </span><span style="color:#ffffff">=</span> <span style="color:#3387cc">0.5</span><span style="color:#ffffff">;</span><span style="color:#ffffff">navigator</span><span style="color:#ffffff">.</span><span style="color:#ffffff">mediaDevices</span><span style="color:#ffffff">.</span><span style="color:#ffffff">getUserMedia</span><span style="color:#ffffff">({</span><span style="color:#ffffff">audio</span><span style="color:#ffffff">:</span> <span style="color:#e28964">true</span><span style="color:#ffffff">},</span> <span style="color:#ffffff">(</span><span style="color:#ffffff">stream</span><span style="color:#ffffff">)</span> <span style="color:#ffffff">=></span> <span style="color:#ffffff">{</span><span style="color:#aeaeae"><em>// Create an AudioNode from the stream.</em></span><span style="color:#e28964">const</span><span style="color:#ffffff"> mediaStreamSource </span><span style="color:#ffffff">=</span><span style="color:#ffffff">audioContext</span><span style="color:#ffffff">.</span><span style="color:#ffffff">createMediaStreamSource</span><span style="color:#ffffff">(</span><span style="color:#ffffff">stream</span><span style="color:#ffffff">);</span><span style="color:#ffffff">mediaStreamSource</span><span style="color:#ffffff">.</span><span style="color:#ffffff">connect</span><span style="color:#ffffff">(</span><span style="color:#ffffff">filterNode</span><span style="color:#ffffff">);</span><span style="color:#ffffff">filterNode</span><span style="color:#ffffff">.</span><span style="color:#ffffff">connect</span><span style="color:#ffffff">(</span><span style="color:#ffffff">gainNode</span><span style="color:#ffffff">);</span><span style="color:#aeaeae"><em>// Connect the gain node to the destination. For example, play the sound.</em></span><span style="color:#ffffff">gainNode</span><span style="color:#ffffff">.</span><span style="color:#ffffff">connect</span><span style="color:#ffffff">(</span><span style="color:#ffffff">audioContext</span><span style="color:#ffffff">.</span><span style="color:#ffffff">destination</span><span style="color:#ffffff">);</span> <span style="color:#ffffff">});</span></span></span>

    基于Chromium的應用程序和擴展程序也可以合并。通過向清單添加和/或權限,只能在安裝時請求和授予一次權限。此后,不會要求用戶獲得相機或麥克風訪問權限。getUserMediaaudioCapturevideoCapture

    對于 , 只需授予一次權限。第一次,瀏覽器的信息欄中會顯示"允許"按鈕。Chrome 在 2015 年底棄用了 HTTP 訪問,因為它被歸類為功能強大的功能。getUserMedia()getUserMedia()

    其意圖可能是為任何流數(shù)據(jù)源啟用 a,而不僅僅是攝像頭或麥克風。這將允許從存儲的數(shù)據(jù)或任意數(shù)據(jù)源(如傳感器或其他輸入)進行流式傳輸。MediaStream

    getUserMedia()真正與其他 JavaScript API 和庫結合使用:

    • 網(wǎng)絡攝像頭玩具是一個照相亭應用程序,它使用WebGL為可以在本地共享或保存的照片添加奇怪而美妙的效果。
    • FaceKat是一款使用headtrackr.js構建的面部跟蹤游戲。
    • ASCII 相機使用 Canvas API 生成 ASCII 圖像。

    正在上傳…重新上傳取消

    咕嚕咕嚕的藝術!

    約束

    約束可用于設置 的視頻分辨率值。這也允許支持其他約束,例如寬高比;對置模式(前置或后置攝像頭);幀速率,高度和寬度;和?applyConstraints()?方法。getUserMedia()

    有關示例,請參閱?WebRTC 示例?getUserMedia:選擇分辨率。

    一個陷阱:約束可能會影響共享資源的可用配置。例如,如果相機在 640 x 480 模式下通過一個選項卡打開,則另一個選項卡將無法使用約束以更高分辨率模式打開它,因為它只能在一種模式下打開。請注意,這是一個實現(xiàn)細節(jié)。可以讓第二個選項卡以更高分辨率的模式重新打開相機,并使用視頻處理將第一個選項卡的視頻軌道縮小到640 x 480,但尚未實現(xiàn)。getUserMedia

    設置不允許的約束值會給出 a 或 a,例如,如果請求的分辨率不可用。若要查看此操作的實際效果,請參閱?WebRTC 示例?getUserMedia:為演示選擇分辨率。DOMExceptionOverconstrainedError

    屏幕和選項卡捕獲

    Chrome 應用還允許通過?chrome.tabCapture 和 chrome.desktopCapture?API 共享單個瀏覽器標簽頁或整個桌面的實時視頻。(有關演示和更多信息,請參閱使用 WebRTC 進行屏幕共享。這篇文章已經(jīng)有幾年的歷史了,但它仍然很有趣。

    在 Chrome 中,也可以使用實驗性約束將屏幕捕獲用作源。請注意,屏幕捕獲需要 HTTPS,并且只能用于開發(fā),因為它是通過命令行標志啟用的,如本文所述。MediaStreamchromeMediaSource

    信令:會話控制、網(wǎng)絡和媒體信息

    WebRTC用于在瀏覽器(也稱為對等體)之間傳輸流數(shù)據(jù),但也需要一種機制來協(xié)調通信和發(fā)送控制消息,這一過程稱為信令。WebRTC未指定信令方法和協(xié)議。信令不是 API 的一部分。RTCPeerConnectionRTCPeerConnection

    相反,WebRTC應用程序開發(fā)人員可以選擇他們喜歡的任何消息傳遞協(xié)議,例如SIP或XMPP,以及任何適當?shù)碾p工(雙向)通信通道。appr.tc?示例使用 XHR 和通道 API 作為信令機制。代碼實驗室使用在?Node?服務器上運行的 Socket.io。

    信令用于交換三種類型的信息:

    • 會話控制消息:初始化或關閉通信并報告錯誤。
    • 網(wǎng)絡配置:對外界來說,你電腦的IP地址和端口是什么?
    • 媒體功能:您的瀏覽器和要與之通信的瀏覽器可以處理哪些編解碼器和分辨率?

    通過信令進行的信息交換必須已成功完成,然后才能開始對等流。

    例如,假設愛麗絲想和鮑勃交流。下面是?W3C WebRTC 規(guī)范中的代碼示例,其中顯示了運行中的信令過程。該代碼假定存在該方法中創(chuàng)建的某些信令機制。另請注意,在 Chrome 和 Opera 上,當前帶有前綴。createSignalingChannel()RTCPeerConnection

    <span style="color:white"><span style="background-color:#444444"><span style="color:#aeaeae"><em>// handles JSON.stringify/parse</em></span> <span style="color:#e28964">const</span><span style="color:#ffffff"> signaling </span><span style="color:#ffffff">=</span> <span style="color:#e28964">new</span> <span style="color:#89bdff">SignalingChannel</span><span style="color:#ffffff">();</span> <span style="color:#e28964">const</span><span style="color:#ffffff"> constraints </span><span style="color:#ffffff">=</span> <span style="color:#ffffff">{</span><span style="color:#ffffff">audio</span><span style="color:#ffffff">:</span> <span style="color:#e28964">true</span><span style="color:#ffffff">,</span><span style="color:#ffffff"> video</span><span style="color:#ffffff">:</span> <span style="color:#e28964">true</span><span style="color:#ffffff">};</span> <span style="color:#e28964">const</span><span style="color:#ffffff"> configuration </span><span style="color:#ffffff">=</span> <span style="color:#ffffff">{</span><span style="color:#ffffff">iceServers</span><span style="color:#ffffff">:</span> <span style="color:#ffffff">[{</span><span style="color:#ffffff">urls</span><span style="color:#ffffff">:</span> <span style="color:#65b042">'stuns:stun.example.org'</span><span style="color:#ffffff">}]};</span> <span style="color:#e28964">const</span><span style="color:#ffffff"> pc </span><span style="color:#ffffff">=</span> <span style="color:#e28964">new</span> <span style="color:#89bdff">RTCPeerConnection</span><span style="color:#ffffff">(</span><span style="color:#ffffff">configuration</span><span style="color:#ffffff">);</span><span style="color:#aeaeae"><em>// Send any ice candidates to the other peer.</em></span><span style="color:#ffffff"> pc</span><span style="color:#ffffff">.</span><span style="color:#ffffff">onicecandidate </span><span style="color:#ffffff">=</span> <span style="color:#ffffff">({</span><span style="color:#ffffff">candidate</span><span style="color:#ffffff">})</span> <span style="color:#ffffff">=></span><span style="color:#ffffff"> signaling</span><span style="color:#ffffff">.</span><span style="color:#ffffff">send</span><span style="color:#ffffff">({</span><span style="color:#ffffff">candidate</span><span style="color:#ffffff">});</span><span style="color:#aeaeae"><em>// Let the "negotiationneeded" event trigger offer generation.</em></span><span style="color:#ffffff"> pc</span><span style="color:#ffffff">.</span><span style="color:#ffffff">onnegotiationneeded </span><span style="color:#ffffff">=</span><span style="color:#ffffff"> async </span><span style="color:#ffffff">()</span> <span style="color:#ffffff">=></span> <span style="color:#ffffff">{</span><span style="color:#e28964">try</span> <span style="color:#ffffff">{</span><span style="color:#ffffff">await pc</span><span style="color:#ffffff">.</span><span style="color:#ffffff">setLocalDescription</span><span style="color:#ffffff">(</span><span style="color:#ffffff">await pc</span><span style="color:#ffffff">.</span><span style="color:#ffffff">createOffer</span><span style="color:#ffffff">());</span><span style="color:#aeaeae"><em>// Send the offer to the other peer.</em></span><span style="color:#ffffff">signaling</span><span style="color:#ffffff">.</span><span style="color:#ffffff">send</span><span style="color:#ffffff">({</span><span style="color:#ffffff">desc</span><span style="color:#ffffff">:</span><span style="color:#ffffff"> pc</span><span style="color:#ffffff">.</span><span style="color:#ffffff">localDescription</span><span style="color:#ffffff">});</span><span style="color:#ffffff">}</span> <span style="color:#e28964">catch</span> <span style="color:#ffffff">(</span><span style="color:#ffffff">err</span><span style="color:#ffffff">)</span> <span style="color:#ffffff">{</span><span style="color:#ffffff">console</span><span style="color:#ffffff">.</span><span style="color:#ffffff">error</span><span style="color:#ffffff">(</span><span style="color:#ffffff">err</span><span style="color:#ffffff">);</span><span style="color:#ffffff">}</span> <span style="color:#ffffff">};</span><span style="color:#aeaeae"><em>// Once remote track media arrives, show it in remote video element.</em></span><span style="color:#ffffff"> pc</span><span style="color:#ffffff">.</span><span style="color:#ffffff">ontrack </span><span style="color:#ffffff">=</span> <span style="color:#ffffff">(</span><span style="color:#e28964">event</span><span style="color:#ffffff">)</span> <span style="color:#ffffff">=></span> <span style="color:#ffffff">{</span><span style="color:#aeaeae"><em>// Don't set srcObject again if it is already set.</em></span><span style="color:#e28964">if</span> <span style="color:#ffffff">(</span><span style="color:#ffffff">remoteView</span><span style="color:#ffffff">.</span><span style="color:#ffffff">srcObject</span><span style="color:#ffffff">)</span> <span style="color:#e28964">return</span><span style="color:#ffffff">;</span><span style="color:#ffffff">remoteView</span><span style="color:#ffffff">.</span><span style="color:#ffffff">srcObject </span><span style="color:#ffffff">=</span> <span style="color:#e28964">event</span><span style="color:#ffffff">.</span><span style="color:#ffffff">streams</span><span style="color:#ffffff">[</span><span style="color:#3387cc">0</span><span style="color:#ffffff">];</span> <span style="color:#ffffff">};</span><span style="color:#aeaeae"><em>// Call start() to initiate.</em></span><span style="color:#ffffff"> async </span><span style="color:#e28964">function</span><span style="color:#ffffff"> start</span><span style="color:#ffffff">()</span> <span style="color:#ffffff">{</span><span style="color:#e28964">try</span> <span style="color:#ffffff">{</span><span style="color:#aeaeae"><em>// Get local stream, show it in self-view, and add it to be sent.</em></span><span style="color:#e28964">const</span><span style="color:#ffffff"> stream </span><span style="color:#ffffff">=</span><span style="color:#ffffff">await navigator</span><span style="color:#ffffff">.</span><span style="color:#ffffff">mediaDevices</span><span style="color:#ffffff">.</span><span style="color:#ffffff">getUserMedia</span><span style="color:#ffffff">(</span><span style="color:#ffffff">constraints</span><span style="color:#ffffff">);</span><span style="color:#ffffff">stream</span><span style="color:#ffffff">.</span><span style="color:#ffffff">getTracks</span><span style="color:#ffffff">().</span><span style="color:#ffffff">forEach</span><span style="color:#ffffff">((</span><span style="color:#ffffff">track</span><span style="color:#ffffff">)</span> <span style="color:#ffffff">=></span><span style="color:#ffffff">pc</span><span style="color:#ffffff">.</span><span style="color:#ffffff">addTrack</span><span style="color:#ffffff">(</span><span style="color:#ffffff">track</span><span style="color:#ffffff">,</span><span style="color:#ffffff"> stream</span><span style="color:#ffffff">));</span><span style="color:#ffffff">selfView</span><span style="color:#ffffff">.</span><span style="color:#ffffff">srcObject </span><span style="color:#ffffff">=</span><span style="color:#ffffff"> stream</span><span style="color:#ffffff">;</span><span style="color:#ffffff">}</span> <span style="color:#e28964">catch</span> <span style="color:#ffffff">(</span><span style="color:#ffffff">err</span><span style="color:#ffffff">)</span> <span style="color:#ffffff">{</span><span style="color:#ffffff">console</span><span style="color:#ffffff">.</span><span style="color:#ffffff">error</span><span style="color:#ffffff">(</span><span style="color:#ffffff">err</span><span style="color:#ffffff">);</span><span style="color:#ffffff">}</span> <span style="color:#ffffff">}</span><span style="color:#ffffff">signaling</span><span style="color:#ffffff">.</span><span style="color:#ffffff">onmessage </span><span style="color:#ffffff">=</span><span style="color:#ffffff"> async </span><span style="color:#ffffff">({</span><span style="color:#ffffff">desc</span><span style="color:#ffffff">,</span><span style="color:#ffffff"> candidate</span><span style="color:#ffffff">})</span> <span style="color:#ffffff">=></span> <span style="color:#ffffff">{</span><span style="color:#e28964">try</span> <span style="color:#ffffff">{</span><span style="color:#e28964">if</span> <span style="color:#ffffff">(</span><span style="color:#ffffff">desc</span><span style="color:#ffffff">)</span> <span style="color:#ffffff">{</span><span style="color:#aeaeae"><em>// If you get an offer, you need to reply with an answer.</em></span><span style="color:#e28964">if</span> <span style="color:#ffffff">(</span><span style="color:#ffffff">desc</span><span style="color:#ffffff">.</span><span style="color:#ffffff">type </span><span style="color:#ffffff">===</span> <span style="color:#65b042">'offer'</span><span style="color:#ffffff">)</span> <span style="color:#ffffff">{</span><span style="color:#ffffff">await pc</span><span style="color:#ffffff">.</span><span style="color:#ffffff">setRemoteDescription</span><span style="color:#ffffff">(</span><span style="color:#ffffff">desc</span><span style="color:#ffffff">);</span><span style="color:#e28964">const</span><span style="color:#ffffff"> stream </span><span style="color:#ffffff">=</span><span style="color:#ffffff">await navigator</span><span style="color:#ffffff">.</span><span style="color:#ffffff">mediaDevices</span><span style="color:#ffffff">.</span><span style="color:#ffffff">getUserMedia</span><span style="color:#ffffff">(</span><span style="color:#ffffff">constraints</span><span style="color:#ffffff">);</span><span style="color:#ffffff">stream</span><span style="color:#ffffff">.</span><span style="color:#ffffff">getTracks</span><span style="color:#ffffff">().</span><span style="color:#ffffff">forEach</span><span style="color:#ffffff">((</span><span style="color:#ffffff">track</span><span style="color:#ffffff">)</span> <span style="color:#ffffff">=></span><span style="color:#ffffff">pc</span><span style="color:#ffffff">.</span><span style="color:#ffffff">addTrack</span><span style="color:#ffffff">(</span><span style="color:#ffffff">track</span><span style="color:#ffffff">,</span><span style="color:#ffffff"> stream</span><span style="color:#ffffff">));</span><span style="color:#ffffff">await pc</span><span style="color:#ffffff">.</span><span style="color:#ffffff">setLocalDescription</span><span style="color:#ffffff">(</span><span style="color:#ffffff">await pc</span><span style="color:#ffffff">.</span><span style="color:#ffffff">createAnswer</span><span style="color:#ffffff">());</span><span style="color:#ffffff">signaling</span><span style="color:#ffffff">.</span><span style="color:#ffffff">send</span><span style="color:#ffffff">({</span><span style="color:#ffffff">desc</span><span style="color:#ffffff">:</span><span style="color:#ffffff"> pc</span><span style="color:#ffffff">.</span><span style="color:#ffffff">localDescription</span><span style="color:#ffffff">});</span><span style="color:#ffffff">}</span> <span style="color:#e28964">else</span> <span style="color:#e28964">if</span> <span style="color:#ffffff">(</span><span style="color:#ffffff">desc</span><span style="color:#ffffff">.</span><span style="color:#ffffff">type </span><span style="color:#ffffff">===</span> <span style="color:#65b042">'answer'</span><span style="color:#ffffff">)</span> <span style="color:#ffffff">{</span><span style="color:#ffffff">await pc</span><span style="color:#ffffff">.</span><span style="color:#ffffff">setRemoteDescription</span><span style="color:#ffffff">(</span><span style="color:#ffffff">desc</span><span style="color:#ffffff">);</span><span style="color:#ffffff">}</span> <span style="color:#e28964">else</span> <span style="color:#ffffff">{</span><span style="color:#ffffff">console</span><span style="color:#ffffff">.</span><span style="color:#ffffff">log</span><span style="color:#ffffff">(</span><span style="color:#65b042">'Unsupported SDP type.'</span><span style="color:#ffffff">);</span><span style="color:#ffffff">}</span><span style="color:#ffffff">}</span> <span style="color:#e28964">else</span> <span style="color:#e28964">if</span> <span style="color:#ffffff">(</span><span style="color:#ffffff">candidate</span><span style="color:#ffffff">)</span> <span style="color:#ffffff">{</span><span style="color:#ffffff">await pc</span><span style="color:#ffffff">.</span><span style="color:#ffffff">addIceCandidate</span><span style="color:#ffffff">(</span><span style="color:#ffffff">candidate</span><span style="color:#ffffff">);</span><span style="color:#ffffff">}</span><span style="color:#ffffff">}</span> <span style="color:#e28964">catch</span> <span style="color:#ffffff">(</span><span style="color:#ffffff">err</span><span style="color:#ffffff">)</span> <span style="color:#ffffff">{</span><span style="color:#ffffff">console</span><span style="color:#ffffff">.</span><span style="color:#ffffff">error</span><span style="color:#ffffff">(</span><span style="color:#ffffff">err</span><span style="color:#ffffff">);</span><span style="color:#ffffff">}</span> <span style="color:#ffffff">};</span></span></span>

    首先,Alice 和 Bob 交換網(wǎng)絡信息。(表達式查找候選項是指使用?ICE 框架查找網(wǎng)絡接口和端口的過程。

  • Alice 使用處理程序創(chuàng)建一個對象,該處理程序在網(wǎng)絡候選程序可用時運行。RTCPeerConnectiononicecandidate
  • Alice 通過 Bob 使用的任何信令通道(如 WebSocket 或其他機制)將序列化的候選數(shù)據(jù)發(fā)送給 Bob。
  • 當 Bob 收到來自 Alice 的應聘者消息時,他會打電話將應聘者添加到遠程對等描述中。addIceCandidate
  • WebRTC 客戶端(也稱為對等體,在本例中稱為 Alice 和 Bob)還需要確定和交換本地和遠程音頻和視頻媒體信息,例如解析和編解碼器功能。通過會話描述協(xié)議 (SDP) 交換產(chǎn)品/服務和答案來發(fā)出信號以交換媒體配置信息:

  • Alice 運行該方法。此返回的傳輸路徑為 —Alice 的本地會話描述。RTCPeerConnectioncreateOffer()RTCSessionDescription
  • 在回調中,Alice 使用設置本地描述,然后通過其信令通道將此會話描述發(fā)送給 Bob。請注意,在被調用之前不會開始收集候選項。這在JSEP IETF草案中得到了編纂。setLocalDescription()RTCPeerConnectionsetLocalDescription()
  • Bob 使用 將 Alice 發(fā)送給他的描述設置為遠程描述。setRemoteDescription()
  • Bob 運行該方法,將他從 Alice 那里獲得的遠程描述傳遞給它,以便可以生成與她的會話兼容的本地會話。回調傳遞一個 .Bob 將其設置為本地描述,并將其發(fā)送給 Alice。RTCPeerConnectioncreateAnswer()createAnswer()RTCSessionDescription
  • 當 Alice 獲取 Bob 的會話描述時,她將其設置為帶有 的遠程描述。setRemoteDescription
  • 乒!
  • 確保允許 在不再需要時通過調用來回收 垃圾回收。否則,線程和連接將保持活動狀態(tài)。在WebRTC中可能會泄漏大量資源!RTCPeerConnectionclose()

    RTCSessionDescription對象是符合會話描述協(xié)議?SDP 的 Blob。序列化后,SDP 對象如下所示:

    <span style="color:white"><span style="background-color:#444444"><span style="color:#ffffff">v</span><span style="color:#ffffff">=</span><span style="color:#3387cc">0</span><span style="color:#ffffff"> o</span><span style="color:#ffffff">=-</span> <span style="color:#3387cc">3883943731</span> <span style="color:#3387cc">1</span><span style="color:#ffffff"> IN IP4 </span><span style="color:#3387cc">127.0</span><span style="color:#ffffff">.</span><span style="color:#3387cc">0.1</span><span style="color:#ffffff"> s</span><span style="color:#ffffff">=</span><span style="color:#ffffff"> t</span><span style="color:#ffffff">=</span><span style="color:#3387cc">0</span> <span style="color:#3387cc">0</span><span style="color:#ffffff"> a</span><span style="color:#ffffff">=</span><span style="color:#e28964">group</span><span style="color:#ffffff">:</span><span style="color:#ffffff">BUNDLE audio video m</span><span style="color:#ffffff">=</span><span style="color:#ffffff">audio </span><span style="color:#3387cc">1</span><span style="color:#ffffff"> RTP</span><span style="color:#ffffff">/</span><span style="color:#ffffff">SAVPF </span><span style="color:#3387cc">103</span> <span style="color:#3387cc">104</span> <span style="color:#3387cc">0</span> <span style="color:#3387cc">8</span> <span style="color:#3387cc">106</span> <span style="color:#3387cc">105</span> <span style="color:#3387cc">13</span> <span style="color:#3387cc">126</span><span style="color:#aeaeae"><em>// ...</em></span><span style="color:#ffffff">a</span><span style="color:#ffffff">=</span><span style="color:#ffffff">ssrc</span><span style="color:#ffffff">:</span><span style="color:#3387cc">2223794119</span><span style="color:#ffffff"> label</span><span style="color:#ffffff">:</span><span style="color:#ffffff">H4fjnMzxy3dPIgQ7HxuCTLb4wLLLeRHnFxh810</span></span></span>

    網(wǎng)絡和媒體信息的獲取和交換可以同時完成,但是在對等體之間的音頻和視頻流開始之前,這兩個過程必須已經(jīng)完成。

    前面描述的要約/答案體系結構稱為?JavaScript 會話建立協(xié)議或 JSEP。(在愛立信的第一個WebRTC實現(xiàn)的演示視頻中,有一個很棒的動畫解釋了信令和流式傳輸?shù)倪^程。

    JSEP 架構

    一旦信令過程成功完成,數(shù)據(jù)就可以在呼叫者和被叫方之間直接對等流式傳輸,或者,如果失敗,則通過中間中繼服務器(稍后將詳細介紹)。流式傳輸是 的工作。RTCPeerConnection

    RTCPeerConnection

    RTCPeerConnection是 WebRTC 組件,用于處理對等體之間流數(shù)據(jù)的穩(wěn)定和高效通信。

    下面是一個 WebRTC 體系結構圖,顯示了 的作用。您會注意到,綠色部分很復雜!RTCPeerConnection

    正在上傳…重新上傳取消

    WebRTC架構(來自?webrtc.org)

    從JavaScript的角度來看,從這張圖中要了解的主要內容是,它保護Web開發(fā)人員免受潛伏在背后的無數(shù)復雜性的影響。WebRTC使用的編解碼器和協(xié)議做了大量的工作,使實時通信成為可能,即使在不可靠的網(wǎng)絡上也是如此:RTCPeerConnection

    • 丟包隱蔽
    • 回聲消除
    • 帶寬適應性
    • 動態(tài)抖動緩沖
    • 自動增益控制
    • 降噪和抑制
    • 圖像清理

    前面的 W3C 代碼從信令角度展示了 WebRTC 的簡化示例。以下是兩個工作 WebRTC 應用程序的演練。第一個是要演示的簡單示例,第二個是完全可操作的視頻聊天客戶端。RTCPeerConnection

    沒有服務器的 RTCPeerConnection

    以下代碼取自?WebRTC 示例對等連接,該連接在一個網(wǎng)頁上具有本地和遠程(以及本地和遠程視頻)。這并不構成任何非常有用的東西 - 調用方和被調用方在同一頁面上 - 但它確實使API的工作原理更加清晰,因為頁面上的對象可以直接交換數(shù)據(jù)和消息,而無需使用中間信令機制。RTCPeerConnectionRTCPeerConnectionRTCPeerConnection

    在此示例中,表示本地對等方(調用方)和遠程對等方(被調用方)。pc1pc2

    訪客

  • 創(chuàng)建一個新流并從中添加流:RTCPeerConnectiongetUserMedia()

    <span style="color:white"><span style="background-color:#444444"><span style="color:#aeaeae"><em>// Servers is an optional configuration file. (See TURN and STUN discussion later.)</em></span><span style="color:#ffffff"> pc1 </span><span style="color:#ffffff">=</span> <span style="color:#e28964">new</span> <span style="color:#89bdff">RTCPeerConnection</span><span style="color:#ffffff">(</span><span style="color:#ffffff">servers</span><span style="color:#ffffff">);</span> <span style="color:#aeaeae"><em>// ...</em></span><span style="color:#ffffff"> localStream</span><span style="color:#ffffff">.</span><span style="color:#ffffff">getTracks</span><span style="color:#ffffff">().</span><span style="color:#ffffff">forEach</span><span style="color:#ffffff">((</span><span style="color:#ffffff">track</span><span style="color:#ffffff">)</span> <span style="color:#ffffff">=></span> <span style="color:#ffffff">{</span><span style="color:#ffffff">pc1</span><span style="color:#ffffff">.</span><span style="color:#ffffff">addTrack</span><span style="color:#ffffff">(</span><span style="color:#ffffff">track</span><span style="color:#ffffff">,</span><span style="color:#ffffff"> localStream</span><span style="color:#ffffff">);</span> <span style="color:#ffffff">});</span></span></span>
  • 創(chuàng)建產(chǎn)品/服務并將其設置為 的本地描述和 遠程描述。這可以直接在代碼中完成,而無需使用信令,因為調用方和被調用方都在同一頁面上:pc1pc2

    <span style="color:white"><span style="background-color:#444444"><span style="color:#ffffff">pc1</span><span style="color:#ffffff">.</span><span style="color:#ffffff">setLocalDescription</span><span style="color:#ffffff">(</span><span style="color:#ffffff">desc</span><span style="color:#ffffff">).</span><span style="color:#e28964">then</span><span style="color:#ffffff">(()</span> <span style="color:#ffffff">=></span> <span style="color:#ffffff">{</span><span style="color:#ffffff">onSetLocalSuccess</span><span style="color:#ffffff">(</span><span style="color:#ffffff">pc1</span><span style="color:#ffffff">);</span><span style="color:#ffffff">},</span><span style="color:#ffffff">onSetSessionDescriptionError</span><span style="color:#ffffff">);</span><span style="color:#ffffff">trace</span><span style="color:#ffffff">(</span><span style="color:#65b042">'pc2 setRemoteDescription start'</span><span style="color:#ffffff">);</span><span style="color:#ffffff">pc2</span><span style="color:#ffffff">.</span><span style="color:#ffffff">setRemoteDescription</span><span style="color:#ffffff">(</span><span style="color:#ffffff">desc</span><span style="color:#ffffff">).</span><span style="color:#e28964">then</span><span style="color:#ffffff">(()</span> <span style="color:#ffffff">=></span> <span style="color:#ffffff">{</span><span style="color:#ffffff">onSetRemoteSuccess</span><span style="color:#ffffff">(</span><span style="color:#ffffff">pc2</span><span style="color:#ffffff">);</span><span style="color:#ffffff">},</span><span style="color:#ffffff">onSetSessionDescriptionError</span><span style="color:#ffffff">);</span></span></span>
  • 被叫方

    創(chuàng)建并在添加來自 的流時,將其顯示在視頻元素中:pc2pc1

    <span style="color:white"><span style="background-color:#444444"><span style="color:#ffffff">pc2 </span><span style="color:#ffffff">=</span> <span style="color:#e28964">new</span> <span style="color:#89bdff">RTCPeerConnection</span><span style="color:#ffffff">(</span><span style="color:#ffffff">servers</span><span style="color:#ffffff">);</span><span style="color:#ffffff"> pc2</span><span style="color:#ffffff">.</span><span style="color:#ffffff">ontrack </span><span style="color:#ffffff">=</span><span style="color:#ffffff"> gotRemoteStream</span><span style="color:#ffffff">;</span> <span style="color:#aeaeae"><em>//...</em></span> <span style="color:#e28964">function</span><span style="color:#ffffff"> gotRemoteStream</span><span style="color:#ffffff">(</span><span style="color:#ffffff">e</span><span style="color:#ffffff">){</span><span style="color:#ffffff">vid2</span><span style="color:#ffffff">.</span><span style="color:#ffffff">srcObject </span><span style="color:#ffffff">=</span><span style="color:#ffffff"> e</span><span style="color:#ffffff">.</span><span style="color:#ffffff">stream</span><span style="color:#ffffff">;</span> <span style="color:#ffffff">}</span></span></span>

    RTCPeerConnectionAPI 加服務器

    在現(xiàn)實世界中,WebRTC需要服務器,無論多么簡單,因此可能會發(fā)生以下情況:

    • 用戶發(fā)現(xiàn)彼此并交換真實世界的詳細信息,例如名稱。
    • WebRTC客戶端應用程序(對等體)交換網(wǎng)絡信息。
    • 對等方交換有關媒體的數(shù)據(jù),例如視頻格式和分辨率。
    • WebRTC 客戶端應用程序遍歷?NAT 網(wǎng)關和防火墻。

    換句話說,WebRTC需要四種類型的服務器端功能:

    • 用戶發(fā)現(xiàn)和通信
    • 信號
    • NAT/防火墻遍歷
    • 對等通信失敗時的中繼服務器

    NAT 遍歷、對等網(wǎng)絡以及構建用于用戶發(fā)現(xiàn)和信令的服務器應用的要求超出了本文的討論范圍??梢哉f,ICE框架使用STUN協(xié)議及其擴展名TURN來應對NAT遍歷和其他網(wǎng)絡變幻莫測。RTCPeerConnection

    ICE 是用于連接對等方(如兩個視頻聊天客戶端)的框架。最初,ICE 嘗試通過 UDP 以盡可能低的延遲直接連接對等方。在此過程中,STUN 服務器只有一個任務:使 NAT 后面的對等方能夠查找其公共地址和端口。(有關 STUN 和 TURN 的詳細信息,請參閱構建 WebRTC 應用所需的后端服務。

    查找連接候選項

    如果 UDP 失敗,ICE 將嘗試 TCP。如果直接連接失敗(特別是由于企業(yè) NAT 遍歷和防火墻),ICE 將使用中間(中繼)TURN 服務器。換句話說,ICE 首先將 STUN 與 UDP 結合使用來直接連接對等體,如果失敗,則回退到 TURN 中繼服務器。表達式查找候選項是指查找網(wǎng)絡接口和端口的過程。

    WebRTC數(shù)據(jù)路徑

    WebRTC工程師Justin Uberti在2013年Google I / O WebRTC演示中提供了有關ICE,STUN和TURN的更多信息。(演示幻燈片給出了 TURN 和 STUN 服務器實現(xiàn)的示例。

    一個簡單的視頻聊天客戶端

    嘗試WebRTC的好地方,包括使用STUN服務器的信令和NAT /防火墻穿越,是?appr.tc?的視頻聊天演示。此應用使用適配器.js、填充程序將應用與規(guī)范更改和前綴差異隔離開來。

    代碼在其日志記錄中故意冗長。檢查控制臺以了解事件的順序。下面是代碼的詳細演練。

    如果你覺得這有點令人困惑,你可能更喜歡 WebRTC codelab。本分步指南介紹了如何構建完整的視頻聊天應用程序,包括在 Node 服務器上運行的簡單信令 服務器。

    網(wǎng)絡拓撲

    目前實現(xiàn)的WebRTC僅支持一對一通信,但可用于更復雜的網(wǎng)絡場景,例如多個對等體直接或通過多點控制單元(MCU)相互通信,多點控制單元(MCU)是可以處理大量參與者并進行選擇性流轉發(fā)的服務器,以及混合或錄制音頻和視頻。

    多點控制單元拓撲示例

    許多現(xiàn)有的WebRTC應用程序僅演示W(wǎng)eb瀏覽器之間的通信,但網(wǎng)關服務器可以使在瀏覽器上運行的WebRTC應用程序與設備(如電話(也稱為PSTN))和VOIP系統(tǒng)進行交互。2012年5月,Doubango Telecom開源了使用WebRTC和WebSocket構建的sipml5 SIP客戶端,該客戶端(以及其他潛在用途)支持在iOS和Android上運行的瀏覽器和應用程序之間的視頻通話。在Google I / O上,Tethr和Tropo展示了一個使用OpenBTS單元在公文包中進行災難通信的框架,以通過WebRTC實現(xiàn)功能手機和計算機之間的通信。電話通信沒有運營商!

    Tethr/Tropo:公文包中的災難通信

    RTCDataChannel應用程序接口

    除了音頻和視頻,WebRTC還支持其他類型的數(shù)據(jù)的實時通信。

    該 API 支持以低延遲和高吞吐量對等方式交換任意數(shù)據(jù)。有關單頁演示以及如何構建簡單的文件傳輸應用程序,請分別參閱?WebRTC 示例和?WebRTC 代碼實驗室。RTCDataChannel

    該 API 有許多潛在的用例,包括:

    • 賭博
    • 遠程桌面應用
    • 實時文本聊天
    • 文件傳輸
    • 去中心化網(wǎng)絡

    該 API 具有多項功能,可充分利用并實現(xiàn)強大而靈活的對等通信:RTCPeerConnection

    • 利用會話設置RTCPeerConnection
    • 多個同時通道,優(yōu)先級
    • 可靠和不可靠的交付語義
    • 內置安全性 (DTLS) 和擁塞控制
    • 能夠與音頻或視頻一起使用或不使用音頻或視頻

    語法有意類似于 WebSocket,具有方法和事件:send()message

    <span style="color:white"><span style="background-color:#444444"><span style="color:#e28964">const</span><span style="color:#ffffff"> localConnection </span><span style="color:#ffffff">=</span> <span style="color:#e28964">new</span> <span style="color:#89bdff">RTCPeerConnection</span><span style="color:#ffffff">(</span><span style="color:#ffffff">servers</span><span style="color:#ffffff">);</span> <span style="color:#e28964">const</span><span style="color:#ffffff"> remoteConnection </span><span style="color:#ffffff">=</span> <span style="color:#e28964">new</span> <span style="color:#89bdff">RTCPeerConnection</span><span style="color:#ffffff">(</span><span style="color:#ffffff">servers</span><span style="color:#ffffff">);</span> <span style="color:#e28964">const</span><span style="color:#ffffff"> sendChannel </span><span style="color:#ffffff">=</span><span style="color:#ffffff">localConnection</span><span style="color:#ffffff">.</span><span style="color:#ffffff">createDataChannel</span><span style="color:#ffffff">(</span><span style="color:#65b042">'sendDataChannel'</span><span style="color:#ffffff">);</span><span style="color:#aeaeae"><em>// ...</em></span><span style="color:#ffffff">remoteConnection</span><span style="color:#ffffff">.</span><span style="color:#ffffff">ondatachannel </span><span style="color:#ffffff">=</span> <span style="color:#ffffff">(</span><span style="color:#e28964">event</span><span style="color:#ffffff">)</span> <span style="color:#ffffff">=></span> <span style="color:#ffffff">{</span><span style="color:#ffffff">receiveChannel </span><span style="color:#ffffff">=</span> <span style="color:#e28964">event</span><span style="color:#ffffff">.</span><span style="color:#ffffff">channel</span><span style="color:#ffffff">;</span><span style="color:#ffffff">receiveChannel</span><span style="color:#ffffff">.</span><span style="color:#ffffff">onmessage </span><span style="color:#ffffff">=</span><span style="color:#ffffff"> onReceiveMessage</span><span style="color:#ffffff">;</span><span style="color:#ffffff">receiveChannel</span><span style="color:#ffffff">.</span><span style="color:#ffffff">onopen </span><span style="color:#ffffff">=</span><span style="color:#ffffff"> onReceiveChannelStateChange</span><span style="color:#ffffff">;</span><span style="color:#ffffff">receiveChannel</span><span style="color:#ffffff">.</span><span style="color:#ffffff">onclose </span><span style="color:#ffffff">=</span><span style="color:#ffffff"> onReceiveChannelStateChange</span><span style="color:#ffffff">;</span> <span style="color:#ffffff">};</span><span style="color:#e28964">function</span><span style="color:#ffffff"> onReceiveMessage</span><span style="color:#ffffff">(</span><span style="color:#e28964">event</span><span style="color:#ffffff">)</span> <span style="color:#ffffff">{</span><span style="color:#ffffff">document</span><span style="color:#ffffff">.</span><span style="color:#ffffff">querySelector</span><span style="color:#ffffff">(</span><span style="color:#65b042">"textarea#send"</span><span style="color:#ffffff">).</span><span style="color:#ffffff">value </span><span style="color:#ffffff">=</span> <span style="color:#e28964">event</span><span style="color:#ffffff">.</span><span style="color:#ffffff">data</span><span style="color:#ffffff">;</span> <span style="color:#ffffff">}</span><span style="color:#ffffff">document</span><span style="color:#ffffff">.</span><span style="color:#ffffff">querySelector</span><span style="color:#ffffff">(</span><span style="color:#65b042">"button#send"</span><span style="color:#ffffff">).</span><span style="color:#ffffff">onclick </span><span style="color:#ffffff">=</span> <span style="color:#ffffff">()</span> <span style="color:#ffffff">=></span> <span style="color:#ffffff">{</span><span style="color:#e28964">var</span><span style="color:#ffffff"> data </span><span style="color:#ffffff">=</span><span style="color:#ffffff"> document</span><span style="color:#ffffff">.</span><span style="color:#ffffff">querySelector</span><span style="color:#ffffff">(</span><span style="color:#65b042">"textarea#send"</span><span style="color:#ffffff">).</span><span style="color:#ffffff">value</span><span style="color:#ffffff">;</span><span style="color:#ffffff">sendChannel</span><span style="color:#ffffff">.</span><span style="color:#ffffff">send</span><span style="color:#ffffff">(</span><span style="color:#ffffff">data</span><span style="color:#ffffff">);</span> <span style="color:#ffffff">};</span></span></span>

    通信直接發(fā)生在瀏覽器之間,因此即使當打孔以應對防火墻和 NAT 失敗時需要中繼 (TURN) 服務器,也可以比 WebSocket 快得多。RTCDataChannel

    RTCDataChannel可在 Chrome、Safari、Firefox、Opera 和 Samsung Internet 中使用。Cube Slam?游戲使用 API 來傳達游戲狀態(tài)。玩朋友或玩熊!創(chuàng)新平臺Sharefest通過peerCDN實現(xiàn)了文件共享,并提供了WebRTC如何實現(xiàn)點對點內容分發(fā)的一瞥。RTCDataChannel

    有關 的更多信息,請查看 IETF?的協(xié)議規(guī)范草案。RTCDataChannel

    安全

    實時通信應用程序或插件可能會通過多種方式危及安全性。例如:

    • 未加密的媒體或數(shù)據(jù)可能會在瀏覽器之間或瀏覽器與服務器之間被截獲。
    • 應用可能會在用戶不知情的情況下錄制和分發(fā)視頻或音頻。
    • 惡意軟件或病毒可能與明顯無害的插件或應用程序一起安裝。

    WebRTC有幾個功能可以避免這些問題:

    • WebRTC實現(xiàn)使用安全協(xié)議,如DTLS和SRTP。
    • 加密對于所有WebRTC組件都是強制性的,包括信令機制。
    • WebRTC不是一個插件。它的組件在瀏覽器沙箱中運行,而不是在單獨的進程中運行。組件不需要單獨安裝,并且每當瀏覽器更新時都會更新。
    • 必須顯式授予攝像頭和麥克風訪問權限,并且當攝像頭或麥克風運行時,用戶界面會清楚地顯示這一點。

    關于流媒體安全性的完整討論超出了本文的范圍。有關更多信息,請參閱 IETF?提議的 WebRTC 安全架構。

    結語

    WebRTC的API和標準可以使內容創(chuàng)建和通信工具民主化和分散化,包括電話,游戲,視頻制作,音樂制作和新聞采集。

    沒有比這更具顛覆性的技術了。

    正如博主菲爾·埃德霍爾姆(Phil Edholm)所說,"WebRTC和HTML5可能實現(xiàn)與原始瀏覽器對信息相同的實時通信轉換。

    開發(fā)人員工具

    • 正在進行的會話的WebRTC統(tǒng)計數(shù)據(jù)可以在以下位置找到:

      chrome://webrtc-internals 屏幕截圖

      • 在 Chrome 瀏覽器中 chrome://webrtc-internals
      • 歌劇中的 opera://webrtc-internals
      • 關于:火狐中的webrtc
    • 跨瀏覽器互操作說明
    • adapter.js是由Google在WebRTC社區(qū)的幫助下維護的WebRTC的JavaScript填充程序,它抽象了供應商前綴,瀏覽器差異和規(guī)范更改。
    • 要了解有關 WebRTC 信令過程的更多信息,請查看?appr.tc?日志輸出到控制臺。
    • 如果太多了,你可能更喜歡使用WebRTC框架,甚至是完整的WebRTC服務。
    • 錯誤報告和功能請求始終受到贊賞:
      • WebRTC錯誤
      • Chrome 錯誤
      • 歌劇錯誤
      • 火狐錯誤
      • WebRTC演示錯誤
      • 適配器.js錯誤

    了解更多信息

    • Justin Uberti 在 Google I/O 2012 上的 WebRTC 會議
    • 艾倫·B·約翰斯頓(Alan B. Johnston)和丹尼爾·C·伯內特(Daniel C. Burnett)在 webrtcbook.com 上以印刷版和電子書格式出版了一本W(wǎng)ebRTC書籍,現(xiàn)已推出第三版。
    • webrtc.org?是WebRTC所有內容的所在地,包括演示,文檔和討論。
    • discuss-webrtc是一個用于WebRTC技術討論的Google Group。
    • @webrtc
    • Google Developers?Talk 文檔提供了有關 NAT 遍歷、STUN、中繼服務器和候選者收集的更多信息。
    • WebRTC on GitHub
    • Stack Overflow是尋找答案并提出有關WebRTC問題的好地方。

    標準和協(xié)議

    • WebRTC W3C 編輯草稿
    • W3C 編輯器草稿:媒體捕獲和流(也稱為getUserMedia)
    • IETF工作組章程
    • IETF WebRTC 數(shù)據(jù)通道協(xié)議草案
    • IETF JSEP Draft
    • IETF為ICE提出的標準
    • IETF RTCWEB工作組互聯(lián)網(wǎng)草案:Web實時通信用例和要求

    WebRTC 支持摘要

    MediaStream和 APIgetUserMedia

    • Chrome 桌面版 18.0.1008 及更高版本;適用于安卓 29 及更高版本的 Chrome 瀏覽器
    • 歌劇18及以上;適用于安卓 20 及更高版本的 Opera
    • Opera 12,Opera Mobile 12(基于Presto引擎)
    • 火狐 17 及更高版本
    • 微軟邊緣 16 及更高版本
    • iOS 上的 Safari 11.2 及更高版本,以及 MacOS 上的 11.1 及更高版本
    • 安卓版上的 UC 11.8 及更高版本
    • 三星互聯(lián)網(wǎng)4及更高版本

    RTCPeerConnection應用程序接口

    • Chrome 桌面 20 及更高版本;適用于 Android 29 及更高版本的 Chrome 瀏覽器(無標志)
    • Opera 18 及更高版本(默認啟用);適用于 Android 20 及更高版本的 Opera(默認情況下處于啟用狀態(tài))
    • Firefox 22 及更高版本(默認啟用)
    • 微軟邊緣 16 及更高版本
    • iOS 上的 Safari 11.2 及更高版本,以及 MacOS 上的 11.1 及更高版本
    • 三星互聯(lián)網(wǎng)4及更高版本

    RTCDataChannel應用程序接口

    • Chrome 25中的實驗版本,但在Chrome 26及更高版本中更穩(wěn)定(并且具有Firefox互操作性);適用于安卓 29 及更高版本的 Chrome 瀏覽器
    • Opera 18及更高版本中的穩(wěn)定版本(以及Firefox互操作性);適用于安卓 20 及更高版本的 Opera
    • Firefox 22 及更高版本(默認啟用)

    有關 API 的跨平臺支持(例如 和)的更多詳細信息,請參閱?caniuse.com?和?Chrome 平臺狀態(tài)。getUserMediaRTCPeerConnection

    本機 API 也可在有關 webrtc.org 的文檔中找到。RTCPeerConnection

    總結

    以上是生活随笔為你收集整理的开始使用WebRTC的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。

    午夜久久影视 | 欧美一级免费在线 | 久久国产免 | 成人午夜在线观看 | 日本视频精品 | 午夜av在线电影 | 中文字幕资源网 | 91av视频导航 | 国产午夜精品免费一区二区三区视频 | 99在线视频精品 | 久草在线资源观看 | 中文伊人 | 久久久国产精品人人片99精片欧美一 | 国产高清成人在线 | 久久精品视频日本 | 亚洲 欧美变态 另类 综合 | 日韩欧美区 | 免费情趣视频 | 99精品久久久久 | 国产精品18久久久久vr手机版特色 | 韩国av一区 | 永久免费在线 | 天天在线免费视频 | 日韩中文在线视频 | 国产精品久久久久影视 | 亚洲涩涩涩 | 日韩羞羞 | 99麻豆久久久国产精品免费 | 日韩精品无码一区二区三区 | 中文字幕你懂的 | 国产在线国偷精品产拍 | 久久精品91久久久久久再现 | 久久免费视频8 | 久久婷婷影视 | av高清影院 | 日韩一区二区免费播放 | 亚洲综合小说电影qvod | 成人黄色一级视频 | 成人四虎| 国产精品久久久999 国产91九色视频 | 久久久久久免费毛片精品 | 欧美日韩免费一区二区 | 国产999久久久| 午夜私人影院久久久久 | 婷婷色在线观看 | 又黄又爽又刺激 | 中文字幕精品www乱入免费视频 | 国产成人精品电影久久久 | 免费视频成人 | 日韩视频1 | 成年人视频免费在线 | 狠狠网站| 三级av网| 久久午夜国产精品 | 伊人狠狠 | 亚洲狠狠干 | 综合网伊人 | 国产又黄又爽无遮挡 | 亚洲欧美成人综合 | 欧美在线视频一区二区三区 | 久久99久久精品 | 久久国产成人午夜av影院潦草 | 超级碰视频 | 欧美日韩精品免费观看视频 | 欧美一级片在线免费观看 | 欧美一区二区三区在线视频观看 | 亚洲精品久久激情国产片 | 亚州成人av在线 | 久久久精品国产免费观看一区二区 | 国产精品成人a免费观看 | 国产成人精品久久亚洲高清不卡 | 国产精品一区在线观看 | 日韩精品一区二区在线观看 | 91免费国产在线观看 | 日本二区三区在线 | 天天夜夜亚洲 | 国产精品第三页 | 久久99精品国产麻豆宅宅 | 91av视频免费观看 | 亚洲黄色免费观看 | 久久精品麻豆 | 日韩大片在线播放 | 色综合激情网 | 中文字幕国语官网在线视频 | 成 人 黄 色 片 在线播放 | 亚洲欧美经典 | 特级黄色片免费看 | 久久久久婷 | 99久久精品国产一区 | 日本在线观看一区二区 | 婷婷色网视频在线播放 | 在线观看视频一区二区 | 亚洲日本在线一区 | 国产精品自产拍在线观看蜜 | 婷婷丁香在线 | 国产一级黄大片 | 日本最新中文字幕 | 亚洲一区二区三区在线看 | 久久人人爽av | 日韩精品一区二区不卡 | 久久精品成人热国产成 | av综合站 | 91免费网站在线观看 | 黄色电影网站在线观看 | 国产第一页在线观看 | 黄色大片入口 | 中文字幕第| 国产精品黑丝在线观看 | 国产精品精品久久久久久 | 狠狠操欧美 | 精品91视频 | 亚洲综合激情 | 久久免费99精品久久久久久 | 91看片淫黄大片一级在线观看 | 国产永久免费观看 | 欧美黄色软件 | 狠狠躁夜夜a产精品视频 | 国产精品久久久999 国产91九色视频 | 国产男女无遮挡猛进猛出在线观看 | 欧美日韩久久不卡 | 伊人婷婷在线 | 456免费视频 | 国产精品一区二区吃奶在线观看 | 精品免费久久 | www.超碰| 国产精品乱码久久久 | 97人人澡人人添人人爽超碰 | 欧美午夜a | 国产1区2区3区精品美女 | 中国精品少妇 | 91一区啪爱嗯打偷拍欧美 | 伊人久久电影网 | 久久久久亚洲国产精品 | 日韩免费在线观看视频 | 国产精品久久久久久爽爽爽 | 在线精品观看国产 | 国产高清av免费在线观看 | 国产不卡免费视频 | 91在线免费公开视频 | 亚洲综合精品视频 | 丁香婷婷激情网 | 欧美肥妇free| 精品国产电影一区 | 日韩在观看线 | 国产一区二区不卡在线 | 18av在线视频 | 久久久久久久久久电影 | 久久66热这里只有精品 | 国产成人精品一二三区 | 超碰在线97国产 | 久久爱导航 | 国产成人在线观看 | 亚洲女欲精品久久久久久久18 | 96国产精品| 天天射天天色天天干 | 一区二区三区免费在线观看视频 | av丝袜在线 | 免费网站在线观看人 | 天天天天色综合 | 狠狠的干狠狠的操 | 超碰精品在线观看 | 日韩精品最新在线观看 | 最新真实国产在线视频 | 成人禁用看黄a在线 | 成人久久免费 | 狠狠干干| 999热线在线观看 | 精品国产一区二 | 天堂网一区二区 | 日韩日韩日韩日韩 | 久久免费美女视频 | 正在播放一区 | 69欧美视频 | 97超碰超碰久久福利超碰 | 欧美一级艳片视频免费观看 | 四虎在线视频 | 五月天综合网站 | 久久国产精品二国产精品中国洋人 | 国产剧情一区 | 亚洲最大在线视频 | 婷婷在线观看视频 | 欧美色图亚洲图片 | 国产成人一区二区三区免费看 | 亚洲 中文字幕av | 激情黄色av | 欧美激情精品久久久久久变态 | bbw av | 99久久久久久 | 国产免费高清 | 国产欧美精品一区二区三区四区 | 亚洲黄色成人网 | 亚洲欧美日韩国产一区二区三区 | 国产不卡在线播放 | 日韩天堂在线观看 | 国产精品a级 | 麻豆精品传媒视频 | 免费看毛片网站 | 欧美在线视频一区二区三区 | 日本免费久久高清视频 | 中文字幕在线免费看 | 中文字幕一区在线观看视频 | 欧美美女视频在线观看 | 国产精品精品久久久久久 | 精品美女国产在线 | www五月天婷婷 | 免费观看www小视频的软件 | 久操综合| 国产一区二区日本 | 香蕉视频国产在线 | 久久99最新地址 | 精品国产乱码久久久久久浪潮 | 国产精品久久久久久久久久久免费看 | 亚州精品天堂中文字幕 | 五月婷av | 五月天婷婷丁香花 | 在线色亚洲 | 99r精品视频在线观看 | 六月丁香久久 | 久久er99热精品一区二区 | 亚洲综合在线播放 | 亚洲精选视频在线 | www九九热 | 欧美一级日韩三级 | 国产精品一区二区三区久久久 | 亚洲综合国产精品 | 欧美午夜视频在线 | 日韩av手机在线看 | 毛片永久新网址首页 | 国偷自产中文字幕亚洲手机在线 | www.久久成人 | 精品一区电影国产 | 欧美精品在线观看免费 | 国产成人福利片 | 国产精品久久久久久久久久三级 | av高清一区 | 四虎在线视频免费观看 | 成人欧美一区二区三区黑人麻豆 | 天天综合网~永久入口 | 欧美激情综合色 | 五月婷婷六月丁香在线观看 | 99热9| 91精品老司机久久一区啪 | 一级电影免费在线观看 | 国产精品视频观看 | 国产乱码精品一区二区三区介绍 | 婷婷国产v亚洲v欧美久久 | 久久国产精品99国产 | 在线观看国产区 | 狠狠色丁香婷婷综合最新地址 | 精品视频免费久久久看 | 日韩av一区二区三区四区 | av在线免费观看不卡 | 久久国产精品一区二区 | 亚洲精品在线免费观看视频 | 久久久污 | 国产在线久久久 | 国产白浆在线观看 | 天天色天天上天天操 | 国产高清免费在线观看 | 久久第四色 | 毛片一区二区 | 五月婷婷丁香在线观看 | 欧美精品久久久久久久 | 国产一区在线视频观看 | 欧美色黄 | 操操日日| 成年人免费在线 | 亚洲最大av网 | av专区在线 | 久久婷婷综合激情 | 国产精品国产三级国产不产一地 | 视频在线观看91 | 在线观看国产永久免费视频 | 美女福利视频 | 四虎成人精品永久免费av | 天天干夜夜操视频 | 欧美日本高清视频 | 一区三区视频在线观看 | 狠狠色丁香婷婷综合欧美 | 免费下载高清毛片 | 免费av网站观看 | 日日干美女 | 国产专区一 | 日韩xxxx视频 | 色婷婷国产精品一区在线观看 | 四虎成人精品永久免费av | 日韩欧美一区二区在线播放 | 国产va饥渴难耐女保洁员在线观看 | 国产婷婷在线观看 | 日韩在线观看免费 | 91精品专区 | 国产中文字幕一区二区 | 久久久资源网 | 免费国产在线精品 | 黄网站大全 | 国产日韩中文字幕在线 | 精品麻豆入口免费 | 人人澡人人爱 | 久精品视频在线观看 | 国产一区二区不卡视频 | 在线视频观看91 | 色综合天天做天天爱 | 日产av在线播放 | 天天草网站 | 手机在线看永久av片免费 | 午夜精选视频 | 久久久91精品国产一区二区精品 | 亚洲精品乱码久久 | 精品一二三区 | 欧美日韩在线观看一区 | 国产视频精品免费 | 99久久激情视频 | 国产精品人人做人人爽人人添 | 日韩免费在线 | 国产精品欧美久久久久三级 | 亚洲色图27p| 免费观看久久 | 中文十次啦 | 国产 视频 高清 免费 | 天天曰天天曰 | 国产精品国产三级国产aⅴ无密码 | 成人片在线播放 | 操综合| 九9热这里真品2 | 激情欧美一区二区三区免费看 | 91看片淫黄大片在线播放 | 免费福利视频导航 | 麻豆久久精品 | 久久久久久久久久久高潮一区二区 | 国产在线综合视频 | 亚洲九九九在线观看 | 久精品一区 | 在线播放亚洲 | 成人av免费 | 狠狠干电影 | 伊香蕉大综综综合久久啪 | 久久久综合 | 久久久成人精品 | av中文字幕第一页 | 久久99热久久99精品 | 久久成人午夜视频 | av天天澡天天爽天天av | 日韩欧美69 | 色天天中文 | 日韩国产欧美在线播放 | 免费网站在线观看成人 | 99久久综合狠狠综合久久 | 五月天色综合 | 精品国产一区二区三区噜噜噜 | 日韩精品一区二区在线视频 | 国产精品久久久精品 | 国产精品麻豆99久久久久久 | 午夜影视一区 | 免费91麻豆精品国产自产在线观看 | 日日干激情五月 | 日韩二区三区在线 | 91色视频 | 免费无遮挡动漫网站 | 一本一本久久aa综合精品 | 国产在线色 | 激情婷婷丁香 | 国产精品99久久99久久久二8 | 中文字幕日本特黄aa毛片 | 欧美一区二区伦理片 | 国产精品亚 | 婷婷六月天综合 | 精品免费在线视频 | wwwav视频| 黄色免费观看网址 | 91人人澡 | 久久精品久久久精品美女 | 最新av免费在线 | 97精品久久人人爽人人爽 | www最近高清中文国语在线观看 | 国产精品 国内视频 | 亚洲人精品午夜 | 精品99免费视频 | av三级在线免费观看 | 久久99精品国产 | www最近高清中文国语在线观看 | 天天操天天曰 | 日韩极品视频在线观看 | 国产精品久久精品 | av在线免费播放 | 国产在线观看网站 | 亚洲精品视频网址 | 久久xx视频| 欧美日韩视频免费 | 欧美激情精品久久久久久变态 | 国产码电影| 久热电影 | 亚洲精品视频在线观看免费视频 | 欧美精品一区在线发布 | 欧美精品三级在线观看 | 九九三级毛片 | 国产精品区一区 | 国产免费嫩草影院 | 国产91精品看黄网站 | 免费午夜在线视频 | 国产精品九九九 | 国产资源免费 | 国产免费亚洲高清 | 99精品久久精品一区二区 | 久草视频精品 | 免费看黄在线看 | 婷婷激情在线 | 成人福利在线 | 免费视频一二三 | 亚洲精品啊啊啊 | 91成人精品一区在线播放 | 国产在线a视频 | 成人动漫一区二区三区 | 在线日本看片免费人成视久网 | 精品久久久久一区二区国产 | 欧美日韩性视频 | 国产一级大片免费看 | 在线观看中文字幕dvd播放 | 麻豆系列在线观看 | 欧美乱大交 | 久久免费视频网站 | 国产精品免费看 | 99精品国产成人一区二区 | 午夜精品久久久久久久久久久 | 亚洲女在线 | a级片久久久 | www.com在线观看 | 亚洲日韩中文字幕在线播放 | 久久av网| 黄色录像av| 国产精品美女久久久 | 婷婷综合在线 | 欧美日韩破处 | 最新国产中文字幕 | 国产一区久久久 | 五月天久久狠狠 | 亚洲精品视频久久 | 成人免费一级 | 国产一线在线 | 狠狠躁夜夜a产精品视频 | 日本最新高清不卡中文字幕 | 亚洲一级片在线看 | 日韩69av| 美女天天操 | 欧美另类v | 欧美精品国产精品 | 日韩av高潮 | 国产精品国产自产拍高清av | 欧美精品一区二区三区一线天视频 | 免费在线91 | 香蕉视频4aa | 天堂视频中文在线 | 国产亚洲va综合人人澡精品 | 成人精品国产免费网站 | 精品欧美一区二区在线观看 | 国产精品v欧美精品 | 91九色国产在线 | 国产永久免费高清在线观看视频 | av一区二区三区在线观看 | 操久 | 四虎成人精品 | 黄色特一级片 | 国产精品mv在线观看 | 久久99精品久久久久久久久久久久 | 亚洲国产高清在线 | 天天操综合 | 日韩电影在线一区二区 | 综合色影院 | 欧美一区二区三区激情视频 | 日本中文一区二区 | 日韩在线免费播放 | 国产手机在线 | 91亚洲精品乱码久久久久久蜜桃 | 成人午夜电影在线 | 久久久久久久亚洲精品 | 国产a级片免费观看 | 日韩久久精品一区二区三区 | 国产精品99久久久久久小说 | 超碰电影在线观看 | 伊人色综合久久天天网 | 日韩理论片中文字幕 | 九九日九九操 | 日本黄色黄网站 | 99久精品视频| 96看片 | 97色噜噜 | 夜夜高潮夜夜爽国产伦精品 | 久久草网 | 在线国产欧美 | 国产在线久久久 | 麻豆91在线看 | 国产精品毛片久久 | 亚洲精品国产精品国产 | 免费看的黄色片 | 日韩免费看片 | 久久精品波多野结衣 | 国产午夜激情视频 | 久久久精品欧美 | 日韩av一区二区三区四区 | 久久婷婷精品视频 | www.色爱 | 久久精品中文字幕一区二区三区 | 亚洲波多野结衣 | 日韩亚洲在线视频 | 欧美精品九九99久久 | 九九视频在线观看视频6 | www.夜夜爱| 一本一本久久a久久精品牛牛影视 | 亚洲色图27p| 亚州精品天堂中文字幕 | 在线播放视频一区 | 91麻豆视频网站 | 亚洲精品国产精品国自 | 日日干美女 | 国产精品ssss在线亚洲 | 亚洲一区二区三区在线看 | 国产精品一区电影 | 精品福利视频在线 | 国产乱对白刺激视频不卡 | 日韩一区视频在线 | 成人久久18免费网站图片 | 国产精品视频区 | 性色av一区二区三区在线观看 | 亚洲日本国产 | 99视频一区二区 | 97超碰免费在线观看 | 麻豆久久久久久久 | 久久99精品久久久久婷婷 | 成人黄色电影视频 | 久久久精品国产一区二区 | 成人三级视频 | 欧美精品一区二区三区一线天视频 | 色 中文字幕 | 欧美不卡视频在线 | 欧美片网站yy | 波多野结衣电影久久 | 成人小视频在线观看免费 | 亚洲爱视频 | 国产成人福利片 | 日韩精品一区二区电影 | 在线观看国产成人av片 | 深夜免费福利 | 在线99热 | 亚洲h在线播放在线观看h | 男女视频国产 | 成人a免费 | 久久久久久久久亚洲精品 | 91精彩在线视频 | 激情婷婷久久 | 97色婷婷 | 97天天综合网 | 一区二区不卡 | 亚洲狠狠干 | a级一a一级在线观看 | 国产精品99久久久久久大便 | 九九免费在线视频 | 国产精品久久久久av | 99久久婷婷国产综合精品 | 午夜影院在线观看18 | 亚洲视屏在线播放 | 激情在线网站 | 久久人人看 | 色五婷婷| 亚洲国产电影在线观看 | 91精品伦理| 欧美 日韩 国产 中文字幕 | 日韩精品一区二区在线观看 | 精品网站999www | 欧美中文字幕久久 | 9999精品| 在线精品亚洲一区二区 | 欧美日韩精品在线 | 久草新在线 | 精品国产a | 激情图片区 | 999视频精品 | 国产精品久久嫩一区二区免费 | 日韩av看片| 日韩精品中字 | av理论电影 | 永久免费精品视频网站 | 免费日韩 精品中文字幕视频在线 | 免费一级毛毛片 | 91精品国产麻豆 | 国产五月婷 | 欧美一级裸体视频 | 国产精品一区二区三区电影 | 人人添人人 | 涩涩网站在线播放 | 在线黄色国产电影 | 黄毛片在线观看 | 91片网| 日韩av不卡在线观看 | 六月丁香在线观看 | 欧美aaa级片 | 色综合色综合色综合 | 手机看片福利 | av天天草 | 91丨九色丨国产在线观看 | 中日韩免费视频 | 超碰免费在线公开 | 日韩电影在线观看一区二区 | 久久国产区 | 999视频精品 | 久久天堂精品视频 | 亚洲理论电影网 | 视频在线观看99 | 丁香影院在线 | avav片| 亚洲精品小视频在线观看 | 天天亚洲综合 | 狠狠干综合 | www最近高清中文国语在线观看 | 国产精品一区二区三区久久 | 亚洲欧美日韩精品久久奇米一区 | 国产精品一区二区电影 | 国产精品九色 | av资源免费看| 日韩在线观看第一页 | 国产麻豆剧果冻传媒视频播放量 | 精精国产xxxx视频在线播放 | 五月综合激情网 | 日韩精品视频在线观看免费 | 九九久 | 久久久香蕉视频 | 丁香av在线 | 日韩二区在线观看 | 成人在线免费av | 天天爽夜夜操 | 在线观看视频国产一区 | 国产精品国产三级在线专区 | www.av中文字幕.com | 国产精选在线观看 | 日韩av免费大片 | www.狠狠色| 丁香五月亚洲综合在线 | 亚洲女人天堂成人av在线 | 天堂av免费| 成人毛片一区 | 麻豆91在线播放 | 国产无区一区二区三麻豆 | 91大神电影 | 色综合久 | 国产免费av一区二区三区 | 欧美色888 | 色小说av | 亚洲va欧美va国产va黑人 | 国产精品日韩在线 | 国产日韩欧美在线观看视频 | 精品国产乱码久久久久久久 | 久久高清av | 少妇激情久久 | 亚洲 欧洲av | 成人网页在线免费观看 | 天天色视频 | 国产美女黄网站免费 | 国产精品久久久久久久久久直播 | 开心丁香婷婷深爱五月 | 综合伊人久久 | 三级av黄色 | 久久人人97超碰精品888 | 国产精品自产拍在线观看网站 | 国产色女 | 97精品久久人人爽人人爽 | 丁香影院在线 | 就要干b| 中文字幕精品一区二区三区电影 | 国产综合福利在线 | 豆豆色资源网xfplay | 日韩在线视频播放 | 九九久久国产精品 | 99久热在线精品视频观看 | 成年人免费看 | 中文字幕一区二区三区在线观看 | 日本中文字幕久久 | 99视频精品免费视频 | 国产原创av片 | av一级片 | 欧美aa在线观看 | 欧美日韩裸体免费视频 | 激情av五月婷婷 | 中文字幕影片免费在线观看 | 久草精品视频在线观看 | 最近能播放的中文字幕 | 欧美成人一二区 | 久久免费视频3 | 成人黄大片视频在线观看 | 91在线视频免费观看 | 久久久国产精品免费 | 亚洲国产免费av | 欧美精品国产综合久久 | 粉嫩一二三区 | 中文一区二区三区在线观看 | 九九九九色 | 中文字幕一区二区三区在线观看 | 高清av中文在线字幕观看1 | 日韩免费在线一区 | 久久综合欧美 | 国产精品视频免费 | 日韩精品一区二区三区免费观看 | 麻豆91在线看 | 一区二区激情 | 久久久久久国产精品亚洲78 | 欧美日性视频 | 97超碰国产精品女人人人爽 | 一级黄色大片在线观看 | 国产精品av在线 | 天天色天天操天天爽 | www.天堂av| 亚洲一区精品二人人爽久久 | 亚洲综合欧美精品电影 | 欧美激情视频一区二区三区 | 久久久久久久久久影视 | 91丨九色丨蝌蚪丰满 | 国产一级在线 | 狠狠操天天干 | 人人舔人人舔 | 91视频麻豆| 亚洲最新av网址 | 国产午夜剧场 | 日韩欧美电影在线 | 免费三级在线 | 国产视频 久久久 | 久久免费毛片视频 | 狠狠色丁香婷婷综合视频 | 黄色视屏免费在线观看 | 99综合电影在线视频 | 精品麻豆入口免费 | 特级西西444www大精品视频免费看 | 婷婷精品国产欧美精品亚洲人人爽 | 在线观看日韩国产 | 成年人免费在线播放 | 亚洲精品h| www.色爱 | 91成人精品观看 | 最近2019年日本中文免费字幕 | 四虎永久免费 | 99re国产| 亚洲片在线资源 | 亚洲视频综合 | 成人免费在线视频观看 | 成人 亚洲 欧美 | 中文字幕亚洲精品日韩 | 久草视频免费在线观看 | 91在线porny国产在线看 | 808电影免费观看三年 | 午夜视频在线观看一区二区三区 | 在线色亚洲 | 国产精品麻豆三级一区视频 | 深夜免费福利视频 | 中国一级片在线观看 | 在线观看免费av片 | 国内精品国产三级国产aⅴ久 | 国产免费xvideos视频入口 | 国产色网站 | www色婷婷com| 欧美精品日韩 | 国产激情久久久 | 91视频在线网址 | 在线观看一级片 | 久久综合色婷婷 | 夜夜高潮夜夜爽国产伦精品 | 精品国产伦一区二区三区观看体验 | 精品理论片 | 日本精品一区二区三区在线观看 | 亚洲91av | 久久网站最新地址 | 五月婷婷在线播放 | 久久久色 | 亚洲精品午夜久久久 | 欧美日韩免费一区 | 69久久久久久久 | 国产中文字幕在线看 | 超碰成人网| 国产伦理久久精品久久久久_ | 操操综合网 | 久草在线官网 | 干狠狠| 天天爱av导航 | 香蕉国产91| 九九欧美| 狠狠色狠狠色合久久伊人 | 一区二区三区久久 | 免费一级特黄毛大片 | 精品色999| 日韩有码在线播放 | 一本—道久久a久久精品蜜桃 | 日本中文在线 | 成人av在线直播 | 超碰在线公开免费 | 国产精品99精品久久免费 | 久久五月精品 | 中文字幕在线观看的网站 | 欧美性久久久久久 | 亚洲国产美女久久久久 | 国产精品a久久久久 | 最新的av网站 | 午夜视频在线观看一区二区三区 | 日本久久综合视频 | 亚洲黄色网络 | 国产99区 | 国产精品igao视频网网址 | 国产一二区免费视频 | 亚洲va欧美va人人爽春色影视 | 91精品国产三级a在线观看 | 手机看片中文字幕 | 最近日韩免费视频 | 久久久久免费精品 | 99热精品久久 | 国产九色91 | 天天躁天天操 | 国产又粗又猛又爽又黄的视频免费 | 一区二区三区免费看 | 久久99久久99精品免费看小说 | 人人爱爱人人 | 97精品国自产拍在线观看 | 成人91av| 免费看精品久久片 | 91视频a | 日韩理论片在线观看 | 国产尤物在线观看 | 亚洲午夜久久久久久久久电影网 | 久久国产二区 | 韩国av电影网 | 国产不卡在线观看 | 一区二区三区四区精品 | 91精品视频免费看 | 中文字幕 国产视频 | 国产精品一区二区av麻豆 | 黄色av免费在线 | 国产日韩精品一区二区三区 | 黄色电影小说 | 亚洲狠狠丁香婷婷综合久久久 | 色诱亚洲精品久久久久久 | 黄色亚洲 | 中国精品一区二区 | 人人爽人人射 | 天天色天天射天天综合网 | 四虎成人网 | 色偷偷人人澡久久超碰69 | 免费网站v | 色婷婷婷| 日韩欧美综合视频 | 中文字幕资源站 | 久久午夜免费视频 | 久久久久久在线观看 | 国产护士在线 | 97超碰色偷偷 | 欧美激精品| 91插插插网站| 欧美一级日韩免费不卡 | 狠狠干成人 | 婷婷激情欧美 | 夜夜躁日日躁狠狠久久88av | 免费成人黄色 | 九九热在线观看视频 | 亚洲少妇激情 | 国产小视频你懂的 | 97成人免费 | 国产精品一区二区视频 | 国产精品美女久久久久久久久 | 日韩网站中文字幕 | 51久久夜色精品国产麻豆 | 91av综合 | 成人免费中文字幕 | 欧洲色综合 | 99一级片 | 中文字幕在线影视资源 | 伊人色综合网 | 六月色丁香 | 欧美一区二区在线 | 狠狠狠干 | 美女啪啪图片 | 日韩免费电影在线观看 | 亚洲天天摸日日摸天天欢 | 激情久久五月 | 国产黄色片在线免费观看 | 日韩欧美国产免费播放 | 日本电影黄色 | 丝袜美女视频网站 | 亚洲综合视频在线 | 成人黄视频 | 99成人免费视频 | 日日夜夜天天久久 | 91福利区一区二区三区 | 日韩欧美在线高清 | 91豆花在线观看 | 欧美射射射| 久久人网 | 亚洲网久久 | 999久久久久久久久6666 | 成人福利在线播放 | 国产伦理剧 | 丁香婷婷深情五月亚洲 | 国产999免费视频 | 91在线蜜桃臀 | 91在线小视频 | 美女黄视频免费看 | 久久艹在线观看 | 在线小视频国产 | 玖玖玖在线观看 | 亚洲最大免费成人网 | 天堂视频一区 | 国产一区高清在线观看 | 久草热视频 | 久久久精品久久日韩一区综合 | 色妞久久福利网 | 天天操天天操 | 亚洲精品在线看 | 久久精品资源 | 国内小视频在线观看 | 成人动漫一区二区 | 中文字幕中文字幕在线中文字幕三区 | 日韩午夜剧场 | www.97视频 | 久久午夜电影网 | 日韩激情影院 | 亚洲另类视频在线观看 | 在线中文字幕视频 | 国产香蕉av | 成年人免费看片网站 | 精品久久久久久国产 | 91久久奴性调教 | 超碰97人人干 | 最新真实国产在线视频 | 久久久免费电影 | 日日天天干 | 91视频88av| 亚洲资源片 | 麻豆成人在线观看 | 国产黄a三级三级三级三级三级 | 国产精品久久99精品毛片三a | 国产精品久久久久av | 亚洲综合网站在线观看 | 视频在线观看日韩 | 97人人网 | 男女视频久久久 | av免费网 | 免费在线成人av | 亚洲手机天堂 | 91在线看视频免费 | 国内一级片在线观看 | 国产色女人 | 国产色视频一区 | 天天爱天天射天天干天天 | 免费的黄色的网站 | 婷婷深爱网 | 久久国产精品一区二区 | 99热精品久久 | 精品久久久久久久久久 | 国产成人精品一二三区 | 免费视频一区 | 91成人在线观看喷潮 | 精品国产一区二区三区免费 | 亚洲黄色av网址 | 精品综合久久 | 亚洲在线| 国产在线高清视频 | av超碰在线观看 | 久久久久久激情 | 久久久久久国产精品免费 | 国产一级电影在线 | 日本资源中文字幕在线 | 精品嫩模福利一区二区蜜臀 | 香蕉久久国产 | www.久久久久 | 黄色三级免费观看 | 亚洲国产精品成人av | 欧美一二三视频 | 麻豆视频在线免费看 | av免费看在线 | 久精品在线观看 | 国产精品免费一区二区三区在线观看 | 99性视频| 国产福利不卡视频 | 亚洲免费国产视频 | 国产又粗又猛又黄视频 | 97超碰人人澡 | 粉嫩aⅴ一区二区三区 | 丁香在线视频 | 国产精品久久久久一区二区三区 | 国产成人三级在线 | 精品成人在线 | 国内小视频在线观看 | 2019精品手机国产品在线 | 亚洲黄网站 | 亚洲五月花 | 精品一区三区 | 日韩精品中字 | 在线观看免费91 | 91cn国产在线 | 午夜精品久久久久久久久久久久 | 69国产盗摄一区二区三区五区 | 人人草人 | 久久人人爽人人爽人人片av免费 | 日韩在线视频一区二区三区 | 97国产| 国产韩国精品一区二区三区 | 激情综合亚洲 |