大規模会議アプリを実装する上での注意点
参加人数が多く、たくさんの映像を同時にディスプレイに表示するようなアプリケーションを実装する際に、いくつかの事項について注意する必要があります。
本記事では、サンプルアプリケーションを例として参照しつつ、以下の注意点について確認していきます。
- Room の種類の選択
- カメラの Stream の設定
- Publish のオプション
- Subscribe のオプション
- 同時に表示する映像の数
本記事では Room ライブラリを使用してアプリケーションを作成しています。
Core ライブラリを利用する場合も注意点は同様となります。
サンプルアプリケーション
https://github.com/skyway/js-sdk/tree/main/examples/large-room
Room の種類の選択
P2P による多人数通信はメディアの変換処理や通信効率の面で無駄が多く、パフォーマンスの制約が厳しく、大規模な利用には向いていません。
そのため大規模会議アプリを開発する際には必ず SFU Room を利用する必要があります。
SFU Room は次のように作成できます。
App.tsx L21
const context = await SkyWayContext.Create(tokenString, contextConfig); const room = await SkyWayRoom.FindOrCreate(context, { name: roomName, type: "sfu", }); const member = await room.join();
カメラの Stream の設定
大規模会議アプリケーションでカメラとマイクの Stream を取得する際の推奨する設定について説明します。
カメラとマイクの Stream は以下のように取得しましょう。
App.tsx L30
const { audio, video } = await SkyWayStreamFactory.createMicrophoneAudioAndCameraStream({ video: { height: 640, width: 360, frameRate: 15 }, });
カメラの Stream については次のような設定を指定しています。
{ height: 640, width: 360, frameRate: 15 }
解像度 640×360 15 fps というのは一般的な Web カメラの映像を表現する品質として十分なので、このレベルの画質を基準にカメラの Stream の設定をすることをおすすめします。
Publish のオプション
Stream を Publish して Channel 上に公開し、他のユーザーが Stream を受信できるようにします。
以下のように Stream を Publish しましょう。
App.tsx L33
await member.publish(audio, { maxSubscribers: 50 }); await member.publish(video, { maxSubscribers: 50, encodings: [ { scaleResolutionDownBy: 4, id: "low", maxBitrate: 100_000 }, { scaleResolutionDownBy: 1, id: "high", maxBitrate: 400_000 }, ], });
それぞれの設定項目について見ていきます。
maxSubscribers
audio,video ともに適切な maxSubscribes の値を設定する必要があります。この値が会議の最大同時参加者の数となります。
Simulcast
Simulcast はクライアントがいくつかの異なる画質の映像を同時に公開できる機能です。
受信側はネットワーク環境に合わせて自動的に画質を選択するか、明示的に画質を選択して受信できます(動画配信サービスの画質選択設定と同じイメージです)。
自動的に画質を選択する場合は少し時間がかかるので、 大規模会議のような、予め高画質な映像を受信するとパフォーマンスに影響が出るとわかっている場合は、はじめから低画質設定を明示的に指定することでユーザー体験を改善できます。
サンプルアプリケーションでは Video の Stream を Publish する際に以下のようにエンコード設定を設定しています。 エンコード設定の設定の数は 2 つまでを推奨しています。3 つ以上設定したとしてもデバイスの負荷状況によっては 3 つ目以降の設定が無視されることがあるからです。
encodings: [ { scaleResolutionDownBy: 4, id: "low", maxBitrate: 80_000, maxFramerate: 5 }, { scaleResolutionDownBy: 1, id: "high", maxBitrate: 400_000, maxFramerate: 30 }, ],
iOS/Android SDK においては maxFramerate を複数指定することはできません。
それぞれの設定項目について見ていきます。
- scaleResolutionDownBy
- scaleResolutionDownBy では映像の元の解像度に対して何分の 1 の解像度に変換するかを指定できます。元の解像度が 640×360 の映像で仮に 4 を入れると 4 分の 1 の解像度である 160×90 の映像が公開されます。
- maxBitrate
- 各エンコード設定のビットレートは maxBitrate の値(bps)に制限されます。
- maxFramerate
- 各エンコード設定のフレームレートは maxFramerate の値に制限されます。
- iOS/Android SDK においては複数指定することはできません。
- id
- 各エンコードの設定には識別用の ID を入れる必要があります。
次にサンプルアプリケーションが設定している値について詳細に解説します。
解像度の設定(scaleResolutionDownBy)
会議の参加者が少ないうちは、映像の描画負荷は問題にはなりませんが、参加者が増えてくるとその負荷は無視できなくなってきます。
最大 50 人の会議アプリケーションでグリッド状に全参加者(自身を除いた 49 人分)の映像を表示する場合、ユーザーのデバイスの総描画解像度は以下のようになります。
7*640 = 4480 7*360 = 2520 4480x2520
一般的な PC のディスプレイの解像度は 1920×1080 であることが多く、総描画解像度がデバイスの解像度を大きく上回っており、デバイスに無駄な描画負荷がかかってしまいます。
そこで描画負荷を軽減するために多人数表示用のエンコード設定を追加する必要があります。
このサンプルアプリケーションでは多人数表示用のエンコード設定の scaleResolutionDownBy を 4 に設定しています。
これにより総描画解像度は以下のようになります。
7*640/4=1120 7*360/4=630 1120x630
動作対象とするクライアントデバイスの性能やアプリケーションの要件に合わせて scaleResolutionDownBy の値は調整してください。
常に総描画解像度がクライアントのデバイスの描画領域の解像度を上回ることのないようにすることが重要です。
ビットレートの設定(maxBitrate)
回線速度の低い環境で快適に大規模会議を利用できるようにするために、通信量について考慮する必要があります。
最大 50 人の会議アプリケーションで全参加者(自身を除いた 49 人分)の映像(400kbps)をユーザーのデバイスに表示する場合下りの通信量は以下のようになります。
400kbps * 49 = 19.6mbps
モバイル回線のような環境では 5mbps 程度の速度しかないことが想定されるので、 全参加者を表示した状態で正常にアプリケーションを利用できるようにするためにはビットレートを制限する必要があります。
このサンプルアプリケーションでは多人数表示用のエンコード設定の maxBitrate を 80kbps に設定しています。
これにより通信量は以下のようになります。
80kbps * 49 = 3.92mbps
動作対象とするネットワーク環境に合わせて maxBitrate の値は調整してください。
クライアントのデバイスの通信帯域を上回る量の通信を行うと、輻輳が発生し、一時的に映像や音声が停止するなどの問題が発生するので、注意する必要があります。
モバイル端末上では同時に表示する映像の数を PC より少なくするなどの最適化を適宜行ってください。
フレームレートの制限(maxFramerate)
映像の滑らかさと描画負荷のバランスを取るために、フレームレートの制限も重要な設定となります。
フレームレートが高いほど映像は滑らかになりますが、それに伴い描画負荷も増えます。特に多人数の会議では、各参加者の映像を描画するための負荷が大きくなるため、適切なフレームレートの制限が必要となります。
このサンプルアプリケーションでは多人数表示用のエンコード設定の maxFrameRate を 5 に設定しています。
これにより、各参加者の映像は最大で秒間 5 フレームで表示され、描画負荷を抑えることができます。
動作対象とするクライアントデバイスの性能やアプリケーションの要件に合わせて maxFrameRate の値は調整してください。
フレームレートが高すぎると、デバイスの描画負荷が増え、パフォーマンスが低下する可能性があります。逆に、フレームレートが低すぎると映像が不自然に見える可能性があります。適切なバランスを見つけることが重要です。
Subscribe のオプション
ビデオを Subscribe する際に preferredEncodingId
に Publish した際に設定したエンコード設定の ID を指定することで指定した ID のエンコード設定で Subscribe できます。
Simulcast による画質の自動選択にはラグがあり、大規模会議で全参加者の映像を表示する場合や、性能の低いモバイル端末でアプリケーションを利用する場合は、一時的に映像や音声が停止する可能性があります。 そういったケースでは、予め低画質設定を指定して Subscribe することで、問題を回避できます。
サンプルアプリケーションでは次のように低画質設定を選択して Subscribe するようにしています。
App.tsx L63
const subscribe = async (publication: RoomPublication) => { if (publication.publisher.id !== member.id) { if (publication.contentType === "video") { await member.subscribe(publication, { preferredEncodingId: "low" }); } else { await member.subscribe(publication); } } };
Subscription のエンコード設定の切り替え
Stream を Subscribe した後、Subscription の映像のエンコード設定を切り替えたい場合は次のようにします。
App.tsx L103
const switchEncodingSetting = async () => { if (subscription.preferredEncoding === "high") { subscription.changePreferredEncoding("low"); } else { subscription.changePreferredEncoding("high"); } };
changePreferredEncoding で変更したいエンコード設定の ID を指定すると Subscription のエンコード設定がその設定にただちに切り替わります。
会議の参加人数に合わせて受信映像の品質設定を変更するなどの工夫を施すのも有効な手段です。
同時に表示する映像の数
解像度やビットレートを抑制したとしても、大量の映像を同時にデコードするのは端末に対して大きな負荷がかかります。サービスがサポートする対象の端末の性能に合わせて同時に表示する映像の数は制限する必要があります。
オンライン研修などの数十人以上のユーザーがビデオをオンにして利用するケースで、ページネーションは端末への負荷を軽減する非常に有効な手段です。
数十人のうち同時に 4×4 人や 5×5 人を同時に表示し、それ以降のユーザーはページ変更ボタンを押した際に表示するよう実装することで端末の負荷を大幅に軽減できます。
まとめ
この記事のサンプルアプリケーションで行った最適化事項についてまとめると以下のようになります。
- SFU を使う
- カメラの解像度を用途に合わせて制限する
- Publish のオプション指定
- maxSubscribers
- 会議の最大参加者数を指定する
- encodings
- 最大参加者数に合わせて解像度を制限する (scaleResolutionDownBy)
- 最大参加者数に合わせてビットレートを制限する (maxBitrate)
- 設定の識別用の ID を設定する
- maxSubscribers
- Subscribe のオプション
- 参加者数が多い場合やクライアントデバイスの性能が低い場合は、はじめから低い映像品質を指定する
- ページネーションの実装を検討する
クライアントデバイスの通信環境や処理性能を意識した設定を行うことが重要です。