タケユー・ウェブ日報

Ruby on Rails や Flutter といったWeb・モバイルアプリ技術を武器にお客様のビジネス立ち上げを支援する、タケユー・ウェブ株式会社の技術ブログです。

JavaScript (TypeScript) でビデオキャプチャーからの映像を表示したり、スナップショットを取ったりしたい!

前回はJavaScript(TypeScript)で「デスクトップや他のウインドウ」を表示しました。

blog.takeyuweb.co.jp

今回は、USBビデオキャプチャー Mirabox HDMI ビデオキャプチャー HSV321 を買ったので、

f:id:uzuki05:20200612224819p:plain

  • Switch のゲームプレイ画面をブラウザ上に表示
  • 任意のタイミングでスナップショットを撮影して表示

してみました。

サンプル

See the Pen getUserMedia by Yuichi Takeuchi (@takeyuweb) on CodePen.

getUserMedia

USBビデオキャプチャーからの映像は、ブラウザからはWebカメラと同じように扱えます。 従って getUserMedia を使うことで簡単に取得することができます。

developer.mozilla.org

captureStream = await navigator.mediaDevices.getUserMedia({video: { deviceId: getSelectedVideo(), width: 1920, height: 1080 }, audio: {deviceId: getSelectedAudio()}});
const video = document.createElement("video");
video.autoplay = true;
video.srcObject = captureStream;
videoContainer.appendChild(video);

バイスの選択

// 先に許可を貰わないとenumerateDevicesが返すデバイス名(label)を取得できない
await navigator.mediaDevices.getUserMedia({video: true, audio: true});
const devices = await navigator.mediaDevices.enumerateDevices();
devices.forEach((device) => {
  console.log(device.kind + ": " + device.label + " id = " + device.deviceId);
  const option = document.createElement("option");
  option.text = device.label;
  option.value = device.deviceId;

  if (device.kind === "audioinput") {
    audioDeviceSelect.appendChild(option);
  } else if (device.kind === "videoinput") {
    videoDeviceSelect.appendChild(option);
  }
});

const getSelectedVideo = () => {
  return videoDeviceSelect.value;
}

const getSelectedAudio = () => {
  return audioDeviceSelect.value;
}

今回、私はMiraBoxで決め打ちだったので雑に書くとこんな感じになりました。

const deviceLabel = 'MiraBox'; 
let miraVideoId:string;
let miraAudioId:string;

await navigator.mediaDevices.getUserMedia({video: true, audio: true});
const devices = await navigator.mediaDevices.enumerateDevices();
devices.forEach((device) => {
  console.log(device.kind + ": " + device.label + " id = " + device.deviceId);
  if (device.kind === "audioinput") {
    if (device.label.match(deviceLabel)) {
      miraAudioId = device.deviceId;
    }
  } else if (device.kind === "videoinput") {
    if (device.label.match(deviceLabel)) {
      miraVideoId = device.deviceId;
    }
  }
});