Amazon Chime SDK で16ビデオ通話セッションを超えてみる。

`この記事はこちらでも紹介しています。 `
https://cloud.flect.co.jp/entry/2020/07/08/153456


前回は、Amazon Chime SDKの新機能を使って作ったホワイトボード機能についてご紹介しました。

https://qiita.com/wok/items/83a8700d5c09cc1747d0

今回もAmazon Chime SDKについての話になります。
少しトリッキーな使い方を実験をしてみたのでご紹介したいと思います。

具体的には、単一のSPA（Single Page Application）から複数の会議室に同時に参加できるかを実験しました。
これができれば、次のことが可能になると考えています。

- （オンラインセミナーなどで、）Amazon Chime SDKの会議室あたりの最大接続数を超える人数に向けた講義が可能になる。
- （オンラインセミナーなどで、）グループ単位で受講者のプライバシーを保護できる。


実験の結果、次のデモのように、単一のユーザ(登壇者)が複数の会議室に参加することで、会議室あたりのビデオ通話可能な最大ユーザ数(16名)を超えるユーザに対し、同時にビデオ通話ができることが確認できました。
また、登壇者以外の各会議室の参加者(受講者)間の会話や映像は他の会議室には伝わらないため、会議室間でプライバシーも保護することができます。

![ezgif-5-2cd8468121a2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365991/a641ba15-d522-0d6d-8132-7f280fcef853.gif)


このデモでは登壇者が2つの会議室に参加することで、30名のユーザとビデオ通話しています。[^1]

[^1]: このデモでは、動画をダミーのカメラデバイスに流し込むことで30名のユーザ(受講者)を模擬している。

<!-- more -->

### Amazon Chime SDKのビデオ通話セッション数と、大規模なオンラインセミナー
私が所属する会社は、AWS, GCP, Azureを代表とするマルチクラウドを扱えることを強みとしたクラウドインテグレータです。
当然、オンライン会議システムのソリューションを提案する場合も、Amazon Chime SDKと他のオンライン会議システムの強み弱みを比較検討するわけですが、
Amazon Chime SDKは会議室あたりのビデオ通話の最大参加者数(セッション数)が、例えばZoomのビデオウェビナープランなどの100名と比較して、16名と少ないです(2020年7月現在)。[^2]
[^2]: Zoom [https://zoom.us/jp-jp/webinar.html:embed:cite]

とはいえ、Amazon Chime SDKには、オンライン会議への接続形態として、下記の2パターンあり音声通話参加者は250名まで接続可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365991/f22ba4c8-bf06-10fb-b8d7-3c0d021fc144.png)

そして、必要に応じてオンラインのまま、16のビデオ通話セッションを音声通話参加者に割当直してビデオ通話参加者にすることができます（下図）。
つまり、例えば発言中のユーザにビデオ通話セッションを割り当て直して、顔を映すということができます。

対面の講演やセミナーを考えると、質疑の場面以外では受講者が他の受講者の顔を見ることは、あまり多くないと思います。
なので、発表中は登壇者にビデオ通話セッションを割り当てて、質疑の際に質問者(特定の受講者)にビデオ通話セッションを割り当てるという構成にすれば、
Amazon Chime SDKのビデオ通話セッション数でも十分な場合も多いのではないかと考えられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365991/791b649b-643e-5727-c7ab-2956a9c4c910.png)

しかし、音声通話参加者が250名を超える場合や、下図のように登壇者側が16名以上の受講者の反応をビデオ映像で見たい場合などには、普通にAmazon Chime SDKを使うだけでは対応できません。
もし、受講者を複数の会議室に分散して参加させ、それらの会議室に登壇者が同時に参加できるようになれば、これを解決できると思われます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365991/722814d6-e84b-90a2-af1b-f58f97be27df.png)


なお、少し横道にそれますが、16名を超える登壇者がいる場合はAmazon Chime SDKだと対応しきれないかもしれません。
この場合でも適宜ビデオ通話セッションを割り当て直せば十分なことも多いとは思いますが、
討論会でパネリスト(≒登壇者)のリアクションを常時ビデオ映像として配信したいといった要件がある場合は対応が難しいと思われます。


### グループで参加したいオンラインセミナー
また、私個人が経験したことではありますが、オンラインの勉強会に参加したときに、発言するとそれが全体に伝わるので躊躇してしまうことがありました。
簡単な理解の確認であれば、横にいる同僚や知り合いにコソコソ話をして確認したいところですが、オンラインの勉強会だとslackなど別のコミュニケーションツールを使って会話をする必要があって面倒です。
最悪の場合、別のツールなのでこちらが話しかけても気づいてもらえない場合があります(涙)。
オンラインセミナーの受講にグループで参加して、受講中はグループ内だけでコミュニケーションが取れる方法があればありがたいと思いました。

また、セミナーの内容によっては、遠方の家族、親戚も一緒にオンラインセミナーで勉強したいが、他人には参加してることが知られたくないようなものがあるかもしれません。
例えば、医療に関わる話であったり、受験や結婚、資産運用などがそれに当たるかもしれません。
こういったものは、シビアな内容のものが多いので家族間で適宜感想を確認しながら受講するということが多いのではないかと思います。

これらについても、下図のように家族やグループ毎に会議室を割り当てて、それらの会議室に登壇者が同時に参加できるようになれば、会議室内の会話や映像は他の会議室には伝わらないので、解決できそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365991/9976dde0-62fb-bace-280c-19e4a90b2d40.png)


### 実装のポイント
ということで、今回はSPAで上記のような構成を作れるかを実験してみました。
今回の実験の内容を含むデモプログラム全体は下記のgitリポジトリにアップしてありますので、ポイントだけ確認していきます。

といっても、特に難しいところはありません。
基本的には単一の会議室に入る処理を繰り返し、それぞれのエンドポイントや参加者を管理しておくようにしておくだけでできます。

たとえば、今回のデモプログラムでは、参加中会議室をそれぞれJoinedMeetingというInterfaceで管理をしています。
このInterfaceには、会議室毎に作成した、`MeetingSessionConfiguration`や `MeetingSession`に加え、参加者情報やビデオタイルといった各会議室固有の情報を格納します。

```javascript
export interface JoinedMeeting{
    meetingSessionConfiguration: MeetingSessionConfiguration,
    meetingSession: MeetingSession,
    roster: { [attendeeId: string]: Attendee },
    videoTileStates: { [id: number]: VideoTileState },
    outputAudioElement: HTMLAudioElement | null,
    <snip>
}

```

これをSPA全体で複数管理できるようにしてあげます。
今回のデモプログラムではmeetingIdをキーとした連想配列で管理しています。

```javascript
export interface AppState {
    joinedMeetings : {[id:string]:JoinedMeeting},
    <snip>
}
```

そして、新しく会議室に参加するたびに、その会議室のMeetingSession.audioVideoからビデオ入力やマイク入力、スピーカーを設定すればよいです。
デバイスの選択し直しの場合も、同様にすべての参加中の会議室のMeetingSession.audioVideoから設定してあげればよいです。
例えば、マイク入力を切り替える場合は次のような感じになります。

```javascript
    selectInputAudioDevice = (deviceId: string) => {
        const currentSettings = this.state.currentSettings // <- 使用するデバイスなどをグローバルに管理している前提。
        currentSettings.selectedInputAudioDevice = deviceId

        Object.keys(this.state.joinedMeetings).forEach((x:string)=>{
            this.state.joinedMeetings[x].meetingSession.audioVideo.chooseAudioInputDevice(deviceId); // <- ここで設定。
        })
        this.setState({ currentSettings: currentSettings })
    }
```


### その他、考慮が必要なポイント
基本的には上記の通りで良いのですが、複数の会議室に入ると、その分の映像を送受信するデータ量が増加します。
これらについては、Amazon Chime SDKのAPIで送信データ量をコントロールできるようになっているので、そこで調整出来るようにしておくと良いと思います。
特に受講者側は、デフォルトで解像度を下げておくほうが良いかもしれません。

```javascript


    selectInputVideoResolution = (value: string) =>{
        <snip>
        Object.keys(this.state.joinedMeetings).forEach((x:string)=>{
            this.state.joinedMeetings[x].meetingSession!.audioVideo.chooseVideoInputQuality(
                videoConfig.width, videoConfig.height, videoConfig.frameRate, videoConfig.maxBandwidthKbps // videoConfigで解像度やフレームレート、最大データ送信量が設定してある前提
            );
        })      
        <snip>
    }
```

### FLECT Amazon Chime Meeting
今回説明した機能は、FLECT研究開発室が開発しているビデオ会議を使った新機能のテストベッドに組み込まれています。
下記のリポジトリに公開していますので、ご興味を持たれましたらアクセスしてみてください。

https://github.com/FLECT-DEV-TEAM/FLECT_Amazon_Chime_Meeting


### 最後に
今回は、Amazon Chime SDKを使ったSPAから複数の会議室に参加できるかを実験してみました。
ネットワークなど計算リソースに関して考慮すべき点は残っていますが、大枠としては可能であることがわかりました。
これにより、複数の会議室から大規模なオンラインセミナーの会場を構成できる見込みを得ることができました。
また、大規模な会場においてグループ間でのプライバシーを保護できる見込みも得ることができました。

弊社FLECTでは、Amazon Chime SDKを用いてこれらの機能を組み込んだシステムの提案、構築をしております。
 興味をお持ちいただけたら是非ご相談ください。


次回は、またAmazon Chimeで遊ぶか、以前紹介したマルチバーコードリーダの技術的な内容をご紹介するかをしようと思ってます。
では。


### 参考・リソース

会議室の参加者のカメラ画像は、次のサイトの動画を用いて擬似的に作成しました。

https://pixabay.com/ja/videos