1.WebRTC簡介
WebRTC是一個(gè)開源的項(xiàng)目,可以提供瀏覽器,手機(jī)應(yīng)用之間實(shí)時(shí)通信能力。
同時(shí),這一功能已經(jīng)內(nèi)置于現(xiàn)代瀏覽器中,所以它可以做到無須借助第三方軟件或插件便可以在開發(fā)網(wǎng)絡(luò)中傳輸高質(zhì)量音視頻流。
-
主要JavaScript API
- MediaStream 音視頻流對(duì)象
- RTCPeerConnection 端對(duì)端音視頻連接對(duì)象
- RTCDataChannel 端對(duì)端數(shù)據(jù)通道對(duì)象
-
適用設(shè)備
- Firefox,Opera,Chrome瀏覽器支持并默認(rèn)啟用了WebRTC功能,并且能夠?qū)崿F(xiàn)互相通信
- IE瀏覽器直到11版本還未支持WebRTC,但是Edge15版本已經(jīng)開始支持WebRTC,最新瀏覽器支持可以查看Can I use
- 原生安卓和ios應(yīng)用均已支持
2.建立連接過程
2.1 概述
首先我們可以分析一下,建立連接需要哪些條件:
1.我們需要知道對(duì)方瀏覽器的網(wǎng)絡(luò)地址才能連接到它,需要獲取到對(duì)方的IP地址和端口號(hào)
2.我們需要對(duì)對(duì)方支持的音頻和視頻編解碼器等電腦軟硬件信息有所了解
當(dāng)我們互相拿到了對(duì)方的地址和電腦軟硬件信息后,就可以通過RTCPeerConnection對(duì)象來建立連接了:

2.2 獲取地址
在獲取對(duì)方地址時(shí),因?yàn)楝F(xiàn)實(shí)網(wǎng)絡(luò)情況的復(fù)雜性,可能不能直接獲取到對(duì)方的地址,這時(shí)就需要用到STUN,TURN和ICE組件來處理不同類型網(wǎng)絡(luò)間的呼叫連接。現(xiàn)實(shí)網(wǎng)絡(luò)環(huán)境有三種情況:
公共網(wǎng)絡(luò)
這類網(wǎng)絡(luò)IP之間可以不受限制地進(jìn)行互相訪問NAT網(wǎng)絡(luò)
這類網(wǎng)絡(luò)主機(jī)在私有內(nèi)網(wǎng)中,沒有單獨(dú)的公網(wǎng)IP,STUN協(xié)議就是解決此網(wǎng)絡(luò)問題
首先發(fā)一個(gè)請(qǐng)求給STUN服務(wù)器,以開啟STUN協(xié)議,之后服務(wù)器識(shí)別出發(fā)出請(qǐng)求的客戶端IP地址,并將其返回給客戶端,客戶端就能通過返回的IP地址來識(shí)別自己嚴(yán)格受限的NAT網(wǎng)絡(luò)
這類網(wǎng)絡(luò)中的主機(jī)在內(nèi)網(wǎng)內(nèi),只能單向訪問外網(wǎng),外網(wǎng)不能直接訪問它,所以這類網(wǎng)絡(luò)需要通過在公共網(wǎng)絡(luò)上的服務(wù)器來進(jìn)行數(shù)據(jù)中轉(zhuǎn),TURN協(xié)議就是解決此網(wǎng)絡(luò)問題
TURN服務(wù)器可以在對(duì)等連接的雙方之間增加一個(gè)轉(zhuǎn)播,TURN服務(wù)器去下載、處理并重定向每一個(gè)用戶發(fā)過來的數(shù)據(jù)包
最后,ICE則是一個(gè)將STUN和TURN結(jié)合在一起的標(biāo)準(zhǔn),它會(huì)判斷主機(jī)是上面三種類型之一,并用相應(yīng)的方法來建立主機(jī)之間的連接
2.3 獲取電腦軟硬件信息
我們需要獲取到對(duì)方所支持的音頻和視頻編解碼器,他們使用哪種網(wǎng)絡(luò)以及他們電腦可以處理多少數(shù)據(jù),我們就需要一個(gè)有用戶所有信息的字符串名片來傳送給其他用戶,這里我們可以使用SDP(會(huì)話描述協(xié)議)
SDP涵蓋了一個(gè)指定用戶的描述、時(shí)間配置和對(duì)媒體的限制,類似于你電腦的名片,其他用戶可以通過它來試著聯(lián)系到你
3.創(chuàng)建應(yīng)用
這里可以創(chuàng)建一個(gè)WebRTC本地應(yīng)用來熟悉一下以上建立連接的流程,主要的功能就是從用戶攝像頭獲取圖像,最終在頁面上顯示兩個(gè)視頻流,一個(gè)來自攝像頭,另一個(gè)來自本地WebRTC連接。
這里我們使用的兩個(gè)連接對(duì)象都在同一個(gè)瀏覽器中,直接瀏覽器中傳輸即可,在真實(shí)環(huán)境中,連接的用戶和自己并不在同一個(gè)瀏覽器中,這就需要一個(gè)websocket服務(wù)器,用于在瀏覽器中連接雙方。
1.由于瀏覽器API有相應(yīng)的前綴,需要有兩個(gè)兼容函數(shù)來首先處理一下:
function hasUserMedia() {
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;
return !!navigator.getUserMedia;
}
function hasRTCPeerConnection() {
window.RTCPeerConnection = window.RTCPeerConnection ||
window.webkitRTCPeerConnection ||
window.mozRTCPeerConnection ||
window.msRTCPeerConnection;
return !!window.RTCPeerConnection;
}
2.可以通過配置自己的STUN服務(wù)器地址,或者不寫配置使用瀏覽器默認(rèn)的STUN服務(wù)器地址,來創(chuàng)建兩個(gè)RTCPeerConnection對(duì)象來模擬連接
var configuration={
//iceServers: [{ url: "stun:127.0.0.1:9876" }]
};
youConnection = new RTCPeerConnection(configuration);
otherConnection = new RTCPeerConnection(configuration);
3.通信雙方交換ICE候選路徑,也就是通過ICE獲取到自己的IP和端口號(hào)后,再互相交換此信息
youConnection.onicecandidate = function (event) {
if (event.candidate) {
console.log(event.candidate);
otherConnection.addIceCandidate(new RTCIceCandidate(event.candidate));
}
};
otherConnection.onicecandidate = function (event) {
if (event.candidate) {
console.log(event.candidate);
youConnection.addIceCandidate(new RTCIceCandidate(event.candidate));
}
};
4.通信雙方通過交換offer和answer來互換SDP信息
var offerOptions={
offerToRecceiveAudio: 1,
offerToReceiveVideo: 1
};
youConnection.createOffer(offerOptions)
.then(function(offer){
console.log(offer);
youConnection.setLocalDescription(offer);
otherConnection.setRemoteDescription(offer);
otherConnection.createAnswer(offerOptions)
.then(function(answer){
console.log(answer);
otherConnection.setLocalDescription(answer);
youConnection.setRemoteDescription(answer);
});
});
5.這樣通信雙方的連接就建立起來了,可以向連接對(duì)象中添加媒體流,另一個(gè)連接對(duì)象就能讀出媒體流,并實(shí)時(shí)顯示在video標(biāo)簽中
youConnection.onaddstream=function(event){
you.srcObject=event.stream;
};
otherConnection.addStream(stream);
4.參考資料
- 《Learning WebRTC》
- 《WebRTC權(quán)威指南》
- 《WebRTC零基礎(chǔ)開發(fā)者教程》