前言
WebRTC是一個開源項目,旨在使得瀏覽器能為實時通信(RTC)提供簡單的JavaScript接口。說的簡單明了一點就是讓瀏覽器提供JS的即時通信接口。這個接口所創(chuàng)立的信道并不是像WebSocket一樣,打通一個瀏覽器與WebSocket服務器之間的通信,而是通過一系列的信令,建立一個瀏覽器與瀏覽器之間(peer-to-peer)的信道,這個信道可以發(fā)送任何數(shù)據(jù),而不需要經(jīng)過服務器。并且WebRTC通過實現(xiàn)MediaStream,通過瀏覽器調(diào)用設備的攝像頭、話筒,使得瀏覽器之間可以傳遞音頻和視頻
WebRTC使得實時通信變成一種標準功能,任何Web應用都無需借助第三方插件和專有軟件,而是通過簡單地JavaScript API即可完成。
在WebRTC中,有三個主要的知識點,理解了這三個知識點,也就理解了WebRTC的底層實現(xiàn)原理。這三個知識點分別是:
MediaStream:獲取音頻和視頻流
RTCPeerConnection:音頻和視頻數(shù)據(jù)通信
RTCDataChannel:任意應用數(shù)據(jù)通信
MediaStream
html
<!DOCTYPE html>
<html>
<head>
<title>Realtime communication with WebRTC</title>
</head>
<body>
<h1>Realtime communication with WebRTC</h1>
<video autoplay playsinline></video>
<script src="js/main.js"></script>
</body>
</html>
main.js
const mediaStreamConstraints = {
video: true,
};
// Video element where stream will be placed.
const localVideo = document.querySelector('video');
// Local stream that will be reproduced on the video.
let localStream;
// Handles success by adding the MediaStream to the video element.
function gotLocalMediaStream(mediaStream) {
localStream = mediaStream;
localVideo.srcObject = mediaStream;
}
// Handles error by logging a message to the console with the error message.
function handleLocalMediaStreamError(error) {
console.log('navigator.getUserMedia error: ', error);
}
// Initializes media stream.
navigator.mediaDevices.getUserMedia(mediaStreamConstraints)
.then(gotLocalMediaStream).catch(handleLocalMediaStreamError);
上面這段代碼,就是獲取了本地的攝像頭,拿到權限后把他添加到video中。
localStream放在了全局,為了可以在命令行中調(diào)試方便,可方便的查看輸出,生產(chǎn)環(huán)境的代碼不要這樣寫。
在JS中,我們通過getUserMedia函數(shù)來處理音頻和視頻,該函數(shù)接收三個參數(shù),分別是音視頻的約束,成功的回調(diào)以及失敗的回調(diào)。
其中第一個參數(shù)約束,默認是關掉音頻audio的,所以指定視頻就將只打開視頻。
也可像下面一樣指定詳細信息
const mediaStreamConstraints = {
video: {
width: {
min: 1280
},
height: {
min: 720
}
}
}
MediaTrackConstraints specification 列舉出了所有的約束,雖然不是每個瀏覽器都支持全部這些選項。
在底層,瀏覽器通過音頻和視頻引擎對捕獲的原始音頻和視頻流加以處理,除了對畫質(zhì)和音質(zhì)增強之外,還得保證音頻和視頻的同步。
由于音頻和視頻是用來傳輸?shù)?,因此,發(fā)送方還要適應不斷變化的帶寬和客戶端之間的網(wǎng)絡延遲調(diào)整輸出的比特率。
對于接收方來說,則必須實時解碼音頻和視頻流,并適應網(wǎng)絡抖動和時延。其工作原理如下圖所示:

如上成功回調(diào)的stream對象中攜帶者一個或多個同步的Track,如果你同時在約束中設置了音頻和視頻為true,則在stream中會攜帶有音頻Track和視頻Track,每個Track在時間上是同步的。
stream的輸出可以被發(fā)送到一或多個目的地:本地的音頻或視頻元素、后期處理的JavaScript代理,或者遠程另一端。如下圖所示:
