關於html5呼叫音視訊等多媒體硬體的API已經很成熟,不過一直找不到機會把這些硬體轉化為實際的應用場景,不過近年來隨著iot和AI的浪潮,我覺得軟硬結合的時機已經成熟。那我們就提前熟悉下怎麼操作這些多媒體硬體吧,首先影像識別是其中最熱門的應用場景,首先實現呼叫攝像頭以及截圖。
demo的效果請看:攝像頭截圖
API相容性
核心的api就是navigator.MediaDevices,從caniuse可看出,PC端除了IE,已經沒多大問題。移動端新版本瀏覽器也支援,同時很多專案都已經轉向小程式,加上移動端一向緊跟最新標準,問題也不大。接著就是支援度就更好的video標籤。最後還有canvas,支援度就更加樂觀了。
硬體的獲取
使用到的api:enumerateDevices,它返回的是一個promise,結果就是裝置列表。裝置的物件屬性主要包括 deviceId,groupId,kind。其中deviceId,groupId 是裝置的標記,可以通過這兩個id呼叫所屬的硬體。而kind 顧名思義就是硬體型別了。有了enumerateDevices就可以遍歷硬體,同時可以實現選擇對應的硬體並呼叫。
//遍歷多媒體硬體
navigator.mediaDevices.enumerateDevices().then(function (devices) {
console.log(devices);
/*
{
deviceId: ""
groupId: "8cac2d9a9e5d30a7bfc5a33b9971a3d40a850f7b0f6634b7f41f7dbe1de0a519"
kind: "audioinput"
label: ""
} []
*/
});
呼叫攝像頭
接著開始呼叫對應的硬體,這裡會使用到另一個api,getUserMedia,同樣它返回的也是一個promise,結果是一個視訊流。有了視訊流就好辦了,把stream設定到video的srcObject,馬上一個視訊監控的應用就出來了。
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);
視訊的截圖
最後就是擷取視訊畫面了,這就用到了canvas的drawImage,這個api不僅支援把canvas物件和image物件渲染進畫布,同時還支援video物件,這就完美解決了我們的需求,核心程式碼如下:
//寫入畫布,並轉換為base64
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
const imgURL = canvas.toDataURL('image/jpeg');
根據需求我們可以把圖片資料轉換為流或二進位制,我這裡轉換為base64,拿到了資料就可以發揮想象了,tensorflow,機器學習,模式識別,大把的應用場景。