html5調用攝影機截圖

關於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,機器學習,模式識別,大把的應用場景。