ブラウザ上にカメラプレビューを表示する

# 概要

- 以下のようにブラウザ上にカメラデバイスを利用してプレビューを表示します

[![カメラプレビューサンプル](https://takeshit.info/wp-content/uploads/2020/08/camera_preview.png "カメラプレビューサンプル")](https://takeshit.info/wp-content/uploads/2020/08/camera_preview.pnghttp:// "カメラプレビューサンプル")

## 使うもの

- [navigator.mediaDevices.getUserMedia](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia)
- カメラデバイス（Facetime HDカメラ、iPhoneバックカメラ、フロントカメラ等）
- ブラウザ（Chrome）
- videoタグ
- HTTPSでアクセスできる環境（これ重要）
    - ※ iPhone, Androidではssl環境下でないとカメラデバイスを利用できなくなっています
    - スマホで見る場合は必ずHTTPSで確認してください
    - APIリファレンスサイト上でもSecure context requiredの対象になっています

## 流れ

1. まずコード
1. 解説
1. まとめ

# まずコード

## 全貌なので多いです

```html
<!doctype html>
<html lang="ja">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">

    <title>Camera Preview!</title>
  </head>
  <body>
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
      <a class="navbar-brand" href="#">Camera Preview</a>
    </nav>

    <div class="container">
      <div class="row">
        <div class="col-lg-12">
          <h1>Hello Camera!</h1>
        </div>
      </div>
      <div class="row">
        <div class="col-lg-12">
          <!-- このvideoタグにカメラの映像を差し込みます -->
          <video class="w-100" src="" autoplay playsinline allowfullscreen></video>
        </div>
      </div>
    </div>

    <script type="text/javascript">
      const constraints = { audio: false, video: {
        // 任意の値を入れます。記述方法は多々あるので詳しくはドキュメントを参照してください
        // Facetime HDカメラはHD画質までなので、1270に設定しています
        // iPhoneであれば4032まで可能です
        width: 1270,
        // iPhoneなどの場合にenvironmentだとバックカメラ、userだとフロントカメラになります
        facingMode: "environment"
      }}

      navigator.mediaDevices.getUserMedia(constraints)
        .then(function(stream) {
          const video = document.querySelector('video');
          video.srcObject = stream
          video.onloadedmetadata = function(e) {
            video.play();
          };
        })
        .catch(function(err) {
          console.log(err.name + ": " + err.message);
        });
      </script>
  </body>

</html>
```

# 2. 解説

### html側

かなり簡単シンプルです。

```html
<!-- このvideoタグにカメラの映像を差し込みます -->
<video class="w-100" src="" autoplay playsinline allowfullscreen></video>
```

id属性をつけたほうが固いですね。
autoplayやplaysinlineなどのオプションはお好みで。
このvideoタグを元にさらにcanvasに書き出してopenCVなどで画像加工もできます。

### javascript側

javascriptはたったこれだけの記述でカメラのプレビューが取得できます。

```html
<script type="text/javascript">
  const constraints = { audio: false, video: {
    // 任意の値を入れます。記述方法は多々あるので詳しくはドキュメントを参照してください
    // Facetime HDカメラはHD画質までなので、1270に設定しています
    // iPhoneであれば4032まで可能です
    width: 1270,
    // iPhoneなどの場合にenvironmentだとバックカメラ、userだとフロントカメラになります
    facingMode: "environment"
  }}

  navigator.mediaDevices.getUserMedia(constraints)
    .then(function(stream) {
      const video = document.querySelector('video');
      video.srcObject = stream
      video.onloadedmetadata = function(e) {
        video.play();
      };
    })
    .catch(function(err) {
      console.log(err.name + ": " + err.message);
    });
</script>
```

最近は色々なブラウザでgetUserMediaがサポートされています。
以前は色々なベンダープレフィックスや実装方法で対応していました。IE以外の最新バージョンであればPC, スマホのほとんどのブラウザで利用可能です。
※ `navigator.getUserMedia()`は非推奨メソッドになっているので注意。

# まとめ

たったこれだけで簡単にプレビューが作成できると思います。
これを元にcanvasに書き出して写真をとっても良いですし、AudioとともにWebRTCに使っても良いかと思います。
ブラウザ上で使える便利な機能の基本なので抑えておいて損はないと思います。

素敵なブラウザライフを！