iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 9
0
Software Development

菜雞前端邁入網頁即時通訊(WebRTC)之旅系列 第 9

[實作篇]MediaStreams API - 基本應用(搭配canvas)

學習目標

  • 如何利用 getUserMedia API 實作簡單的canvas應用

實作

接下來會展示一些簡單實作,
主要是熟悉能透過getUserMedia 取得 MediaStream 後,能夠做哪些應用。

注意: 因為getUserMedia在相容性上需要額外處理,這邊會利用Google包裝好的shim lib - adapter.js.來方便我們操作。


MediaStreamTrack 控制(停止/啟動/關閉)

<!-- index.html -->
<h1>基礎 getUserMedia 影音流播放控制</h1>
<hr>
<video autoplay></video>
<!-- 取得media stream -->
<button onclick="onCapture()">Capture</button>
<!-- 停止media stream -->
<button onclick="stopMedia()">Stop</button>

加上兩個Button,Capture按鈕負責重新啟用mediaStream,Stop按紐負責停止功能

加上adapter.js lib

引入adapter.js幫我們處理好相容性問題,方便主程式操作getUserMedia。

<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<!-- 主要程式 -->
<script src="./js/main.js"></script>

實作主程式

// ./js/main.js
const video = document.querySelector('video');
const constraints = {
  audio: false,
  video: true
};

function handleSuccess(stream) {
  window.stream = stream; // 方便可以在瀏覽器console
  video.srcObject = stream;
}

function handleError(error) {
  console.log('navigator.MediaDevices.getUserMedia error: ', error.message, error.name);
}

function onCapture () {
  navigator.mediaDevices.getUserMedia(constraints).then(handleSuccess).catch(handleError);
}

function stopMedia () {
  if (window.stream) {
    const videoStreams = window.stream.getVideoTracks()

    videoStreams.forEach(stream => {
      stream.stop() // 停止所有media stream
    });

    // 釋放資源
    video.src = video.srcObject = null;
  }
}

onCapture ()

try it

試試看,顯示畫面以及停止功能!

延伸思考:

  • stream.stop()換成stream.enabled = false會有什麼差異呢?

但在嘗試前記得要先將video.srcObject = nullmark起來。

// video.src = video.srcObject = null;

對 MediaStreamTracks object不熟的話,可以先觀看[知識篇]MediaStreams API - MediaStreamTrack Object


Screenshots With Canvas

提醒: 部分code會延續上面,這邊就會略過。

搭配canvas 來做視訊截圖

這次的index.html將會如下:

<div id="screenshot">
  <h1>搭配 Canvas 做視訊截圖功能</h1>
  <hr>
  <video autoplay></video>
  <button id="screenshot-button">Screenshot Button</button>
  <canvas></canvas>
  <!-- 也能將canvas轉成image data -->
  <img src="">
</div>
<!-- ... -->

透過Screenshot Button綁定click event,讓canvas渲染事件觸發當下的影格內容。

// ./js/main.js
const screenshotButton = document.querySelector('#screenshot-button');
const img = document.querySelector('#screenshot img');
const video = document.querySelector('#screenshot video');
const canvas = document.querySelector('canvas');

screenshotButton.onclick = video.onclick = function () {
  canvas.width = video.videoWidth;
  canvas.height = video.videoHeight;
  // 渲染
  canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
  
};

// ...

延伸思考:

  • 嘗試利用canvas搭配img src來顯示截圖。
// 轉成image data
img.src = canvas.toDataURL('image/png');

總結

本章節了解到:

  • 操作 MediaStream object。
  • 如何搭配Canvas。
  • 除了利用Canvas的2D渲染api drawImage
    將影格內容繪製出來外,也能將其利用toDataURL api 轉為data URI,
    就能利用image element渲染出來。
新手入門,如有錯誤,歡迎指正~~~

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


上一篇
[知識篇]MediaStreams API - MediaStreamTrack Object
下一篇
[實作篇]MediaStreams API - 基本應用(搭配CSS filter)
系列文
菜雞前端邁入網頁即時通訊(WebRTC)之旅30

尚未有邦友留言

立即登入留言