1.WebRTC開發背景
由於業務需求,需要在項目中實現實時音視頻通話功能,之前基於瀏覽器開發的Web項目要進行音視頻通話,需要安裝flash插件才能實現或者使用C/S客戶端進行通信。隨着互聯網技術的驅動下,在很多場景下需要進行音視頻通信,在生活中我們現在使用電話越來越少,使用微信和視頻越來越多。在一些行業也需要進行音視頻實時通信,如:在線教育,遠程醫療,保險理賠等等。有了WebRTC,可以開發一些好的網頁應用,使得音視頻通話越來越簡單,無需安裝任何插件,只需打開網頁,就能實現音視頻通話,方然也能實現消息收發,文件收發等等,下面,根據自己平時的項目開發與,對WebRTC就行一個簡單的理解與概述,最終實現一個簡單的拍照室Demo。
2.WebRTC歷史和概述
WebRTC是“網絡實時通信”(Web Real Time Communication)的縮寫。它最初是為了解決瀏覽器上視頻通話而提出的,即兩個瀏覽器之間直接進行視頻和音頻的通信,不經過服務器。后來發展到除了音頻和視頻,還可以傳輸文字和其他數據。2010年5月,Google以6820萬美元收購VoIP軟件開發商Global IP Solutions的GIPS引擎,並改為名為“WebRTC”。WebRTC使用GIPS引擎,實現了基於網頁的視頻會議,並支持722,PCM,ILBC,ISAC等編碼,同時使用谷歌自家的VP8視頻解碼器;同時支持RTP/SRTP傳輸等。Google是WebRTC的主要支持者和開發者,它推動了WebRTC標准的確立。
WebRTC是一門年輕的技術,從2011推出到2017年,一直發展的不溫不火。根據一段時間的開發,個人認為主要原因有:各個瀏覽器的支持兼容程度和在互聯網環境下點對點能夠連接的成功率。從2017年蘋果公司宣布iOS11的Safari瀏覽器支持WebRTC,一些雲通信產品例如騰訊雲通信和網易雲通信也是基於WebRTC上進行封裝二次開發,也間接的說明了WebRTC發展會越來越好。

3.基本概念的了解
為了簡化開發,WebRTC在瀏覽器中API集成了大量的技術,解決了一些繁重的問題,如捕捉攝像頭和麥克風,處理音視頻流,傳輸層等等。

- 捕捉攝像頭和麥克風
建立通信平台第一步要檢測用戶設備的攝像頭和麥克風權限,先檢測設備的可用性,然后在獲取用戶授權並與設備建立連接,最后獲取一段數據流。
- 音頻與視頻的編解碼
在互聯網要發送一段音視頻數據,技術優化了網絡數據,數據尺寸也還是很大,所以要對數據在發送端編碼,然后在接收端解碼。WebRTC內置的幾種編解碼器包括:H.264,Opcus,iSAC,VP8。作為前端開發的我,最這些編解碼技術當然不是很了解。幸運的是,當兩個瀏覽器回話時,會綜合兩端情況選擇最優的編解碼器。
- 傳輸層
主要處理數據丟包,數據包排序以及建立用戶之間的連接問題
- 會話管理
通常來說就是信令(Signaling),負責在瀏覽器中建立並管理多個連接。
4.獲取用戶媒體
創建一個基於WebRTC的通信平台,首先要通過用戶的網絡攝像頭和麥克風獲取實時的視頻和音頻流,可以通過調用瀏覽器的getUserMedia API來實現。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>獲取媒體流</title>
</head>
<body>
<div id="app">
<h1>獲取媒體流</h1>
<video autoplay></video>
</div>
<script>
function hasUserMedia() {
return !!(navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);
}
if (hasUserMedia()) {
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
navigator.getUserMedia({video: true, audio: false}, function (stream) {
console.log(stream);
var video = document.querySelector('video');
video.src=window.URL.createObjectURL(stream);
}, function (err) {
console.log(err);
});
} else {
alert("Sorry, your browser does not support getUserMedia.");
}
</script>
</body>
</html>

是否打開使用攝像頭權限

注意:打開攝像頭后獲取到的視頻流展示在Video標簽中,video標簽需要加上autoplay屬性視頻才可以播放,在調試中可以把getUserMedia方法參數中的audio設置為:false,避免雜音太大,同理,把video設置為false只能聽到自己說話而沒有畫面,可以代替普通電話使用。
5.限制視頻流
我們可以通過設置參數來控制視頻和音頻是否使用,除此之外,我們可以傳入一個對象做更復雜的限制,如分辨率,視頻寬高比等等。
navigator.getUserMedia({video: {
width: 320,
/*height:240,*/
aspectRatio:1.77
}, audio: false}, function (stream) {
console.log(stream);
var video = document.querySelector('video');
video.src=window.URL.createObjectURL(stream);
}, function (err) {
console.log(err);
});

可以根據自己業務需求來設置固定的寬高或分辨率等等。
6.完成一個拍照室Demo
通過調用攝像頭獲取到的視頻流以及H5的canvas標簽我們可以完成一個簡易的拍照功能。
增加一個拍照按鈕以及一個canvas,修改后的整個頁面代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>獲取媒體流</title>
</head>
<body>
<div id="app">
<h1>獲取媒體流</h1>
<video id="video" autoplay></video>
<button type="button" onclick="capture()">點擊拍照</button>
<canvas id="canvas" width="320" height="240"></canvas>
</div>
<script>
function hasUserMedia() {
return !!(navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);
}
if (hasUserMedia()) {
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
navigator.getUserMedia({video: {
width: 320,
height:240,
}, audio: false}, function (stream) {
console.log(stream);
var video = document.querySelector('video');
video.src=window.URL.createObjectURL(stream);
}, function (err) {
console.log(err);
});
} else {
alert("Sorry, your browser does not support getUserMedia.");
}
function capture(){
console.log('capture...');
var cxt=document.getElementById('canvas').getContext('2d');
var video=document.getElementById('video');
cxt.drawImage(video,0,0);
}
</script>
</body>
</html>

現在單擊一個點擊拍照按鈕,可以捕捉視頻的某一幀並同時繪制到canvas上,加上canvas功能本來就很強大,后期對照片的旋轉,剪裁,濾鏡也都是可以實現的。
延伸:現在很多WebApp上要實時上傳證件功能,我們通過這種WebRTC+canvas也是可以實現的,而且是瀏覽器直接調的硬件拍照,有沒有很溜。
7.開發中遇到的問題
在直接用http打開本地服務器頁面是調用不了攝像頭的,瀏覽器的限制認為http下是不安全的,但是可以用127.0.0.1或者localhost來代替本機ip。網頁部署到服務器時也得使用https協議來返回頁面,否則,無法調用攝像頭。

以上簡單的介紹了WebRTC的發展歷史以及一些基本概念,讓大家對其有個初步的了解,最后通過調用攝像頭完成一個拍照室的Demo。后續文章再詳細的寫如何通過WebRTC來實現點對點通信,相信WebRTC功能會越來越強大,這只是第一步。
參考資料:
《Learning WebRTC 中文版》
《JavaScript 標准參考教程(alpha) 阮一峰》
轉載請注明出處,謝謝。
