成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

深入理解WebRTC

sumory / 2395人閱讀

摘要:對(duì)于接收方來說,則必須實(shí)時(shí)解碼音頻和視頻流,并適應(yīng)網(wǎng)絡(luò)抖動(dòng)和時(shí)延。另外,由于主要是用來解決實(shí)時(shí)通信的問題,可靠性并不是很重要,因此,使用作為傳輸層協(xié)議低延遲和及時(shí)性才是關(guān)鍵。握手記錄嚴(yán)格按照協(xié)議規(guī)定的順序傳輸,順序不對(duì)就報(bào)錯(cuò)。

Web Real-Time Communication(Web實(shí)時(shí)通信,WebRTC)由一組標(biāo)準(zhǔn)、協(xié)議和JavaScript API組成,用于實(shí)現(xiàn)瀏覽器之間(端到端)的音頻、視頻及數(shù)據(jù)共享。

WebRTC使得實(shí)時(shí)通信變成一種標(biāo)準(zhǔn)功能,任何Web應(yīng)用都無需借助第三方插件和專有軟件,而是通過簡(jiǎn)單地JavaScript API即可完成。

在WebRTC中,有三個(gè)主要的知識(shí)點(diǎn),理解了這三個(gè)知識(shí)點(diǎn),也就理解了WebRTC的底層實(shí)現(xiàn)原理。這三個(gè)知識(shí)點(diǎn)分別是:

MediaStream:獲取音頻和視頻流

RTCPeerConnection:音頻和視頻數(shù)據(jù)通信

RTCDataChannel:任意應(yīng)用數(shù)據(jù)通信

MediaStream

如上所說,MediaStream主要是用于獲取音頻和視頻流。其JS實(shí)現(xiàn)也比較簡(jiǎn)單,代碼如下:

"use strict";

navigator.getUserMedia = navigator.getUserMedia ||
    navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

var constraints = { // 音頻、視頻約束
  audio: true, // 指定請(qǐng)求音頻Track
  video: {  // 指定請(qǐng)求視頻Track
      mandatory: { // 對(duì)視頻Track的強(qiáng)制約束條件
          width: {min: 320},
          height: {min: 180}
      },
      optional: [ // 對(duì)視頻Track的可選約束條件
          {frameRate: 30}
      ]
  }
};

var video = document.querySelector("video");

function successCallback(stream) {
  if (window.URL) {
    video.src = window.URL.createObjectURL(stream);
  } else {
    video.src = stream;
  }
}

function errorCallback(error) {
  console.log("navigator.getUserMedia error: ", error);
}

navigator.getUserMedia(constraints, successCallback, errorCallback);

在JS中,我們通過getUserMedia函數(shù)來處理音頻和視頻,該函數(shù)接收三個(gè)參數(shù),分別是音視頻的約束,成功的回調(diào)以及失敗的回調(diào)。

在底層,瀏覽器通過音頻和視頻引擎對(duì)捕獲的原始音頻和視頻流加以處理,除了對(duì)畫質(zhì)和音質(zhì)增強(qiáng)之外,還得保證音頻和視頻的同步。

由于音頻和視頻是用來傳輸?shù)?,因此,發(fā)送方還要適應(yīng)不斷變化的帶寬和客戶端之間的網(wǎng)絡(luò)延遲調(diào)整輸出的比特率。

對(duì)于接收方來說,則必須實(shí)時(shí)解碼音頻和視頻流,并適應(yīng)網(wǎng)絡(luò)抖動(dòng)和時(shí)延。其工作原理如下圖所示:

如上成功回調(diào)的stream對(duì)象中攜帶者一個(gè)或多個(gè)同步的Track,如果你同時(shí)在約束中設(shè)置了音頻和視頻為true,則在stream中會(huì)攜帶有音頻Track和視頻Track,每個(gè)Track在時(shí)間上是同步的。

stream的輸出可以被發(fā)送到一或多個(gè)目的地:本地的音頻或視頻元素、后期處理的JavaScript代理,或者遠(yuǎn)程另一端。如下圖所示:

RTCPeerConnection

在獲取到音頻和視頻流后,下一步要做的就是將其發(fā)送出去。但這個(gè)跟client-server模式不同,這是client-client之間的傳輸,因此,在協(xié)議層面就必須解決NAT穿透問題,否則傳輸就無從談起。

另外,由于WebRTC主要是用來解決實(shí)時(shí)通信的問題,可靠性并不是很重要,因此,WebRTC使用UDP作為傳輸層協(xié)議:低延遲和及時(shí)性才是關(guān)鍵。

在更深入講解之前,我們先來思考一下,是不是只要打開音頻、視頻,然后發(fā)送UDP包就搞定了?

當(dāng)然沒那么簡(jiǎn)單,除了要解決我們上面說的NAT穿透問題之外,還需要為每個(gè)流協(xié)商參數(shù),對(duì)用戶數(shù)據(jù)進(jìn)行加密,并且需要實(shí)現(xiàn)擁塞和流量控制。

我們來看一張WebRTC的分層協(xié)議圖:

ICE、STUN和TURN是通過UDP建立并維護(hù)端到端連接所必需的;SDP 是一種數(shù)據(jù)格式,用于端到端連接時(shí)協(xié)商參數(shù);DTLS用于保障傳輸數(shù)據(jù)的安全;SCTP和SRTP屬于應(yīng)用層協(xié)議,用于在UDP之上提供不同流的多路復(fù)用、擁塞和流量控制,以及部分可靠的交付和其他服務(wù)。

ICE(Interactive Connectivity Establishment,交互連接建立):由于端與端之間存在多層防火墻和NAT設(shè)備阻隔,因此我們需要一種機(jī)制來收集兩端之間公共線路的IP,而ICE則是干這件事的好幫手。

ICE代理向操作系統(tǒng)查詢本地IP地址

如果配置了STUN服務(wù)器,ICE代理會(huì)查詢外部STUN服務(wù)器,以取得本地端的公共IP和端口

如果配置了TURN服務(wù)器,ICE則會(huì)將TURN服務(wù)器作為一個(gè)候選項(xiàng),當(dāng)端到端的連接失敗,數(shù)據(jù)將通過指定的中間設(shè)備轉(zhuǎn)發(fā)。

WebRTC使用SDP(Session Description Protocol,會(huì)話描述協(xié)議)描述端到端連接的參數(shù)。
SDP不包含媒體本身的任何信息,僅用于描述"會(huì)話狀況",表現(xiàn)為一系列的連接屬性:要交換的媒體類型(音頻、視頻及應(yīng)用數(shù)據(jù))、網(wǎng)絡(luò)傳輸協(xié)議、使用的編解碼器及其設(shè)置、帶寬及其他元數(shù)據(jù)。

DTLS對(duì)TLS協(xié)議進(jìn)行了擴(kuò)展,為每條握手記錄明確添加了偏移字段和序號(hào),這樣就滿足了有序交付的條件,也能讓大記錄可以被分段成多個(gè)分組并在另一端再進(jìn)行組裝。
DTLS握手記錄嚴(yán)格按照TLS協(xié)議規(guī)定的順序傳輸,順序不對(duì)就報(bào)錯(cuò)。最后,DTLS還要處理丟包問題:兩端都是用計(jì)時(shí)器,如果預(yù)定時(shí)間沒有收到應(yīng)答,就重傳握手記錄。
為保證過程完整,兩端都要生成自己簽名的證書,然后按照常規(guī)的TLS握手協(xié)議走。但這樣的證書不能用于驗(yàn)證身份,因?yàn)闆]有要驗(yàn)證的信任鏈。因此,在必要情況下,
應(yīng)用必須自己參與各端的身份驗(yàn)證:

應(yīng)用可以通過登錄來驗(yàn)證用戶

每一端也可以在生成SDP提議/應(yīng)答時(shí)指定各自的"身份頒發(fā)機(jī)構(gòu)",等對(duì)端接收到SDP消息后,可以聯(lián)系指定的身份頒發(fā)機(jī)構(gòu)驗(yàn)證收到的證書

SRTP為通過IP網(wǎng)絡(luò)交付音頻和視頻定義了標(biāo)準(zhǔn)的分組格式。SRTP本身并不對(duì)傳輸數(shù)據(jù)的及時(shí)性、可靠性或數(shù)據(jù)恢復(fù)提供任何保證機(jī)制,
它只負(fù)責(zé)把數(shù)字化的音頻采樣和視頻幀用一些元數(shù)據(jù)封裝起來,以輔助接收方處理這些流。

SCTP是一個(gè)傳輸層協(xié)議,直接在IP協(xié)議上運(yùn)行,這一點(diǎn)跟TCP和UDP類似。不過在WebRTC這里,SCTP是在一個(gè)安全的DTLS信道中運(yùn)行,而這個(gè)信道又運(yùn)行在UDP之上。
由于WebRTC支持通過DataChannel API在端與端之間傳輸任意應(yīng)用數(shù)據(jù),而DataChannel就依賴于SCTP。

以上講了這么多,終于到我們的主角RTCPeerConnection,RTCPeerConnection接口負(fù)責(zé)維護(hù)每一個(gè)端到端連接的完整生命周期:

RTCPeerConnection管理穿越NAT的完整ICE工作流

RTCPeerConnection發(fā)送自動(dòng)(STUN)持久化信號(hào)

RTCPeerConnection跟蹤本地流

RTCPeerConnection跟蹤遠(yuǎn)程流

RTCPeerConnection按需觸發(fā)自動(dòng)流協(xié)商

RTCPeerConnection提供必要的API,以生成連接提議,接收應(yīng)答,允許我們查詢連接的當(dāng)前狀態(tài),等等

我們來看一下示例代碼:

var signalingChannel = new SignalingChannel();
var pc = null;
var ice = {
    "iceServers": [
        { "url": "stun:stun.l.google.com:19302" }, //使用google公共測(cè)試服務(wù)器
        { "url": "turn:[email protected]", "credential": "pass" } // 如有turn服務(wù)器,可在此配置
    ]
};
signalingChannel.onmessage = function (msg) {
    if (msg.offer) { // 監(jiān)聽并處理通過發(fā)信通道交付的遠(yuǎn)程提議
        pc = new RTCPeerConnection(ice);
        pc.setRemoteDescription(msg.offer);
        navigator.getUserMedia({ "audio": true, "video": true }, gotStream, logError);
    } else if (msg.candidate) { // 注冊(cè)遠(yuǎn)程ICE候選項(xiàng)以開始連接檢查
        pc.addIceCandidate(msg.candidate);
    }
}
function gotStream(evt) {
    pc.addstream(evt.stream);
    var local_video = document.getElementById("local_video");
    local_video.src = window.URL.createObjectURL(evt.stream);
    pc.createAnswer(function (answer) { // 生成描述端連接的SDP應(yīng)答并發(fā)送到對(duì)端
        pc.setLocalDescription(answer);
        signalingChannel.send(answer.sdp);
    });
}
pc.onicecandidate = function (evt) {
    if (evt.candidate) {
        signalingChannel.send(evt.candidate);
    }
}
pc.onaddstream = function (evt) {
    var remote_video = document.getElementById("remote_video");
    remote_video.src = window.URL.createObjectURL(evt.stream);
}
function logError() { ... }
DataChannel

DataChannel支持端到端的任意應(yīng)用數(shù)據(jù)交換,就像WebSocket一樣,但是是端到端的。
建立RTCPeerConnection連接之后,兩端可以打開一或多個(gè)信道交換文本或二進(jìn)制數(shù)據(jù)。

其示例demo如下:

var ice = {
    "iceServers": [
        {"url": "stun:stun.l.google.com:19302"},   // google公共測(cè)試服務(wù)器
        // {"url": "turn:[email protected]", "credential": "pass"}
    ]
};

// var signalingChannel =  new SignalingChannel();

var pc = new RTCPeerConnection(ice);

navigator.getUserMedia({"audio": true}, gotStream, logError);

function gotStream(stram) {
    pc.addStream(stram);

    pc.createOffer().then(function(offer){
        pc.setLocalDescription(offer);
    });
}

pc.onicecandidate = function(evt) {
    // console.log(evt);
    if(evt.target.iceGatheringState == "complete") {
        pc.createOffer().then(function(offer){
            // console.log(offer.sdp);
            // signalingChannel.send(sdp);
        })
    }
}

function handleChannel(chan) {
    console.log(chan);
    chan.onerror = function(err) {}
    chan.onclose = function() {}
    chan.onopen = function(evt) {
        console.log("established");
        chan.send("DataChannel connection established.");
    }

    chan.onmessage = function(msg){
        // do something
    }
}


// 以合適的交付語義初始化新的DataChannel
var dc = pc.createDataChannel("namedChannel", {reliable: false});

handleChannel(dc);
pc.onDataChannel = handleChannel;


function logError(){
    console.log("error");
}

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/88764.html

相關(guān)文章

  • JavaScript 是如何工作的:WebRTC 和對(duì)等網(wǎng)絡(luò)的機(jī)制!

    摘要:為了使連接起作用,對(duì)等方必須獲取元數(shù)據(jù)的本地媒體條件例如,分辨率和編解碼器功能,并收集應(yīng)用程序主機(jī)的可能網(wǎng)絡(luò)地址,用于來回傳遞這些關(guān)鍵信息的信令機(jī)制并未內(nèi)置到中。所有特定于多媒體的元數(shù)據(jù)都使用協(xié)議傳遞。 這是專門探索 JavaScript 及其所構(gòu)建的組件的系列文章的第 18 篇。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! 如果你錯(cuò)過了前面的章節(jié),可以在這里...

    XBaron 評(píng)論0 收藏0
  • 開發(fā)一個(gè)實(shí)時(shí)音視頻通信系統(tǒng),你需要什么技術(shù)儲(chǔ)備?

    摘要:實(shí)時(shí)通訊系統(tǒng)是最近互聯(lián)網(wǎng)應(yīng)用的一個(gè)新領(lǐng)域。現(xiàn)在的問題是,開發(fā)一個(gè)優(yōu)秀的系統(tǒng)需要具備哪些技術(shù)儲(chǔ)備呢先看終端方面。各個(gè)平臺(tái),,,底層音頻系統(tǒng)也需要深入了解?;ヂ?lián)網(wǎng)不是一個(gè)可靠的實(shí)時(shí)音視頻傳輸網(wǎng)絡(luò)。現(xiàn)在我們知道開發(fā)一個(gè)系統(tǒng)需要什么技術(shù)了。 RTC(real time communication)實(shí)時(shí)通訊系統(tǒng)是最近互聯(lián)網(wǎng)應(yīng)用的一個(gè)新領(lǐng)域。RTC系統(tǒng)的應(yīng)用極其廣泛,我們常見的視頻電話,會(huì)議系統(tǒng),...

    church 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<