7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

LIFULLその2Advent Calendar 2020

Day 17

Amazon Chime SDK JSをローカルHTMLで雑に動かす

Posted at

技術検証で Amazon Chime SDK を使い出したが、
APIも多く学び始めすぐ、0から動かすのに手間取った記憶がある。

そこで、Amazon Chime SDK に入門し公式サンプルプロジェクトを動かした後、
0から動かしてみるのに楽な最小構成を考えてみた。

大枠こんな感じ

  • MeetingSession 起動に必須パラメーターは AWS CLI で作る
  • ローカルサーバーとHTMLファイルだけで通話クライアントを起動する

何が美味しい?

ローカルサーバーで動くので各種クライアントAPIを試すのに便利

事前準備

  • AmazonChimeFullAccess許可済み AWS IAM + AWS CLI
  • この公式サンプルを参考に Amazon Chime SDK JS のminファイルを出力する
  • 適当なローカルサーバーを用意する(http-server等)

使うHTML一枚

<html lang="ja">

<head>
    <script src="./scripts/amazon-chime-sdk.min.js"></script>
    <style>
        .main {
            display: flex;
            align-items: flex-start;
        }
        #video-tile {
            width:80%;
            display: flex;
            flex-wrap: wrap;
        }
        #video-tile video {
            width: 46%;
            height: auto;
            margin: 2%;
        }
    </style>
</head>

<body>
    <div class="main">
        <form action="/" method="get" id="meeting-params">
            <div>
                <label for="">Meeting JSON</label>
                <br>
                <textarea name="meeting" id="" cols="200" rows="16">
{
    "Meeting": {
        "MeetingId": "EXAMPLE",
        "MediaPlacement": {
            "AudioHostUrl": "",
            "AudioFallbackUrl": "",
            "ScreenDataUrl": "",
            "ScreenSharingUrl": "",
            "ScreenViewingUrl": "",
            "SignalingUrl": "",
            "TurnControlUrl": ""
        },
        "MediaRegion": ""
    }
}</textarea>
            </div>
            <div>
                <label for="">Attendee JSON</label>
                <br>
                <textarea name="attendee" id="" cols="200" rows="8">
{
    "Attendee": {
        "ExternalUserId": "EXAMPLE",
        "AttendeeId": "",
        "JoinToken": ""
    }
}</textarea>
            </div>
            <div>
                <button>Start Chime</button>
            </div>
        </form>

        <div id="video-tile">
            <video id="video-tile-self"></video>
        </div>
        <audio id="audio-view"></audio>
    </div>

</body>

<script>
    const params = (new URL(document.location)).searchParams;
    const params_meeting = params.get('meeting');
    const params_attendee = params.get('attendee');

    (async () => {
        if (!params_meeting) {
            return;
        }else{
            const p = document.getElementById('meeting-params');
            p.hidden = true;
        }

        const meeting = JSON.parse(params_meeting);
        const attendee = JSON.parse(params_attendee);

        const logger = new ChimeSDK.ConsoleLogger('ChimeMeetingLogs', ChimeSDK.LogLevel.ERROR);
        const deviceController = new ChimeSDK.DefaultDeviceController(logger);
        const configuration = new ChimeSDK.MeetingSessionConfiguration(meeting, attendee);
        const meetingSession = new ChimeSDK.DefaultMeetingSession(configuration, logger, deviceController);

        try {
            const audioInputs = await meetingSession.audioVideo.listAudioInputDevices();
            const audioOutputs = await meetingSession.audioVideo.listAudioOutputDevices();
            const videoInputs = await meetingSession.audioVideo.listVideoInputDevices();
            await meetingSession.audioVideo.chooseAudioInputDevice(audioInputs[0].deviceId);
            await meetingSession.audioVideo.chooseAudioOutputDevice(audioOutputs[0].deviceId);
            await meetingSession.audioVideo.chooseVideoInputDevice(videoInputs[0].deviceId);
        } catch (err) {
            // handle error - unable to acquire audio device perhaps due to permissions blocking
        }
        const audioOutputElement = document.getElementById('audio-view');
        meetingSession.audioVideo.bindAudioElement(audioOutputElement);

        const videoElementSelf = document.getElementById('video-tile-self');
        const videoElementTile = document.getElementById('video-tile');

        const observer = {
            videoTileDidUpdate: tileState => {
                if (!tileState.boundAttendeeId) {
                    return;
                }
                if (tileState.localTile){
                    meetingSession.audioVideo.bindVideoElement(tileState.tileId, videoElementSelf);
                }else{
                    if(!document.getElementById(tileState.tileId)){
                        const node = document.createElement("video");
                        node.id = tileState.tileId;
                        videoElementTile.appendChild(node);
                    }
                    const videoElementNew = document.getElementById(tileState.tileId);
                    meetingSession.audioVideo.bindVideoElement(tileState.tileId, videoElementNew);
                }
            },
            videoTileWasRemoved: tileId => {
                const videoElementRemoved = document.getElementById(tileId);
                videoElementRemoved.remove();
            }
        };

        meetingSession.audioVideo.addObserver(observer);
        meetingSession.audioVideo.startLocalVideoTile();
        meetingSession.audioVideo.start();
    })();
</script>

</html>

利用手順

  1. ビルドした Amazon Chime SDK JS min ファイルを上記 HTML に読ませる
  2. AWS CLI 経由で Chime ミーティングを作成する
    • $ aws chime create-meeting
    • $ aws chime create-attendee --meeting-id ($ aws chime create-meetingの返り値の MeetingId) --external-user-id (適当な参加者名)
  3. ローカルサーバーを起動し、2で得たJSONを貼り付けてセッションスタート

このローカル起動クライアントでも、複数人参加ができる

接続先のセッションは「Amazon Chime メディア・サービス」がよしなに用意してくれるので、ローカルにあるクライアント同士でも1on1ができる

複数人参加の手順

  • meeting JSON パラメーターを共有し入力
  • attendee JSON パラーメーターは参加者の数だけ個別に作り入力
7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?