如何在 PWA 中訪問相機
已發表: 2020-08-19目錄
以前在我們詳細介紹 PWA 的硬件功能的文章中介紹過,攝像頭訪問是我們越來越多地看到的更突出的功能之一。 但是要將這種能力正確地集成到你的 PWA 中也不是一件容易的事,這就是為什麼在我們今天的文章中,我們將嘗試引導你完成整個過程:
先決條件
- 可以使用 ReactJS 和我們的書面指南輕鬆創建的基本 PWA
- 對 HTML 和 JavaScript 有紮實的理解
如何在 PWA 中訪問相機
基礎知識
介紹getUserMedia() — webRTC 的 API
為了直接訪問攝像頭和/或麥克風,Web 使用了一個名為getUserMedia()的 API,幾乎所有現代瀏覽器都廣泛支持該 API。 此 API 以及RTCPeerConnection和RTCDataChannel是 WebRTC 的一部分——WebRTC 是一個內置於瀏覽器中的框架,可以實現實時通信。
基本上,API ( navigator.mediaDevices.getUserMedia(constraints) ) 的作用是提示用戶允許訪問電話的音頻和視頻輸入(例如,麥克風、網絡攝像頭、攝像頭等)。 使用該權限,API 會生成一個名為local的MediaStream JavaScript 對象,該對象可以進一步操作。
例子
比如說,我們有一個按鈕:
<button>露出我的臉</button>
並單擊哪個按鈕調用navigator.mediaDevices.getUserMedia()方法(無音頻輸入):
navigator.mediaDevices.getUserMedia({
視頻:真實
})哎呀,我們也可以瘋狂地使用約束:
navigator.mediaDevices.getUserMedia({
視頻: {
最小縱橫比:1.333,
最小幀率:30,
寬度:1280,
身高:720
}
}) 此外,我們可以在 video 對像中指定facingMode屬性,它告訴瀏覽器使用設備的哪個攝像頭:
{
視頻: {
...
面對模式:{
//使用後置攝像頭
確切的:'環境'
}
}
}或者
{
視頻 : {
…
//使用前置攝像頭
面對模式:'用戶'
}
}備註:
- API 僅在安全來源 (HTTPS) 上可用
- 要獲取當前設備上支持的約束列表,請運行:
navigator.mediaDevices.getSupportedConstraints()
複雜的部分
現在我們已經對基礎有了紮實的了解,讓我們繼續進行高級部分。 在這一部分中,我們將嘗試在 PWA 中創建一個按鈕,單擊該按鈕後,它會打開我們的相機並讓我們做進一步的工作。
創建[Get access to camera]按鈕
首先,讓我們從 index.html 中的<button>開始:
<button>訪問相機</button> <視頻自動播放></video> <script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
注:

- 自動播放用於告訴媒體流自動播放而不是在第一幀凍結。
- adapter-latest.js 是一個墊片,用於將應用程序與規範更改和前綴差異隔離開來。
通過單擊按鈕實時流式傳輸視頻
要在單擊按鈕時實時流式傳輸視頻,我們需要添加一個EventListener ,它會在發出click事件時調用:
document.querySelector('#get-access').addEventListener('click', async function init(e) {
嘗試 {
}
捕捉(錯誤){
}
}) 之後,它調用navigator.mediaDevices.getUserMedia()並使用設備的網絡攝像頭請求視頻流:
document.querySelector('#get-access').addEventListener('click', async function init(e) {
嘗試 {
常量流 = 等待 navigator.mediaDevices.getUserMedia({
音頻:假,
視頻:真實
})
常量 videoTracks = stream.getVideoTracks()
常量軌道 = videoTracks[0]
alert(`從 ${track.label} 獲取視頻`)
document.querySelector('video').srcObject = 流
document.querySelector('#get-access').setAttribute('hidden', true)
//視頻流在播放3秒後被track.stop()停止。
setTimeout(() => { track.stop() }, 3 * 1000)
} 捕捉(錯誤){
警報(`${error.name}`)
控制台.錯誤(錯誤)
}
})此外,如上文“基本”部分所述,您還可以為視頻流指定更多要求:
navigator.mediaDevices.getUserMedia({
視頻: {
強制:{ minAspectRatio: 1.333, maxAspectRatio: 1.334, facesMode: 'user'},
可選的: [
{ minFrameRate: 60 },
{ 最大寬度:640 },
{ 最大高度:480 }
]
}
},成功回調,錯誤回調);創建畫布
將<video>元素與<canvas>結合使用,您可以進一步處理我們的實時視頻流。 這包括執行各種效果的能力,例如應用自定義濾鏡、色度鍵控(又名“綠屏效果”)——所有這些都使用 JavaScript 代碼。
如果您想了解更多有關此內容的信息,Mozilla 編寫了有關使用畫布操作視頻的詳細指南,因此請不要忘記查看!
使用takePhoto()和grabFrame()捕捉畫布的快照
getUserMedia API 的新takePhoto和grabFrame方法可用於捕獲當前流視頻的快照。 兩種方法之間仍然存在顯著差異:
基本上, grabFrame所做的只是抓取下一個視頻幀——這是一種簡單且不那麼有效的拍照方法。 另一方面, takePhoto方法使用一種更好的捕獲幀的方法,即通過中斷當前視頻流來使用相機的“最高可用攝影相機分辨率”來捕獲 Blob 圖像。
在下面的示例中,我們將使用grabFrame方法將捕獲的幀繪製到canvas元素中:
var grabFrameButton = document.querySelector('button#grabFrame');
var canvas = document.querySelector('canvas');
grabFrameButton.onclick = grabFrame;
函數抓取幀(){
imageCapture.grabFrame()
.then(函數(imageBitmap){
console.log('抓取的幀:', imageBitmap);
canvas.width = imageBitmap.width;
canvas.height = imageBitmap.height;
canvas.getContext('2d').drawImage(imageBitmap, 0, 0);
canvas.classList.remove('隱藏');
})
.catch(函數(錯誤){
console.log('grabFrame() 錯誤:',錯誤);
});
} 在這個例子中,我們使用了takePhoto()方法:
var takePhotoButton = document.querySelector('button#takePhoto');
var canvas = document.querySelector('canvas');
takePhotoButton.onclick = 拍照;
// 從當前選擇的相機源中獲取一個 Blob 和
// 用 img 元素顯示它。
功能拍照(){
imageCapture.takePhoto().then(function(blob) {
console.log('拍照:', blob);
img.classList.remove('隱藏');
img.src = URL.createObjectURL(blob);
}).catch(函數(錯誤){
console.log('takePhoto() 錯誤:',錯誤);
});
}要了解上述方法的實際效果,我們建議使用 Simple Image Capture; 或者,PWA 媒體捕獲也是 PWA 中基本媒體捕獲功能的一個很好的例子。
結論
在本教程中,我們向您介紹了在 PWA 中實現相機功能的基礎知識和一些高級技巧。 其餘的只是您的想像力,以充分利用此功能。
對於希望開發下一代 PWA 支持的商店的 Magento 商家,在 SimiCart 中,我們根據您的需求提供完整的 PWA 解決方案。
