[譯]WebRTC基礎實踐 - 4. 獲取攝像頭的視訊流
本節內容
在本節課程中, 我們將學習以下知識點:
本節的完整版程式碼位於 step-01
資料夾中。
HTML程式碼
在 work
目錄下的 index.html
檔案中, 增加 video
標籤和 script
標籤:
<!DOCTYPE html> <html> <head> <title>Realtime communication with WebRTC</title> <link rel="stylesheet" href="css/main.css" /> </head> <body> <h1>Realtime communication with WebRTC</h1> <!-- 增加的程式碼在下面這裡: --> <video autoplay playsinline></video> <script src="js/main.js"></script> </body> </html>
注意: 如果有中文字元, 則 .html
檔案需要使用 UTF-8 編碼儲存/另存。
JavaScript程式碼
在 js
目錄下的 main.js
檔案中, 加入以下的程式碼:
'use strict'; // 本節只需要使用到 video (video: true). const mediaStreamConstraints = { video: true }; // 用於播放視訊流stream 的 video元素. const localVideo = document.querySelector('video'); // Local stream that will be reproduced on the video. let localStream; // success 處理函式;by adding the MediaStream to the video element. function gotLocalMediaStream(mediaStream) { localStream = mediaStream; localVideo.srcObject = mediaStream; } // error 處理函式;將 error 資訊列印到 console. function handleLocalMediaStreamError(error) { console.log('navigator.getUserMedia error: ', error); } // 初始化 media stream. navigator.mediaDevices.getUserMedia(mediaStreamConstraints) .then(gotLocalMediaStream).catch(handleLocalMediaStreamError);
本教程中的 JavaScript 程式碼, 都在起始處加上 'use strict';
,這樣可以避免很多新手經常碰到的程式設計錯誤。
關於嚴格模式的更多資訊, 請參考 ofollow,noindex" target="_blank">ECMAScript 5 Strict Mode, JSON, and More 。
執行示例
在瀏覽器中開啟對應的 index.html
頁面, 效果類似如下:
當然, 頁面中展示的你本地攝像頭實時拍攝到的內容。
原理解析
navigator.mediaDevices.getUserMedia(mediaStreamConstraints) .then(gotLocalMediaStream).catch(handleLocalMediaStreamError); }
呼叫 getUserMedia()
方法之後, 瀏覽器會判斷當前域名(domain)是否具有呼叫攝像頭的許可權, 如果是第一次請求授權, 則會彈出對話方塊, 要求使用者手動選擇允許。 如下圖所示:
如果許可權驗證通過, 則返回 API/MediaStream" rel="nofollow,noindex" target="_blank">MediaStream 物件, 可以將該物件賦值給 media 元素的 srcObject
屬性:
function gotLocalMediaStream(mediaStream) { localVideo.srcObject = mediaStream; }
引數 constraints
可以指定要獲取哪些 media 資訊。如果不指定, 聲音(audio) 預設配置是禁用的, 所以此處實際上只獲取了 video 流:
const mediaStreamConstraints = { video: true };
還可以加上更多的約束條件, 例如設定視訊解析度:
const hdConstraints = { video: { width: { min: 1280 }, height: { min: 720 } } }
MediaTrackConstraints 規範文件 列出了所有可用的約束型別, 雖然有一些瀏覽器不相容其中的某些選項。如果當前選擇的攝像頭不支援給定的約束選項, 呼叫 getUserMedia()
時則會丟擲 OverconstrainedError
錯誤。預設也不會提示使用者進行再次授權。
當然, 使用者隨時可以管理授權資訊, 或者切換攝像頭, 如下圖所示:
各個版本的瀏覽器介面可能略有不同, 但應該都能找到管理授權的地方。搞不定的就上網搜尋。
關於限制不同解析度的demo, 請參考 https://simpl.info/getusermedia/constraints/ , 選擇攝像頭和麥克風的demo請參考: https://simpl.info/getusermedia/sources/ 。
如果 getUserMedia()
呼叫成功, 則將攝像頭傳過來的視訊流, 作為 video 的來源:
function gotLocalMediaStream(mediaStream) { localVideo.srcObject = mediaStream; }
練習與實踐
- 此處
localStream
是一個全域性變數, 所以可以通過 console 來檢視: 開啟瀏覽器控制檯, 輸入localStream
並按回車。 (開啟控制檯的方式: Windows系統按F12並選擇; 或者組合快捷鍵:Ctrl-Shift-J
; Mac系統則是Command-Option-J
)。 -
localStream.getVideoTracks()
返回的是什麼值呢? - 檢視 constraints 物件: 如果設定為
{audio: true, video: true}
, 有什麼效果呢? - video 元素的大小是多少? 如何通過JavaScript獲得視訊的原生尺寸? 而不是僅僅獲取顯示出來的尺寸? 嘗試使用 Chrome開發工具來檢視相關API。
- 嘗試對 video 元素新增 CSS 過濾器。例如:
video { filter: blur(4px) invert(1) opacity(0.5); }
- 嘗試新增SVG過濾器。例如:
video { filter: hue-rotate(180deg) saturate(200%); }
知識點回顧
在本節課程中, 我們學到了:
- 從網路攝像頭獲取視訊。
- 設定媒體約束條件(media constraint)。
- 混合視訊元素。
本節的完整版程式碼位於 step-01
資料夾中。
- 記得設定
video
元素的autoplay
屬性。如果沒有設定, 則只能看到第一幀畫面! -
getUserMedia()
方法提供了很多可選引數, 請參考 https://webrtc.github.io/samples/src/content/peerconnection/constraints/ . 當然, 其中也有一些有趣的 WebRTC 示例。
最佳實踐
- 請確保 video 元素的內容不會溢位包裹容器。通過
width
和max-width
樣式可以設定 video 的預設尺寸、最大尺寸。 瀏覽器會自動計算對應的 height 屬性:
video { max-width: 100%; width: 320px; }
後續內容
既然獲取到了 video, 那要如何使用呢? 我們將在下一小節講解!
原文連結: https://codelabs.developers.google.com/codelabs/webrtc-web/#3
翻譯人員: 鐵錨 - https://blog.csdn.net/renfufei
翻譯日期: 2018年07月04日