Twilio Videoで都度Roomの設定を行う方法


はじめに

みなさん、こんにちは。
KDDIウェブコミュニケーションズのTwilio事業部エバンジェリストの高橋です。

今回は、Twilio Videoで都度Roomの設定を行う方法について説明します。

Twilio Videoでは、Roomと呼ばれる会議室に対して、Participantと呼ばれる参加者が入室することで会議が行われます。
Roomには3種類のタイプ(Peer-to-Peer Room / Small Group Room / Group Room)が用意されています。どのタイプを使ったほうが良いかは以下のフローチャートを参考にします。

参加人数が2名ならPeer-to-Peer Roomが最も性能が高く、3〜4名ならSmall Group Room、5名以上ならGroup Roomを利用します。
ただし、End-to-Endでの暗号化が必須の場合は、Peer-to-Peer Roomを使うしかありません(それ以外のタイプを選択した場合も、EndとTwilio間では暗号化がされています)。逆に録画が必要な場合は、Peer-to-Peer Roomは使えません。
それぞれのRoomタイプや、録画の有無により料金が異なりますので、どのRoomタイプを使うかを選択することは重要です。

Roomタイプ 1参加者毎の料金(税込) 録画料金(税込)
Peer-to-Peer Room 0.22917円/分 録画不可
Small Group Room 0.61111円/分 1.52778円/分
Group Room 1.52778円/分 1.52778円/分

※録画を行う場合には、上記以外にもデータ保管料と録画データダウンロード料が必要です。

Roomタイプの選択方法

Twilio VideoのRoomタイプの決定には2つの方法があります。

  • Ad-hoc:会議を開催する度に自動的にRoomを作成します
  • REST API:APIを使って、事前にRoomを作成します

Twilioが提供しているQuickStartOSSのビデオソリューションなどは、Ad-hocを利用しています。
Ad-hocでは、Roomは自動的に作成されるため、Roomタイプは管理コンソールで設定したデフォルト値(Room Topology)が適用されます。

一方、Ad-hocでは都度Roomタイプを変更したり、録画の有無を指定することができません。都度変更が必要な場合は、REST APIを使って事前にRoomを作成する必要があります。

REST APIでRoomを作成する

会議に先立ち、REST APIを使ってRoomを事前に作成する場合は、Ad-hocとは以下の点が異なります。

  • Roomを作成してから5分以内に誰も入室しない場合は、Roomは自動的に削除されます。
  • 全員がRoomから退出した後、5分間はルームは存在し続けます。5分経過後、自動的に削除されます。

REST APIのサンプル

入室までのタイムアウトがあるので、REST APIは最初の参加者が入室する直前に行うのが良いでしょう。入室するためには、アクセストークンの生成が必須なので、トークンを生成するタイミングでRoomを作ってしまうのが良さそうです。

以下のコードは、アクセストークンを作成する際に、同時にRoomを生成するサンプルです。
事前に会議に招待した人数によって、Small Group Roomにするか、Group Roomにするかを動的に判定しています。

video-token.js
exports.handler = async function(context, event, callback) {
    const response = new Twilio.Response();
    response.appendHeader('Access-Control-Allow-Origin', '*');  // CORS対策

    // パラメータのチェック
    const IDENTITY = event.identity || '';  // ユーザID
    if (IDENTITY === '') callback(new Error(`Parameter 'identity' was not set.`));

    const roomName = event.room || '';  // ルーム名
    if (roomName === '') callback(new Error(`Parameter 'room' was not set.`));

    const attendeesCount = event.attendees || 0;    // 会議に招待した人数
    if (attendeesCount === 0) callback(new Error(`Parameter 'attendees' was not set.`));

    const ACCOUNT_SID = 'AC'; // TwilioのAccountSid
    const API_KEY = ''; // Twilio VideoのAPI Key
    const API_SECRET = ''; // Twilio VideoのAPI Secret

    const RECORDING = false;    // 録画
    const ROOM_TYPE = attendeesCount > 4 ? 'group' : 'group-small'; // Roomタイプ
    const MAX_PARTICIPANTS = attendeesCount > 4 ? 50 : 4; // 最大参加者数(Group Roomは50名まで)

    // Roomを生成
    const client = require('twilio')(API_KEY, API_SECRET, {accountSid: ACCOUNT_SID});
    await client.video.rooms.list({
        uniqueName: roomName,
    })
    .then(rooms => {
        console.log('rooms.length: ', rooms.length);
        if (rooms.length === 0) {
            // 開催中のRoomがないので生成
            return client.video.rooms.create({
                maxParticipants: MAX_PARTICIPANTS,
                recordParticipantsOnConnect: RECORDING,
                type: ROOM_TYPE,
                uniqueName: roomName,
                mediaRegion: 'jp1',
            });
        } else {
            return null;
        }
    })
    .then(room => {
        if (room) {
            console.log(`Room created. ${room.sid}`);
        } else {
            console.log(`Room was exist.`);
        }
    })
    .catch(error => {
        callback(new Error(`Room create error: ${error}`));
    });

    // アクセストークンの作成
    const AccessToken = Twilio.jwt.AccessToken;
    const VideoGrant = AccessToken.VideoGrant;

    const videoGrant = new VideoGrant({
        room: roomName
    });

    const accessToken = new AccessToken(
        ACCOUNT_SID,
        API_KEY,
        API_SECRET
    );

    accessToken.addGrant(videoGrant);
    accessToken.identity = IDENTITY;

    response.appendHeader('Content-Type', 'application/json');
    response.setBody({
        token: accessToken.toJwt()
    });
    callback(null, response);
};

最初の参加者がRoomを生成するので、二人目以降の参加者がアクセストークンを生成する時は、すでにRoomが生成されているかを確認しています。
すでにRoomが存在するかを確認するには、RoomをリストするAPIを利用します。ただし、このAPIの実行が非同期で実行されると、その後の処理が先に行われてFunctionが終了してしまうので、async/awaitでRoomの生成を実行するところがポイントです。

まとめ

今回は、Twilio VideoのRoomをRest APIで生成する方法を説明しました。
記事の中にも書きましたが、REST APIでRoomを生成した場合、全員が退出してから5分経過しないとルームが閉じません。Twilio Videoを使った課金サービスなどを検討している方にとっては、正確なRoomの開催時間で課金をしたいケースも少なくないため、Ad-hocでの動作と同じように、全員が退出したタイミングでRoomが閉じられたほうが良いケースもあるでしょう。
こちらについては、次回の記事でご紹介します。


Twilio(トゥイリオ)とは

https://cloudapi.kddi-web.com
Twilioは音声通話、メッセージング(SMS/チャット)、ビデオなどの 様々なコミュニケーション手段をアプリケーションやビジネスへ容易に組み込むことのできるクラウドAPIサービスです。初期費用不要な従量課金制で、各種開発言語に対応しているため、多くのハッカソンイベントやスタートアップなどにも、ご利用いただいております。