如何在 PWA 中訪問相機

已發表: 2020-08-19

目錄

以前在我們詳細介紹 PWA 的硬件功能的文章中介紹過,攝像頭訪問是我們越來越多地看到的更突出的功能之一。 但是要將這種能力正確地集成到你的 PWA 中也不是一件容易的事,這就是為什麼在我們今天的文章中,我們將嘗試引導你完成整個過程:

先決條件

  • 可以使用 ReactJS 和我們的書面指南輕鬆創建的基本 PWA
  • 對 HTML 和 JavaScript 有紮實的理解

如何在 PWA 中訪問相機

基礎知識

介紹getUserMedia() — webRTC 的 API

為了直接訪問攝像頭和/或麥克風,Web 使用了一個名為getUserMedia()的 API,幾乎所有現代瀏覽器都廣泛支持該 API。 此 API 以及RTCPeerConnectionRTCDataChannel是 WebRTC 的一部分——WebRTC 是一個內置於瀏覽器中的框架,可以實現實時通信。

基本上,API ( navigator.mediaDevices.getUserMedia(constraints) ) 的作用是提示用戶允許訪問電話的音頻和視頻輸入(例如,麥克風、網絡攝像頭、攝像頭等)。 使用該權限,API 會生成一個名為localMediaStream 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(() =&gt; { 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 的新takePhotograbFrame方法可用於捕獲當前流視頻的快照。 兩種方法之間仍然存在顯著差異:

基本上, 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 解決方案。

探索 simicart PWA