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