🧑‍💻

Agoraでweb会議システムを作ってみよう!

2021/03/01に公開

はじめに

最近何かとよく目にするClubhouse。そのClubhouseで使われているっぽいAgoraを今回使用し、web会議システム的なものを作ってみようという記事です。

Agoraとは

  • Agoraは、ネイティブアプリやWebサイトにビデオ通話やライブ配信をかんたんに実装できるSDKです。

特徴

  • WebRTCと互換性があり、P2P通信よりも安定しています。と書いてあるように、Agoraは、WebRTC互換の技術を使用しており、通信はP2PではなくAgoraのサーバを使うそうです。
    ただ、他のビデオ通話系のサービスである、ZoomやGoogle Meetなども全てサーバ経由なので、他のサービスと方式は同じようですね。
  • プライベートネットワークでサーバ間を繋ぐのが強みのサービスのようです。
  • 1000 人以上の配信(双方向通話)が可能のようです。(片方向のpush型ならより多くなるのではないか?)
  • 従量課金制だが、音声10,000 分/月の無料枠があるようで、クレジットカードの登録なしで利用できるようです。

やってみよう

アカウント作成

① まず、 https://agora.io にアクセスし、右上の「Get Started」をクリックしてください。
スクリーンショット 2021-02-04 9.41.45.png

② SMS認証があるので、必須項目を入力していく。
スクリーンショット 2021-02-04 9.43.08.png

③ コンソール画面に入ってみる。
スクリーンショット 2021-02-04 9.58.07.png

プロジェクトの作成

① 「new project」をクリックする
スクリーンショット 2021-02-04 9.58.07.png

② プロジェクトの名前を入力し、「Authentication Mechanism」を「Secured mode」を選択
スクリーンショット 2021-02-04 12.31.51.png

④ Project Managementから、作成したプロジェクトがあるか確認する
スクリーンショット 2021-02-04 12.34.40.png

⑤ で確認したプロジェクトの右側にある「edit」を選択する。
スクリーンショット 2021-02-04 12.43.03.png

⑥ App IDとApp Certificate(Primary Certificate)の項目の右側の目のところをクリックし、コピーする
=> これが認証情報になります。
スクリーンショット 2021-02-04 12.40.20.png

実装

  • 今回はvueを用いて、クライアント側の実装をしていこうと思います。
    事前にvue cliは入れていただければと思います。
    ① vue cliを入れていれば下記のコマンドvueのプロジェクトを作成できます。
vue create agora-poc

② npmを利用し、agora SDKをinstallします。

npm install agora-rtc-sdk

③ vue.config.jsファイルを作成し、下記のものをコピペする

portはなんでも良いのですが、hostは127.0.0.1でなければなりません。

module.exports = {
    devServer: {
        host: '127.0.0.1',
        port: 9999,
        disableHostCheck: true,
    },
};

④ 下記のものをHelloWorld.vueに貼り付ける
vueで動作させるために結構このコード頑張りました。w
また、ソースコードが汚いのは勘弁してください。。
(ちょろっと体験したかったため、リファクタを全くしていません。w)

<template>
  <div class="hello">
    <h1>
      Video Call<br><small style="font-size: 14pt;">Powered by Agora.io</small>
    </h1>
    <h4>Local video</h4>
    <div id="me"></div>
    <h4>Remote video</h4>
    <div id="container"></div>
  </div>
</template>

<script>
import AgoraRTC from 'agora-rtc-sdk'
export default {
  name: 'Helloworld',

  created() {
    let client = AgoraRTC.createClient({
      mode: "rtc",
      codec: "vp8",
    });

    let localStream = AgoraRTC.createStream({
      audio: true,
      video: true,
    });

    client.init("yourAppId");

    client.join("yourToken", "test", null, ()=>{
      localStream.init(()=>{
      localStream.play("me");
      client.publish(localStream, handleError);
      }, handleError);
      client.on("stream-added", function(evt){
        client.subscribe(evt.stream, handleError);
      });
      client.on("stream-subscribed", function(evt){
        let stream = evt.stream;
        let streamId = String(stream.getId());
        addVideoStream(streamId);
        stream.play(streamId);
      });
      client.on("stream-removed", function(evt){
        let stream = evt.stream;
        let streamId = String(stream.getId());
        stream.close();
        removeVideoStream(streamId);
      });
      client.on("peer-leave", function(evt){
        let stream = evt.stream;
        let streamId = String(stream.getId());
        stream.close();
        removeVideoStream(streamId);
      });
    }, handleError);
  }
}

const handleError = function(err){
  console.log("Error: ", err);
};

function addVideoStream(elementId){
  let streamDiv = document.createElement("div");
  streamDiv.id = elementId;
  streamDiv.style.transform = "rotateY(180deg)";
  streamDiv.style.width = "400px";
  streamDiv.style.height = "400px";

  document.getElementById("container").appendChild(streamDiv);
}

function removeVideoStream(elementId) {
  let remoteDiv = document.getElementById(elementId);
  if (remoteDiv) remoteDiv.parentNode.removeChild(remoteDiv);
}
</script>

<style scoped>
* {
  font-family: sans-serif;
}
h1,h4 {
  text-align: center;
}
#me {
  width: 400px;
  height: 400px;
  margin: 0 auto;
}
#me video {
  position: relative !important;
}
#container video {
  position: relative !important;
}

</style>

注意点1: 上記コードの下記の箇所には、手順の中でメモをしたAppIdを入れます。

client.init("yourAppId");

注意点2: 上記のコードの下記の箇所にはtokenを入れます。

client.join("yourToken", "test", null, ()=>{

tokenの発行は、プロジェクトのeditから下記の箇所を選択すると取得する画面に移動します。
スクリーンショット 2021-02-04 23.17.28.png

動作させてみよう!

tuxくんに出てきてもらいましょう! ちなみに画像の画質が悪いのは、かなり圧縮している為です。
output.gif

おわりに

ビデオ通話系だと他にZoomのSDKとかあったりすると思うので、そのうちそちらもやってみたいと思います。

参考

https://docs.agora.io/en/Voice/landing-page?platform=Web
https://zenn.dev/arahabica/articles/0f54f2cdb1a29d
https://zenn.dev/voluntas/scraps/9403b803320d6f
https://zenn.dev/ginpei/articles/agora-voice-chat

Discussion