[*WebRTC*] WebRTCの初心者向けハンズオンに参加してきた

# はじめに
WebRTCの存在自体は知っていてちょっとググったことがあるものの、
なんか難しそうだなぁ・・・いつか触ろう・・・と思っていました。

今回、たまたま[初心者向け！WebRTCプラットフォームハンズオン 第三回はAgora.io](https://webrtc.connpass.com/event/98121/)というイベントを発見したため参加してきました。

# WebRTCとは
W3Cが提唱している、リアルタイムコミュニケーションのための仕様です。
プラグイン無しにビデオ通話やボイス通話などができるそうです。
ここ→[WebRTC](https://webrtc.org/)に何やらまとめてあるのですが、
アーキテクチャを見ただけでウッてなります。

# Agora.ioとは
ビデオ通話やライブ配信など、リアルタイムコミュニケーションのためのSDKを提供しています。
これを使えばSDKを使って予め用意されたAPIを叩けば、
シグナリングサーバがどうのとかTURNサーバがどうのとかそういう目に見えない複雑な
部分のところは気にしなくてもビデオ通話アプリなどを作ることができます。

# ハンズオン
## スライド
↓↓　ハンズオン時のスライド
[Agora.ioWebRTCハンズオン[2018/11/18]](https://qiita.com/fu-jimoto/items/61fb7474ba6b1f4d6457)

## コード
[fu-jimoto/Agora-WebRTC-VideoCall](https://github.com/fu-jimoto/Agora-WebRTC-VideoCall)をもとにハンズオンを行う形式でした。

## API仕様
AgoraSDKのAPI仕様は[Agora Developer Center](https://docs.agora.io/en/?_ga=2.50914025.1365318995.1542517634-77184348.1542517634)から探せます。

## 作ったもの

```html
<!DOCTYPE html>
<html>

<head>
  <title>Agora Web Sample</title>
  <!-- 必要なスクリプトの読み込み -->
  <link rel="stylesheet" href="../common/vendor/bootstrap.min.css">
  <!-- AgoraSDK -->
  <script src="../common/AgoraRTCSDK-2.5.0.js"></script>
  <script src="../common/vendor/jquery.js"></script>
  <!-- AgoraSDKを使うためにAppIDが必要 -->
  <script src="../common/app_id.js"></script>
  <!-- 顔認識をして顔を黒く塗りつぶして見えなくしたり・・・なんてことができるライブラリ -->
  <!-- これはAgoraSDKに含まれるものではなく、また別のライブラリ。 -->
  <script src="../common/vendor/clmtrackr.js"></script>
  <script src="../common/vendor/model_pca_20_svm.js"></script>
  <style>
    #local_area {
      position: relative;
    }

    #overlay {
      transform: scaleX(-1);
      position: absolute;
      left: 0;
      top: 0;
    }
  </style>
</head>

<body>
  <div id="log"></div>
  <!-- 退出用ボタン・・・通話から退出するときに押す -->
  <button onclick="leave();">leave</button>
  <!-- 自分の映像・・・自分側のカメラの映像が表示されるエリア -->
  <div id="local_video" style="width:320px;height:240px;"></div>
  <!-- 他拠点の映像・・・通話に参加した相手側の映像が表示されるエリア -->
  <div id="agora_remote" style="width:320px;height:240px;"></div>
  <!-- 顔認識用・・・表示されているビデオ上に重ねるためのcanvas -->
  <canvas id="overlay" width="320" height="240"></canvas>

  <script language="javascript">
    var client, localStream;

    // 顔認識用の処理
    var video, canvas, ctx, tracker;
    function startTrack() {
      requestAnimationFrame(startTrack);
      var data = tracker.getCurrentPosition();
      if (data) {
        // console.dirxml(data)
        var x = data[1][0];
        var y = data[20][1];
        var w = data[13][0] - data[1][0];
        var h = data[7][1] - data[20][1];
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.fillRect(x, y, w, h);
      }
    }

    // Agoraクライアントを生成
    // liveにすることでNativeSDKとの接続が可能
    client = AgoraRTC.createClient({ mode: 'live', codec: 'h264' });

    // 他拠点が退出したときのイベントを受け取る
    client.on('peer-leave', function (evt) {
      var stream = evt.stream;
      if (stream) {
        stream.stop();
        $('#agora_remote' + stream.getId()).remove();
      }
    });

    // 他拠点がストリームをパブリッシュした通知を受け取る
    // 該当ストリーム情報を表示したくない場合など、サブスクライブしないようにしたら表示しないように、とかできる
    client.on('stream-added', function (evt) {
      var stream = evt.stream;
      client.subscribe(stream, function (err) { });
    });

    // サブスクライブした場合、画面に表示
    client.on('stream-subscribed', function (evt) {
      var stream = evt.stream;
      $('div#agora_remote').append('<div id="agora_remote' + stream.getId() + '" style="width:320px;height:240px;"></div>');
      stream.play('agora_remote' + stream.getId());
    });

    // クライアントの初期化処理
    client.init(app_id, function () {
      // ワンタイムトークンを発行して接続させるというセキュアな対応も可能（第1引数　・・・今回はワンタイムトーク無しでいけるように設定してあるため不要
      // 第2引数は部屋名みたいなもの。他の人とかぶると同じルームになる
      // uidは自分で指定して入れれば任意のものを指定できる
      client.join("", "sample_webrtc_room", null, function (uid) {
        // Agoraネットワークに接続成功すると実行される
        $("#log").html("connected");

        // カメラとマイクを準備する
        // デバイスの指定が可能、screen: trueにすると画面共有可能
        // getVideoProfileというAPIを叩いてサイズを変更可能 https://docs.agora.io/en/Video/API%20Reference/web/interfaces/agorartc.stream.html#setvideoprofile
        // setScreenProfileというAPIを使えば画面共有の画質を設定することができる
        // localStream = AgoraRTC.createStream({ streamID: uid, audio: true, video: true, screen: true, mediaSource: "screen" }); // 画面共有の場合のコード
        localStream = AgoraRTC.createStream({streamID: uid, audio: true, video:true, screen: false});
        // 初期化を実行したらカメラの接続とマイクの接続を許可するかのダイアログが表示された
        localStream.init(function () {
          // この状態ではAgoraネットワークには送って無くて単にローカル映像を表示しているだけ
          localStream.play("local_video")

          // Agoraから持ってきたVideo要素を取得
          video = document.getElementById("video" + uid);
          video.setAttribute('height', '240');
          video.setAttribute('width', '320');

          // 顔認識用の処理
          tracker = new clm.tracker();
          tracker.init(pModel);
          tracker.start(video);
          canvas = document.getElementById('overlay');
          ctx = canvas.getContext('2d');
          // 顔認識をスタート
          startTrack();

          // Agoraネットワークにパブリッシュ
          client.publish(localStream, function (err) { });
        }, function (err) {
          console.log('エラーが発生')
        });

      }, function (err) { });
    }, function (err) { });

    // 退出処理
    function leave() {
      client.leave(function () {
        if (localStream) {
          localStream.stop();
        }
      }, function (err) { });
    }
  </script>
</body>

</html>
```

## その他
AppIDは[Sign up for free](https://dashboard.agora.io/en/signup)からユーザー登録すれば、
月10,000分まではフリーで使えるようです。

# おわりに
自分でサーバーを立ててやるのはなかなか難しそうと感じたので、
こういった便利なAPIを使用するのが一番手っ取り早いと思いました。
短い時間でビデオ通話アプリが作れて楽しかったです。

# リンク情報まとめ
* [ハンズオンのスライド資料](https://qiita.com/fu-jimoto/items/61fb7474ba6b1f4d6457)
* [Agora開発用ドキュメント](https://docs.agora.io/en/?_ga=2.50914025.1365318995.1542517634-77184348.1542517634)
* [ハンズオンで使用したコード](https://github.com/fu-jimoto/Agora-WebRTC-VideoCall)