在這篇文章中,我將向您展現如何經過JavaScript在網頁上訪問設備的攝像頭,並支持多種瀏覽器,而無需外部庫。javascript
要訪問用戶的相機(或麥克風),咱們使用JavaScript MediaStream API。該API容許經過流訪問這些設備捕獲的視頻和音頻。html
第一步是檢查瀏覽器是否支持此API:前端
if (
"mediaDevices" in navigator &&
"getUserMedia" in navigator.mediaDevices
) {
// ok, 瀏覽器支持它
}
複製代碼
在現代瀏覽器中,支持是不錯的(固然沒有Internet Explorer)。java
要捕獲由攝像機生成的視頻流,咱們使用 mediaDevices
對象的 getUserMedia
方法。這個方法接收一個對象,其中包含咱們要請求的媒體類型(視頻或音頻)和一些要求。首先,咱們能夠經過 {video: true}
來獲取攝像機的視頻。canvas
const videoStream = await navigator.mediaDevices.getUserMedia({ video: true });
複製代碼
此調用將詢問用戶是否容許訪問攝像機。若是用戶拒絕,它將引起異常而且不返回流。所以,必須在 try/catch
塊內完成處理這種狀況。api
請注意,它返回一個Promise,所以您必須使用 async/await
或 then
塊。在Mac OS系統上還會彈出受權瀏覽器
點擊「好」,就能夠訪問電腦攝像頭了,控制檯輸出的 videoStream
對象以下async
咱們能夠經過傳遞有關所需分辨率以及最小和最大限制的信息來改善視頻的要求:ide
const constraints = {
video: {
width: {
min: 1280,
ideal: 1920,
max: 2560,
},
height: {
min: 720,
ideal: 1080,
max: 1440,
},
},
};
const videoStream = await navigator.mediaDevices.getUserMedia(constraints);
複製代碼
這樣,流以正確的寬度和高度比例進入,若是它是處於縱向模式的手機,則須要進行尺寸反轉。ui
既然有了流,咱們該如何處理?
咱們能夠在頁面上的 video
元素中顯示視頻:
// 頁面中有一個 <video autoplay id="video"></video> 標籤
const video = document.querySelector("#video");
const videoStream = await navigator.mediaDevices.getUserMedia(constraints);
video.srcObject = videoStream;
複製代碼
請注意 video
標籤中的自動播放屬性 autoplay
,沒有它,你須要調用 video.play()
才能真正開始顯示圖像。
默認狀況下,getUserMedia
將使用系統默認的視頻錄製設備。若是是有兩個攝像頭的手機,它使用前置攝像頭。
要訪問後置攝像頭,咱們必須在視頻規格中包括 faceModeMode:"environment"
:
const constraints = {
video: {
width: { ... },
height: { ... },
facingMode: "environment"
},
};
複製代碼
默認值爲 faceingMode:"user"
,即前置攝像頭。
須要注意的是,若是你想在已經播放視頻的狀況下更換攝像機,你須要先中止當前的視頻流,而後再將其替換成另外一臺攝像機的視頻流。
videoStream.getTracks().forEach((track) => {
track.stop();
});
複製代碼
你能夠作的另外一件很酷的事情是捕獲視頻的圖像(屏幕快照)。
你能夠在canvas上繪製當前視頻幀,例如:
// 頁面中有一個 <canvas id="canvas"></canvas> 標籤
const canvas = document.querySelector("#canvas");
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas.getContext("2d").drawImage(video, 0, 0);
複製代碼
你還能夠在 img
元素中顯示畫布內容。
在本教程建立的示例中,我添加了一個按鈕,該按鈕可從畫布動態建立圖像並將其添加到頁面:
const img = document.createElement("img");
img.src = canvas.toDataURL("image/png");
screenshotsContainer.prepend(img);
複製代碼
在線效果及源代碼:coding.zhangbing.site/view.html?u…
本文首發於公衆號 《前端全棧開發者》 ID:by-zhangbing-dev,第一時間閱讀最新文章,會優先兩天發表新文章。關注後私信回覆:大禮包,送某網精品視頻課程網盤資料,準能爲你節省很多錢!