VueとSkyWayAPIで1対1の通話機能を実装する

[SkyWayAPIのチュートリアル](https://webrtc.ecl.ntt.com/documents/javascript-sdk.html)をVueを使って実装しました。
(2020年8月29日時点で動きます。)

# この記事で説明しないこと
- vue-cliを使ったプロジェクトの作り方
- SkyWayAPIのAPIキーの発行方法

# 各種バージョン

- skyway-js: ^3.0.2 
- vue: ^2.6.11


# 実装
```vuejs
:App.vue
<template>
  <div>
    <video @loadeddata="onLoadedData" :srcObject.prop="myStream" id="my-video" width='400px' autoplay muted playsinline></video>
    <p id="my-id">{{ peerId }}</p>

    <textarea id="their-id" v-model="theirId"></textarea>
    <button id="make-call" @click="makeCall">発信</button>
    <video @loadeddata="onLoadedData" :srcObject.prop="theirStream" id="their-video" width="400px" autoplay muted></video>
  </div>
</template>

<script>
import Peer from 'skyway-js'
import { APIKEY } from '../key';
export default {
  name: 'Home',
  data() {
    return {
      // 自分の通話上のID
      peerId: "",

      // 相手のID
      theirId: "",

      // 自分のカメラ情報
      localStream: null,

      // Peerインスタンス用
      peer: null,

      // 通話をかける際に必要
      mediaConnection: null,

      // 自分のカメラ情報
      myStream: null,

      // 相手のカメラ情報
      theirStream: null,
    }
  },
  created() {
    // ユーザーのカメラと音声情報を取得
    navigator.mediaDevices.getUserMedia({ video: true, audio: true })
      .then(stream => {
        this.myStream = stream
        this.localStream = stream;
      }).catch(error => {
        console.error(error);
        return;
      })

    // インスタンスの初期化
    this.peer = new Peer({
      key: APIKEY, //自身のAPIキー
      debug: 3,
    })

    // サーバーに接続できたときに発火
    this.peer.on('open', () => {
      this.peerId = this.peer.id;
    })
    // 通話がかかってきたときに発火する
    this.peer.on('call', mediaConnection => {
      mediaConnection.answer(this.localStream);
    })
  },
  methods: {
    // 通話の開始
    makeCall() {
      // 相手のIDと自分のカメラ情報を渡して通話開始
      this.mediaConnection = this.peer.call(this.theirId, this.localStream);
      // メディア情報を取得したときに発火
      this.mediaConnection.on('stream', stream => {
        this.theirStream = stream;
      })
    },
    // カメラ情報を取得できたら、描画。
    onLoadedData(event) {
      event.target.play();
    },
  },
}
</script>

```

# 重要な部分
```javascript
// インスタンスの初期化
this.peer = new Peer({
   key: APIKEY, //自身のAPIキー
   debug: 3,
})

// サーバーに接続できたときに発火
 this.peer.on('open', () => {
   this.peerId = this.peer.id;
 })
```
SkyWayAPIを使うためにはPeerクラスを初期化する必要があるらしい。
初期化してサーバーに接続が成功すると、idが生成され、これを使って他人に通話をかけることが出来る。

```javascript
// 通話がかかってきたときに発火する
this.peer.on('call', mediaConnection => {
  mediaConnection.answer(this.localStream);
})

// 相手のIDと自分のカメラ情報を渡して通話開始
this.mediaConnection = this.peer.call(this.theirId, this.localStream);

// メディア情報を取得したときに発火
this.mediaConnection.on('stream', stream => {
  this.theirStream = stream;
})
```
mediaConnectionってやつがカメラなどのデバイスの情報を司ってるので、自分のカメラ情報を渡すと相手に渡してくれたり、相手のメディア情報を取得したときにイベントを発火してくれたりする。

# 結果
2窓にしてフォームにお互いのIDを入力してあげると、描画してくれます。
![スクリーンショット 2020-08-29 23.20.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352602/f85050c6-3193-8f1d-3ea9-698259a6d4d4.png)


# 参考文献

- [SkyWayAPIのチュートリアル](https://webrtc.ecl.ntt.com/documents/javascript-sdk.html)
- [vue.jsで複数のvideoタグを扱う](https://qiita.com/dbgso/items/271d903237b41dffcc6d)
- [MediaDevices.getUserMedia()](https://developer.mozilla.org/ja/docs/Web/API/MediaDevices/getUserMedia)