【 PeerJS 】リアルタイムビデオ通話のデモ実装編(3) - カメラ映像をストリーミング

#初めに
_本稿は、「PeerJSを使ったリアルタイムビデオ通話のデモを実装してみたシリーズ」のPART(3)である。_

- [PeerJSを使ったリアルタイムビデオ通話のデモを実装してみた話(1) - mediaDevices.getUserMedia()の使い方](http://qiita.com/Futo23/items/3f7a750e3b06cd2dfe6b)
- [PeerJSを使ったリアルタイムビデオ通話のデモを実装してみた話(2) - PeerJS疎通確認](http://qiita.com/Futo23/items/1c840895e8bb0e36a7ff#_reference-5ad63be3f33402afeca8)
- __PeerJSを使ったリアルタイムビデオ通話のデモを実装してみた話(3) - カメラ映像をストリーミング__

前回までの記事では、テキストデータの授受までを記載しました。

今回は、さらにもう一歩踏み込んで、__カメラ映像のリアルタイムストリーミング(デモ)__を実装してみようと思います。

#リアルタイムストリーミング(デモ)実装手順
1. カメラ映像にアクセスし、ストリームデータを取得する。
2. 双方でのコネクションを確立する。
3. ```2.``` で取得したカメラ映像を相手に送る。

##1. カメラ映像にアクセスし、ストリームデータを取得する。
>相手のPeerIDを指定して```peer.call```を実行することで、その相手を呼び出すことができます。
※相手を呼び出す時、または、呼び出しに応答する時には、MediaStreamを提供する必要があります。
[Skyway - 公式ドキュメント](https://nttcom.github.io/skyway/docs/)

ソースコードは、以下の通り。

```sample.html
<script type="text/javascript">
　let localVideo;

  // カメラ、オーディオ等のリソースへアクセス
  navigator.mediaDevices.getUserMedia({video : true, audio : true})
  .then(function (stream) {
    // カメラ、オーディオリソースへのアクセス成功時
    // 変数videoStreamに取得したストリームデータを代入
　　localVideo = stream;
  }).catch(function (error) {
　  // カメラ、オーディオリソースへのアクセス失敗時
　　// エラー内容をコンソール出力する。
    console.log(error);
  });
</script>
```

##2. 双方でのコネクションを確立します。

__[呼び出す側]__

```caller.js
// mediaStreamは自端末のカメラ映像(ストリーミングデータ)
let call = peer.call('reciverId',mediaStream)
```

__[呼び出される側]__

```callee.js
peer.on('call',function(call){
 // mediaStreamは自端末のカメラ映像(ストリーミングデータ)
 call.answer(mediaStream);
});
```


<font color="red">__[※重要]__</font>
相手を呼び出す時、または、呼び出しに応答する時には、__MediaStream__を提供する必要があります。

##3. ```2.``` で取得したカメラ映像を相手に送る。

続いて、```navigator.mediaDevices.getUserMedia()```を使用して、端末のカメラ映像にアクセスします。

ソースコードは、以下の通り。

__[呼び出し側]__

```caller.html
<!DOCTYPE html>
<head>
  <meta charset="UTF-8">
  <title>sample</title>
  <script src="http://cdn.peerjs.com/0.3/peer.js"></script>
</head>
<body>
  <video id="local_video" autoplay></video>
  <video id="remote_video" autoplay></video>
</body>

  <script type="text/javascript">

    let localVideo = document.getElementById('local_video');
    let RemoteVideo = document.getElementById('remote_video');

    let peer = new Peer('senderId',{key : 'we074c3o2tv2huxr'});

    navigator.mediaDevices.getUserMedia({video : true, audio : true})
    .then(function (stream) {
      // カメラ映像、オーディオへのアクセスが成功した場合
      // 取得したカメラ映像を相手に送ります。
      localVideo.srcObject = stream;
      let call = peer.call('reciverId',stream);
      if (call != null) {
        call.on('stream', function(stream) {
               // ストリーミングデータ受信処理
               RemoteVideo.srcObject = stream;
        });
      }
    }).catch(function (error) {
      // カメラ映像、オーディオへのアクセスが失敗した場合
      // エラーの内容をconsole.logで出力します。
      console.log(error);
    });

  </script>
</html>
```


__[呼び出される側]__

```callee.html
<!DOCTYPE html>
<head>
  <meta charset="UTF-8">
  <title>sample</title>
  <script src="http://cdn.peerjs.com/0.3/peer.js"></script>
</head>
<body>
  <video id="local_video" autoplay></video>
  <video id="remote_video" autoplay></video>
</body>

  <script type="text/javascript">

    let localVideo = document.getElementById('local_video');
    let RemoteVideo = document.getElementById('remote_video');

    let peer = new Peer('reciverId',{key : 'we074c3o2tv2huxr'});

    peer.on('call', function(call){
      navigator.mediaDevices.getUserMedia({video : true, audio : true})
      .then(function (stream) {
        // カメラ映像、オーディオへのアクセスが成功した場合
        // 取得したカメラ映像を相手に送ります。
        localVideo.srcObject = stream;
        call.answer(stream);
        call.on('stream', function(stream) {
           // ストリーミングデータ受信処理
           RemoteVideo.srcObject = stream;
        });

      }).catch(function (error) {
        // カメラ映像、オーディオへのアクセスが失敗した場合
        // エラーの内容をconsole.logで出力します。
        console.log(error);
      });
    });

  </script>
</html>
```

#検証してみる。(手順)
1. まず、最初に__<font color="red">呼び出される側</font>__のhtmlファイルをブラウザで確認
2. __<font color="red">呼び出し側</font>__のhtmlファイルをブラウザで確認  
→カメラ、オーディオ等のリソースへのアクセス許可を求められる (許可)
3. __<font color="red">呼び出される側</font>__も同様に許可をする。
4. 双方向間で通信ができていることが確認できる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/50dd4370-48c3-87f0-7396-02c06e757240.png)

このような形で表示されれば、成功です。

実際、少し遅延が発生して違う表情になってますｗ


#終わりに
見た目は悪いですが、ざっと__PeerJSを使ったリアルタイムビデオ通話(?)__のようなものが作れました。
もちろんサービスにするには、まだまだほど遠いですが、デモを実装する中で、
自分自身、WebRTCへの知見が深まったように思います。

最後までお読みいただき、誠にありがとうございました。
また、つたない文章の記事ですが、__「いいね」__を押していただきましたみなさま、
本当にありがとうございます。

本連載は、これにて終了させていただきますが、
3つの記事に関しては、これからも随時アップデートを行っていく予定ですので、
もし何かございましたらコメントいただけますと幸いです。

以上。