オンライン配信の要件とアーキテクチャ
今回グループとはいえ異なる二社間でオンライン配信を行う上で、外せない要件がいくつかありました。
- 観覧者を特定ユーザ(自社 + グループ会社)に限定出来る事
- 但し、参加者の総数は不明
- 所属会社の違いに関係なく利用できる事
- 複雑な社内手続き無しですぐに導入できる事
これらを踏まえた上で設計した結果、大体以下のようなアーキテクチャになりました。
ポイントは大きく2つです。
- 動画配信基盤
ライブストリーミング処理には、Amazon IVSを採用しました。今回はライブストリーミングさえできれば良かったのでIVSを選びましたが、透かしを入れる、フォーマットを調整する等、配信する前に動画の調整が必要な場合はElemental Media系も視野に入ります。この辺りは弊社ソニービズネットワークスの池田が担当しているので、いつか彼が詳しく解説するブログを書いてくれると思います(笑)。
- 動画配信サイト
今回必要な機能はユーザ認証、動画視聴くらいだったので、サーバレスのSPAとして設計しました。そして必要なコンポーネントの機能開発・デプロイには、AWS Amplifyをフル活用しています。
完全にサーバレスで構築している為、メンテナンス不要、低コスト、そして要件を網羅しつつ2週間程度での超短期間開発を実現する事が出来ました。
AWS Amplifyとは
AWS Amplifyとは、AWSを活用したWebアプリケーションを構築する為のフレームワークです。AWS曰く「Amplifyにはwebアプリやモバイルアプリを構築する為に必要なものが全て揃って」いるそうです。実際とても多機能で便利なのですが、個人的には以下の2点がAWS Amplifyの素晴らしいところだと思っています。
- Webアプリで求められる一般的な機能を簡単に実装出来る
AWS Amplifyは、機能の実装に必要なSDKを多数用意しています。例えばDB回りのCRUD(Create, Read, Update, Delete)処理、S3を活用したファイル管理等です。また、Amplify UI Kit として、機能の実装に使えるReactコンポーネントを予め用意してくれています。これを活用する事で、パラメータを渡すだけで機能を実装出来ます。(詳細なコードは後述)
- 認証機能を簡単に実装出来る
個人的にはこれがAWS Amplifyを活用する一番のポイントです。一般的なWebアプリの開発では、認証機能の実装が最大の課題になります。当たり前の話ですが、Webアプリはインターネットに公開して利用します。誰でもアクセスできる環境に置いてはいますが、登録したユーザのみが機能を利用できるべきです。AWS Amplifyを使うと、最小限のコマンドとコードで認証回りを実装出来ます。
次のセクションから、実際に実装したUIとコードを解説します。
実装した機能 「認証」
サイトを開くと、最初に以下の認証画面が表示されます。
このコンポーネントはAmplify UI Kitをそのまま活用して実装しています。AWS Amplifyを使って認証機能を実装する為に必要な手順は、Amplify UI Kitで用意されているコンポーネントを使って、以下のようにサイトのコンポーネントを囲ってあげるだけです。
App.js(トップページの関数)のコードから抜粋
※参考 AWS Amplify UI Kit Authenticator :
https://ui.docs.amplify.aws/react/connected-components/authenticator
これだけで、ログインしていないユーザは<Authenticator>の中のコンポーネントにアクセスできなくなります。
基本的に認証機能の実装はこれで終わりなのですが、今回は「観覧者を特定ユーザ(自社 + グループ会社)に限定出来る事」という要件があります。満たす手段は色々考えられますが、今回はAmazon Cognito のLambdaトリガーを利用して実装しました。
Amazon Cognito User Poolは、認証時の以下タイミングでLambdaをトリガーする事が出来ます。
- サインアップ前
- サインアップ確認後
- 認証前
- 認証後
各イベントでLambdaをトリガーすると、以下のデータがLambdaへ引き渡されます。
各認証イベントからLambdaへ引き渡されるイベント
この中の情報を使って、Cognitoの認証フローをカスタマイズする事が可能です。今回はこの中のメールアドレスを使って、特定のドメインを持つアドレスのみサインアップを許可します。サンプルコードは以下です。
カスタム認証フロー用Lambdaのサンプルコード
※参考 サインアップ前のLambdaトリガー
https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/user-pool-lambda-pre-sign-up.html
実装のポイントは、受け取ったイベントオブジェクトをそのまま処理の最後にレスポンスとして返す事です(20行目)。これで指定したユーザにのみサインアップを許可する事が出来ました。
実装した機能 「ライブ配信プレーヤー」
サインインに成功すると、以下のような画面が表示されます。
トップページのライブ配信プレーヤー
このプレーヤーには、外部ライブラリであるreact-playerを利用しました。
参考 react-player: https://github.com/cookpete/react-player
react-playerはオープンソースの高機能プレーヤーです。今回は可能な限りライトに実装したかった為、IVSから払い出されるHLSのマニフェストファイルを指定するだけで動くこちらを採用しました。
Player.jsx より抜粋
<ReactPlayer>のurlプロパティに、IVSから払い出されるマニフェストファイルのURLを指定しています。あとは配信を開始するだけで、ユーザはライブを観覧出来ます。
実装した機能 「リアルタイムコメント投稿」
ところで、プレーヤーの右側に謎のコメント欄がある事にはお気づきになられましたか?
トップページのコメント欄
これは特に要件にはありませんでしたが、面白そうだったので載せた機能です。動画の感想を「Comment」と書かれた入力欄に入力し、右側の送信ボタンを押す事で、コメントを投稿できます。投稿されたコメントは、観覧中の全ユーザにも即時反映されます。AWS AppSyncとAmazon DynamoDBを組み合わせて実装しています。
AWS AppSyncはGraphQLを提供するマネージドサービスです。Amplify SDKに組み込まれており、コマンド1つで作成 & 認証機能とシームレスに連携出来ます。一般的にWebアプリからDynamoDBを操作する方法は以下の2つです。
- API Gateway + AWS Lambda
- AWS AppSync
前者の場合、Lambda側でクエリを実装する必要があり、かつLambdaのメンテナンスも必要になりますが、AppSyncの場合、Webアプリ側だけでクエリの実装が完結します。これだけでも大分開発が捗るのですが、AppSyncを採用した一番の理由は「サブスクリプション」という機能の存在です。
サブスクリプションは、データベースの更新を検出し、クライアント側に更新内容を配信する機能です。登録したデータがそのままクライアント側に配信されます。これを利用する事で、他のユーザがDynamoDBに登録したコメントを、即座に反映する事が可能になります。
今回は、AppSyncを使って以下の3つの機能を実装しました。
- トップページ表示時にDynamoDBをQueryし、投稿されているコメントを取得
- トップページ表示時にPutItemイベントをサブスクライブ、PutItemを検出したら更新を受信
- 送信ボタン押下時、Commentに入力された値をDynamoDBへPutItem
以上で、リアルタイムコメント機能を実装する事が出来ました。AppSyncは複数のコンポーネントから構成されており、ここでまとめ切れるものではありません。別の機会で詳細な設計・構築方法について解説出来ればと思います。
AWS Amplifyのポイント
実際にAWS Amplifyを活用してみて、感じたポイントは以下です。
- 認証機能のカスタマイズ
- AppSyncのカスタマイズ
- (Amplifyとは関係ないですが)ユーザインプットに対するセキュリティ対策
1について、恐らく通常の案件ではサインアップ出来るユーザに制限をかける事が多いと思います。制限の手法としては、セルフサインアップの無効化、接続元IP制限、Lambda を使ったカスタム認証フローが挙げられます。これらを事前に知っておき、要件に合わせて実装する事が重要です。
2について、amplify add api コマンドで作成されるDynamoDBの操作方法は「Scan」です。ScanはDynamoDBのデータを全て取得する負荷の高い操作で、基本的には非推奨とされています。実際の案件ではデータ量が多くなる事が予想され、Scan ではなく Query を使うように書き直して利用しましょう。
- 参考 DynamoDBのマッピングテンプレート
https://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/resolver-mapping-template-reference-dynamodb.html
3について、Amplifyを使うと自由に実装出来る分、セキュリティ対策を検討する事が大切になります。ユーザインプットを許可するとインジェクションやXSS等の様々な攻撃、公序良俗に反する内容のコメント投稿に対して対策が必要になります。今回はプライベート利用という事でコメント内容ついては許容し、AWS WAFによる各種攻撃対策と、文字数制限の2つを実装しました。次回以降は Amazon Bedrock で入力をチェックし、問題なければ投稿、というような生成AIを活用したアーキテクチャを検討したいと思います。
終わりに
AWS AmplifyはAWSサービスを活用したWebアプリの開発を高速化する、強力なフレームワークです。どのアプリでも必ず必要になる(そのくせ実装が大変な)認証機能や、不特定多数のクライアントにデータをPushするアーキテクチャを簡単に実装出来るのは、本当に素晴らしいと感じました。サーバレスという事で料金もお手軽なので、皆さんもぜひお気軽に触ってみて頂ければと思います。
触ってみて分からないところは、ぜひソニービズネットワークスにご相談下さい。以上、開発グループの濱田でした。