iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 5
0

學習目標

本章你將會了解到:

  • getUserMedia 包含哪些功能
  • 如何使用getUserMedia來擷取本機影音流(Video/Audio streams)

簡介

var promise = navigator.mediaDevices.getUserMedia(constraints);

透過mediaDevices.getUserMedia,會提示使用者是否給予存取多媒體數據的許可,同意後會產生MediaStream物件,裡面包含了請求的存取的多媒體數據,例如:視頻(透過本機內建的視訊鏡頭或是外接裝置等),音頻(透過本機內建的麥克風或是外接裝置等)。

並且會回傳Promise物件,但該API所回傳的promise可能不會resolve或是reject,取決於使用者行為,可能沒有允許也沒拒絕!
使用上可能就要注意到,並針對流程進行處理。

constraints :

該參數是基於MediaStreamConstraints物件,
用於指定存取的多媒體數據的類型及相關參數。

先來看看基本範例:

// 同時請求不帶任何參數的音頻和視頻:
{ audio: true, video: true }

注意: 該參數包含video與audio兩種類型,可以單純指定其一或如範例同時指定兩種類型,但不能完全都不指定!
當沒有指定任一時或是瀏覽器不支援參數的設定等,會拋出promise.reject返回失敗的狀態。

進階一點的話,如指定視頻畫素:

{
  video: { width: 1280, height: 720 }
}

更多細節可以看看:MDN文件


實作範例

在html上加上video tag

<!-- index.html -->
<video autoplay></video>

透過getUserMedia來取得多媒體數據流

// 這邊我們單純只想取得video
const mediaStreamConstraints = {
  video: true
};

function handleMediaStreamError(error) {
  console.log('navigator.getUserMedia error: ', error);
}

function gotLocalMediaStream(mediaStream) {
  // console.log(mediaStream)
  const localStream = mediaStream;

  // 取的video html element( HTMLMediaElement ).
  const localVideo = document.querySelector('video');
  // Older browsers may not have srcObject.
  if ("srcObject" in localVideo) {
    localVideo.srcObject = localStream;
  } else {
    // Avoid using this in new browsers, as it is going away.
    localVideo.src = window.URL.createObjectURL(localStream);
  }
}

navigator.mediaDevices
  .getUserMedia(mediaStreamConstraints)
  .then(gotLocalMediaStream)
  .catch(handleMediaStreamError)

Try it

在瀏覽器上打開你的index.html,結果應該會如下圖所示:

https://ithelp.ithome.com.tw/upload/images/20200918/20129521l96Hxh273X.png


實作講解

本次實作主要就是透過navigator.mediaDevices.getUserMedia(),來取得使用者的同意,
如果同意的話,將會回傳MediaStream object,裡面會包含從webcam拿到影音流資料,並透過Javascript來操作。

navigator.mediaDevices
  .getUserMedia(/** setting media constraints */)
  .then(/** handle Success */)
  .catch(/** handle Error */)

取的MediaStream object後,可以利用HTMLMediaElement.srcObject屬性,將其顯示在網頁上。

function gotLocalMediaStream(mediaStream) {
  const localStream = mediaStream;
  const localVideo = document.querySelector('video');

  if ("srcObject" in localVideo) {
    localVideo.srcObject = localStream;
  } else {
    localVideo.src = window.URL.createObjectURL(localStream);
  }
}

注意: 因為srcObject屬性的支援度還沒有很全面,如果再沒有支援的情況下,必須用URL.createObjectURL()轉換後賦值給HTMLMediaElement.src

補充

實作後試想一下幾個蠻好奇的地方:

  • consolemediaStream object,裡面究竟存了哪些資料或提供了哪些api能夠使用。
  • 如果改變constraints的設定後,會產生怎樣的變化。
const mediaStreamConstraints = {
  video: {
    width: {min: 1280},
    height: {min: 720}
  }
};

總結

本章節了解到:

  • 如何使用getUserMedia來存取多媒體數據流
  • 設定constraints的功用
  • 如何透過HTMLMediaElement的屬性將video stream顯示到網頁上
新手入門,如有錯誤,歡迎指正~~~

系列文章同步更新於部落格


上一篇
[知識篇]WebRTC - JavaScript APIs
下一篇
[知識篇]MediaStreams API - getUserMedia 相容性處理
系列文
菜雞前端邁入網頁即時通訊(WebRTC)之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
gjlmotea
iT邦研究生 5 級 ‧ 2022-03-01 17:36:59

非常感謝教學

補充一下:
MDN的網址有更改過,現在只找到英文版

另外在本地端127.0.0.1測試上沒有問題
但部署到遠端機器上,若是http協定的話會出現
(index):7 Uncaught TypeError: Cannot read properties of undefined (reading 'getUserMedia')的錯誤

可以透過 Chrome 調整安全性Flag來解決

而https則無上述問題,可透過部署在https上來解

我要留言

立即登入留言