html5呼叫攝像頭截圖

Jeff.Zhong發表於2021-12-26

關於html5呼叫音視訊等多媒體硬體的API已經很成熟,不過一直找不到機會把這些硬體轉化為實際的應用場景,不過近年來隨著iot和AI的浪潮,我覺得軟硬結合的時機已經成熟。那我們就提前熟悉下怎麼操作這些多媒體硬體吧,首先影像識別是其中最熱門的應用場景,首先實現呼叫攝像頭以及截圖。

demo的效果請看:攝像頭截圖

API相容性

核心的api就是navigator.MediaDevices,從caniuse可看出,PC端除了IE,已經沒多大問題。移動端新版本瀏覽器也支援,同時很多專案都已經轉向小程式,加上移動端一向緊跟最新標準,問題也不大。接著就是支援度就更好的video標籤。最後還有canvas,支援度就更加樂觀了。

硬體的獲取

使用到的api:enumerateDevices,它返回的是一個promise,結果就是裝置列表。裝置的物件屬性主要包括 deviceIdgroupIdkind。其中deviceIdgroupId 是裝置的標記,可以通過這兩個id呼叫所屬的硬體。而kind 顧名思義就是硬體型別了。有了enumerateDevices就可以遍歷硬體,同時可以實現選擇對應的硬體並呼叫。

//遍歷多媒體硬體
navigator.mediaDevices.enumerateDevices().then(function (devices) {
  console.log(devices);
  /*
  {
    deviceId: ""
    groupId: "8cac2d9a9e5d30a7bfc5a33b9971a3d40a850f7b0f6634b7f41f7dbe1de0a519"
    kind: "audioinput"
    label: ""
  } []
  */
});

呼叫攝像頭

接著開始呼叫對應的硬體,這裡會使用到另一個api,getUserMedia,同樣它返回的也是一個promise,結果是一個視訊流。有了視訊流就好辦了,把stream設定到videosrcObject,馬上一個視訊監控的應用就出來了。

getUserMedia的引數設定比較複雜,具體可參考MDN裡面的文件 getUserMedia,我這裡設定的是對應的攝像頭及視訊的尺寸。loadedmetadata事件在後設資料(metadata)被載入完成後觸發視訊播放。

// 呼叫攝像頭,並將流匯入video
navigator.mediaDevices.getUserMedia({ 
  video: { groupId, width: 800, height: 600 }
}).then(function (stream) {
    video.srcObject = stream;
    mediaTrack = stream.getTracks()[0];
    video.onloadedmetadata = function (e) {
      video.play();
    };
})
.catch(console.log);

視訊的截圖

最後就是擷取視訊畫面了,這就用到了canvasdrawImage,這個api不僅支援把canvas物件和image物件渲染進畫布,同時還支援video物件,這就完美解決了我們的需求,核心程式碼如下:

//寫入畫布,並轉換為base64
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
const imgURL = canvas.toDataURL('image/jpeg');

根據需求我們可以把圖片資料轉換為流或二進位制,我這裡轉換為base64,拿到了資料就可以發揮想象了,tensorflow,機器學習,模式識別,大把的應用場景。

相關文章