2 HTML躬行記——WebRTC基礎實踐

WebRTC (Web Real-Time Communications) 是一項實時通訊技術,在 2011 年由 Google 提出,經過 10 年的發展,W3C 于 2021 年正式發布 WebRTC 1.0 標準 。

2 HTML躬行記——WebRTC基礎實踐

文章插圖
WebRTC 標準概括介紹了兩種不同的技術:媒體捕獲設備和點對點連接(P2P,Peer-to-Peer),可讓用戶無需安裝任何插件或第三方軟件的情況下,實現共享桌面、文件傳輸、視頻直播等功能 。
下圖是官方給出的一張 WebRTC 整體架構設計圖:
2 HTML躬行記——WebRTC基礎實踐

文章插圖
  • 紫色部分是前端開發所使用的 API 。
  • 藍色實線部分是各大瀏覽器廠商所使用的 API 。
  • 藍色虛線部分包含可自定義的 3 塊:音頻引擎、視頻引擎和網絡傳輸 。
由于各個瀏覽器對 WebRTC 的實現有所不同,因此 Google 官方提供了一個適配器腳本庫:adapter.js,省去很多兼容工作 。
本文的源碼已上傳至 Github , 有需要的可以隨意下載 。
一、自拍自拍是指通過攝像頭拍照生成圖片,先看下 HTML 結構 , 其實就 4 個元素 。
<video id="video"></video><button id="btn">拍照</button><canvas id="canvas" width="300" height="300"></canvas><img id="img" alt="照片"/>1)getUserMedia()
然后在腳本中聲明各個元素 , 通過 navigator.mediaDevices.getUserMedia() 方法獲取媒體流 。
const video = document.getElementById('video');const canvas = document.getElementById('canvas');const btn = document.getElementById('btn');const img = document.getElementById('img');const size = 300;/** * 獲取媒體流 */navigator.mediaDevices.getUserMedia({video: {width: size,height: size,},audio: false}).then((stream) => {video.srcObject = stream;video.play();});getUserMedia() 的參數是一個包含了video 和 audio 兩個成員的 MediaStreamConstraints 對象,上面代碼將攝像頭的分辨率限制為 300 x 300 。
then() 中的 stream 參數是一個 MediaStream 媒體流,一個流相當于容器 , 可以包含幾條軌道,例如視頻和音頻軌道,每條軌道都是獨立的 。
video 元素中的 src 和 srcObject 是一對互斥的屬性,后者可關聯媒體源 , 根據規范也可以是 Blob 或者 File 等類型的數據 。
接著為按鈕綁定點擊事件,并且在點擊時從流中捕獲幀,畫到 Canvas 內,再導出賦給 img 元素 。
/** * 點擊拍照 */btn.addEventListener('click', (e) => {const context = canvas.getContext('2d');// 從流中捕獲幀context.drawImage(video, 0, 0, size, size);// 將幀導出為圖片const data = https://www.huyubaike.com/biancheng/canvas.toDataURL('image/png');img.setAttribute('src', data);}, false);在下圖中,左邊是 video 元素,打開攝像頭后就會有畫面,在點擊拍照按鈕后 , 右邊顯示捕獲的幀 。
2 HTML躬行記——WebRTC基礎實踐

文章插圖
2)enumerateDevices()
MediaDevices 提供了訪問媒體輸入和輸出的設備 , 例如攝像頭、麥克風等,得到硬件資源的媒體數據 。
mediaDevices.enumerateDevices() 會得到一個描述設備的 MediaDeviceInfo 的數組 。
其中 groupId 用于標識多個設備屬于同一個物理設備,例如一個顯示器內置了攝像頭和麥克風 。
navigator.mediaDevices.enumerateDevices().then((devices) => {devices.forEach((device) => {console.log(`${device.kind}: ${device.label} id = ${device.deviceId}`);});})3)devicechange
當媒體設備(例如麥克風、攝像頭等)連接到系統或從系統中移除時,devicechange 事件就會被發送給設備實例 。
navigator.mediaDevices.ondevicechange = (event) => { };event 參數沒有附加任何特殊的屬性 。
二、共享桌面Windows 系統采用的共享桌面協議是 RDP(Remote Desktop Protocal),另一種可在不同操作系統共享桌面的協議是 VNC(Virtual Network Console) 。
像 TeamViewer 采用的就是后一種協議 , 而 WebRTC 的遠程桌面沒有采用傳統的 RDP、VNC 等協議,因為不需要遠程控制 。
WebRTC 提供了 getDisplayMedia() 方法采集桌面,在使用上與之前的 getUserMedia() 方法類似 。
navigator.mediaDevices.getDisplayMedia({video: {width: 2000,height: 1000}}).then((stream) => {video.srcObject = stream;video.play();});在刷新頁面后,會要求選擇共享的桌面,包括整個屏幕、窗口或 Chrome 標簽頁 。
2 HTML躬行記——WebRTC基礎實踐

文章插圖
三、錄像WebRTC 的錄像包括錄制音頻和視頻兩種流,通過 Blob 對象將數據保存成多媒體文件 。

推薦閱讀