【 PeerJS 】リアルタイムビデオ通話のデモ実装編(1) ～mediaDevices.getUserMedia()の使い方～

#はじめに
<u>昨今、スマートグラス業界を賑わせている__「遠隔作業支援サービス」__の 技術要素</u>である
__<font color="red">「WebRTC(Web Real-Time Communication)」</font>__について、簡易なデモの実装を通じて、
WebRTCへの理解を深めたいと思います。

_※こちらの記事は、<font color="teal">「 WebRTC初心者向けの記事 」</font>になりますので、
記載内容の技術レベルは低めですが、何卒ご容赦いただけますと幸いです。_

__そもそもWebRTCとは？__的な話は、[こちらの記事](http://qiita.com/Futo23/items/1afef27ae78170de6f02)をご参照ください。

#対象読者
- __「WebRTC」__に興味はあるが、そこまで深く理解していない方
- __「WebRTC」__という言葉は知っているが、どのような技術かあまり詳しく知らない方

#実装内容(簡易デモ)
今回は、__PC__と__スマートグラスとの間__で__<font color="red">リアルタイムビデオ通話</font>__(っぽいもの？)を実装してみます。

上記デモを実現するためには、下記の機能を実装する必要があります。

>__1.__ 端末自体のカメラ映像を取得する機能
__2.__ PeerJSサーバーを用いて、コネクションをはる機能(疎通確認)
__3.__ 2.で確立したコネクションを元に、動画をストリーミング配信する機能

一つずつ、順を追って実装していきましょう。

<font color="red">__Haste makes waste!__</font> (急がば回れ!)

#1. 端末自身のカメラ画像を取得する。

端末自身のカメラ映像を取得するには、```navigator.mediaDevices.getUserMedia()```を使用します。

昔から知識がある人であれば、```navigator.getUserMedia()```の間違いじゃないか？
と思われる方もいっらしゃるかと思いますが、[ MOZILLA ](https://developer.mozilla.org/ja/docs/Web/API/Navigator/getUserMedia)のサイトを見てみると、、。

>![getUserMedia.png](https://qiita-image-store.s3.amazonaws.com/0/180432/24408870-1882-9c88-e750-fead3591eac3.png)

>__Navigator.getUserMedia - (非推奨)__
この機能はWeb標準から削除されました。まだサポートしているブラウザがあるかもしれませんが、
ゆくゆくはなくなるものです。新旧にかかわらず、プロジェクトでの使用をやめてください。
この機能を使用するページ、Webアプリはいつ動かなくなってもおかしくありません。

>[Navigator.getUserMedia(Web標準)の廃止について](http://qiita.com/Futo23/items/bff1ce1d2e1b219b243d)

__じゃあ、どうすれば良いの？__
<font color="red">__A. [navigator.mediaDevices.getUserMedia()](https://developer.mozilla.org/ja/docs/Web/API/MediaDevices/getUserMedia) を使用します。__</font>

詳しくは、[こちらの記事](http://qiita.com/Futo23/items/bff1ce1d2e1b219b243d)をご覧ください。

##実際のソースコード

```sample1.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>sample1</title>
</head>
<body>
    <video id="local_video" autoplay style = "width : 900px; height : 600px;">
</body>
    <script type="text/javascript">
      let localVideo = document.getElementById('local_video');

      // Start local video
      navigator.mediaDevices.getUserMedia({video : true, audio : false})
      .then(function (stream) {
        localVideo.srcObject = stream;
      }).catch(function (error){
        console.error('mediaDevices.getUserMedia() error:', error);
        return;
      });
    </script>
</html>
```

上記のサンプルコードを見ていきましょう。

_※ 初心者が躓きそうなポイントをPickUpして解説していきます。_

##1. [videoタグ](http://www.htmq.com/html5/004.shtml)

```<video id="local_video" autoplay style...>```

>HTML5では、任意の動画フォーマットを文書に埋め込むための<video>タグが追加されました。
このタグを使用することで、<font color="red">__ユーザーにプラグインをインストールしてもらうことなく__</font>、HTMLからシンプルに動画を扱えるようになります。

__[autoplay属性]__
autoplay属性を指定すると、ウェブページを読み込んだ時点で、動画が再生されます。

##2. [document.getElementById('id名')](https://developer.mozilla.org/ja/docs/Web/API/Document/getElementById)

>指定されたidを持つ要素を返します。

上記のソースコードの場合、videoの要素を取得することができます。


_※もし、与えられた「 id 」をもつ要素が存在しなかった場合は、「 null 」が返ってきます。_

##3. [navigator.mediaDevices.getUserMedia()](https://developer.mozilla.org/ja/docs/Web/API/MediaDevices/getUserMedia)

>MediaDevices.getUserMedia()メソッドは、カメラやスクリーンシェアリング、マイクのようなビデオやオーディオ入力装置の使用許可をユーザーに要求します。__ユーザーが許可を出した場合、返却された<font color="red">「Promise」</font>は結果として生成されたMediaStreamオブジェクトとして解決__されます。

簡単に言うと、デバイスのカメラ、オーディオの使用許可をユーザーに要求し、
ユーザーがそれを承認すれば、デバイスのカメラ、オーディオ等にアクセスが可能になります。

##4. [srcObject](https://developer.mozilla.org/ja/docs/Web/API/HTMLMediaElement/srcObject)

>HTMLMediaElement.srcObjectは、HTMLMediaElementのプロパティです。
静的ファイルではなく、例えば、ローカルカメラの映像を表示したい時に、
リソースのオブジェクトをセットするためのプロパティです。
[「TMLMediaElement.srcObject - メディアプロバイダーより抜粋」](https://syncer.jp/Web/API_Interface/Reference/IDL/HTMLMediaElement/srcObject/)

もう一度、ソースコードを見てみましょう。


```sample1.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>sample1</title>
</head>
<body>
    <!-- videoタグ使用 autoplay属性を指定しているので、ユーザーがリソースへのアクセスを許可すると自動的に再生される。 -->
    <video id="local_video" autoplay style = "width : 900px; height : 600px;">
</body>
    <script type="text/javascript">
      // video要素を取得し、変数に代入します。
      let localVideo = document.getElementById('local_video');

      // カメラ、オーディオ等のリソースへのアクセスの許可が下りれば、
      navigator.mediaDevices.getUserMedia({video : true, audio : false})
      .then(function (stream) {
　　　　 // videoタグの箇所へ、カメラの映像を挿入します。
        localVideo.srcObject = stream;
      }).catch(function (error){
        // もし許可されなかった場合、エラーの場合にはエラーログを表示します。
        console.error('mediaDevices.getUserMedia() error:', error);
        return;
      });
    </script>
</html>
```

実際に、実行してみると、、。

__[許可前]__

リソースにアクセスしても問題ないかどうかアラートが上がります。(Google Chrome)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/b743f091-2c34-46ba-9805-2ea71e0c214e.png)


__[許可後]__

ブラウザ閲覧中のPCカメラが起動し、映像がvideoタグ内にリアルタイムで配信されることが確認できました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/4c2d73cb-96cb-bef2-f1d2-c6c23c15da81.png)

次は、PeerJSサーバーを用いてコネクションを確立する(疎通確認)を実装してみたいと思います。

続きは、
[1. PeerJSを使ったリアルタイムビデオ通話のデモを実装してみた話(2)](http://qiita.com/Futo23/items/1c840895e8bb0e36a7ff)
[2. PeerJSを使ったリアルタイムビデオ通話のデモを実装してみた話(3)](http://qiita.com/Futo23/items/c26167d48367f92fe1f3#_reference-4689df6b60c531fc0c0e)
をご覧ください。


#終わりに
実際に実装を進めながら、Qiitaに記事を書くと理解も深まりますね。
最後までお読みいただき、ありがとうございました。