9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ブラウザから取得したカメラの映像を、加工してキャプチャーする方法。

Posted at

目的

  • getUserMedia()で取得した映像を加工する。
  • 加工した映像をキャプチャーする。

概要

  • canvasを使って映像を加工する。
  • なんの役に立つかは僕の頭では見いだせなかったけど、技術として面白くて好き。

開発環境

  • OS: macOS Mojave 10.14.4
  • ブラウザ: Google Chrome 73.0.3683.103
  • エディター: Visual Studio Code 1.33.0
  • ローカルサーバー: Live Server(VSCode拡張機能)

対応ブラウザ

getUserMedia

スクリーンショット 2019-04-23 22.01.50.png 参照:[getUserMedia/Stream API](https://caniuse.com/#search=getusermedia)

canvas

スクリーンショット 2019-04-23 22.04.07.png 参照:[Canvas (basic support)](https://caniuse.com/#search=canvas)

ゴール

Kapture 2019-04-23 at 21.56.28 (2).gif

ソース

javascript

js/index.js
/*
 *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree.
 */

'use strict';

const snapshotButton = document.querySelector('button');
const filterSelect = document.querySelector('select#filter');

const video = window.video = document.querySelector('video');
const canvas = window.canvas = document.querySelector('canvas');
canvas.width = 480;
canvas.height = 360;

snapshotButton.onclick = function () {
  canvas.width = video.videoWidth;
  canvas.height = video.videoHeight;
  canvas.className = filterSelect.value;
  canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
};

filterSelect.onchange = function () {
  video.className = filterSelect.value;
};

const constraints = {
  audio: false,
  video: true
};

function handleSuccess(stream) {
  window.stream = stream;
  video.srcObject = stream;
}

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

navigator.mediaDevices.getUserMedia(constraints).then(handleSuccess).catch(handleError);

html

html/index.html
<!DOCTYPE html>
<!--
 *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree.
-->
<html lang="jp">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>getUserMedia() with canvas</title>
<link rel="stylesheet" href="style.css">
</head>
<body>

  <h1>webRTC - getUserMedia with canvas</h1>
  <video playsinline autoplay></video>
  <div>
    <label for="filter">フィルター: </label>
    <select id="filter">
      <option value="none">なし</option>
      <option value="blur">Blur</option>
      <option value="grayscale">Grayscale</option>
      <option value="invert">Invert</option>
      <option value="sepia">Sepia</option>
    </select>
    <button>撮影する</button>
  </div>
  <canvas></canvas>

<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script src="index.js" async></script>
</body>
</html>

css

css/style.css
.none {
    -webkit-filter: none;
    filter: none;
}
.blur {
    -webkit-filter: blur(3px);
    filter: blur(3px);
}
.grayscale {
    -webkit-filter: grayscale(1);
    filter: grayscale(1);
}
.invert {
    -webkit-filter: invert(1);
    filter: invert(1);
}
.sepia {
    -webkit-filter: sepia(1);
    filter: sepia(1);
}
button#snapshot {
    margin: 0 10px 25px 0;
    width: 110px;
}
video {
    object-fit: cover;
}

説明

javascript/index.js
const snapshotButton = document.querySelector('button');
const filterSelect = document.querySelector('select#filter');

const video = window.video = document.querySelector('video');
const canvas = window.canvas = document.querySelector('canvas');
  • 各種要素を取得する。
javascript/index.js
snapshotButton.onclick = function () {
  canvas.width = video.videoWidth;
  canvas.height = video.videoHeight;
  canvas.className = filterSelect.value;
  canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);

  filterSelect.onchange = function () {
    video.className = filterSelect.value;
  };
};
  • 撮影ボタンが押されたら、まずビデオのサイズを取得する。
  • その後、フィルターの値をcanvasにわたす。
  • canvasに描画するためにgetContext()を呼び出す。
  • canvas上に画像を表示させるためにdrawImage()を呼び出す。
javascript/index.js
const constraints = {
  audio: false,
  video: true
};

function handleSuccess(stream) {
  window.stream = stream;
  video.srcObject = stream;
}

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

navigator.mediaDevices.getUserMedia(constraints).then(handleSuccess).catch(handleError);
  • getUserMedia()を実行して、ブラウザからデバイスのカメラ映像を取得する。
  • getUserMedia()が成功したら、取得したmediaStreamをvideo要素のsrcにわたす。
  • 失敗したらブラウザのコンソールにエラーを表示する。

ひとこと

  • 何に使えるかわからないけど、見た目が変わるのは楽しい。

参考文献

Real time communication with WebRTC

9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?