AppSyncとTouchDesignerを組み合わせて、ほぼリアルタイムのいいね!機能で発表を沸かせてみた
はじめに
先日、社内でAWSのre:Inventに行った人による報告会がありました。
報告会の基本的なスタイルといえばみなさんご存知、一方的にスピーカーが話すスタイル。そのスタイルだと聴衆者はよほどのことがない限り退屈になってしまうのが慣例。
そこをインタラクティブな報告会にすることができればより関心を持ってもらって聞いてもらえることができるのではないでしょうか?
と思って考えたシステムは聴衆者がボタンを押すと発表スクリーンに出てくるいいね機能。
今回はラスベガスで開催されたre:Inventの報告会だったこともあり、メダルを使ったいいね機能をAWSのAmplifyやAppSync、リアルタイムレンダリングソフトであるTouchDesignerを用いて実装しました。
完成物
いいねボタンのタップWebページ(いいねを送信)
報告会の発表スライド(いいねをリアルタイムレンダリング)
システム構成
いいねボタンを押すWebアプリはReact/Amplifyで実装し、タップする度にAppSync経由でDynamoDBのテーブルのいいね数がカウントアップされます。
そのいいね数をTouchDesignerからAppSync経由で取得し、PremierePro上で再生される発表動画にいいねの数に応じたメダルテロップを貼り付けることでリアルタイム連動を実現しました。
実装までの流れ
このシステムを実現するまでのワークフローは以下の流れとなります。1. Amplify Studioを使ってReactのWebアプリを実装
2. AppSyncでいいね数を+1するカスタムリゾルバの実装
3. TouchDesignerでいいね数の取得
1. Amplify Studioを使ってReactのWebアプリを実装
Amplify StudioによるWebアプリの基盤構築
まずAWS Amplifyで新しいアプリケーションを構築すると、Amplify Studioがセットアップされます。
今回はFieldNameにcount、TypeにIntを指定したテーブルを作成し、Save and Deployをするだけで、Reactの初期画面からAppSync、DynamoDBまでのWebアプリ基盤をわずか15分で作成することができました。
注意点として、GraphQL API settings画面のconflict resolution & offline capabilitiesを必ずEnableに変更することをお忘れなく。
UI実装のためのローカル環境の構築
次にUI部分のカウントアップ機能の実装をローカル環境で行います。
コマンドプロンプトで以下を実行します。
npx create-react-app my-react-app #Reactのプロジェクトの作成
npm install aws-amplify @aws-amplify/ui-react #Amplifyのライブラリの取得
amplify pull --appId [アプリのId] --envName staging #Amplify Studioの画面上のコードを入力
これでローカル環境の構築ができたので、ReactでUI画面を作成しました。
2. AWS AppSyncでいいね数を+1するカスタムリゾルバの実装
UI画面ができたので、いいねボタンを押すといいね数が+1されるカスタムリゾルバをAWS AppSyncを使って作成します。
AWS AppSyncの実装
AWS AppSyncとは自動でスケーリングするマネージドGraphQLサービスです。セキュリティやキャッシング、細かいアクセス制御、モニタリングとオブザーバビリティ(可観測性)などが組み込まれており、他のAWSサービスとAppSyncを簡単に統合することができます。AppSyncのコンソール上では、自分が作成したクエリ言語などを確認できるような環境が用意されており、この環境を使うことで他にツールを使わずにバックエンドの実装を確認することができるという点が魅力です。
今回のシステムでは、いいねボタンを押すとAppSyncでDynamoDBの該当レコードのcount数を取得し、インクリメント(+1)を行ってアップデートをするという処理を行いました。DynamoDBでの項目は下の画像のように設定し、id: countidのレコードのcount数を更新します。
コンソール上でのカスタムリゾルバの構築
まずはスキーマにcount属性をインクリメントするmutationを定義します。
このmutationに対するリゾルバを作成します。リゾルバはユニットリゾルバで作成してください。右のMutationでアタッチを行い、VTL (Velocity Template Language) スクリプトを書きます。DynamoDBのUpdateItem操作を使用してcount属性をインクリメントするコードは以下の通りです。
{
"version" : "2017-02-28",
"operation" : "UpdateItem",
"key" : {
"id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
},
"update" : {
"expression" : "SET #count = #count + :increment",
"expressionNames" : {
"#count" : "count"
},
"expressionValues" : {
":increment" : $util.dynamodb.toDynamoDBJson(1)
}
}
}
保存をすると、クエリ画面に遷移し、適切な処理が行われているか確認をします。mutationを実行した後にクエリでcount数を取得すると、+1されていることが確認できました。
UIにカスタムリゾルバを適用
無事バックエンドの設定が終わったので、先ほど作ったいいね画面のボタンのハンドラ部分にMutationをコピペします。それだけでUIからカウントアップ機能が簡単に実装することができました。
const onclickButtonSubmit = async (event) => {
event.preventDefault();
const incrementMutation = `
mutation MyMutation {
incrementCount(id: "countid") {
id
}
}
`;
最後のステップとして、ローカル環境からのamplify add hosting
によるホスティング設定を行い、
amplify publish
コマンドを実行することで、Amplify環境へのデプロイが完了します。
これにより、ホスティングされたURL上で「いいね」ボタンが表示され、利用可能になります。
3. TouchDesignerでいいね数の取得
TouchDesignerからクエリを出していいねメダルを描画
次はいいねメダルの枚数を取得するクエリを確認します。
AppSyncで”countid”がidであるレコードのcountを取得するクエリを実行すると、正常に取得することができました。
TouchDesignerからクエリで枚数を取得
上記のクエリをコピペし、1秒間隔でCHOP Execute内のPythonから枚数を取得します。
TouchDesignerでのいいねカウント取得をPythonで実装
TouchDesignerは基本的にはシングルスレッドであることから、通信する部分だけは別のTouchDesignerを起動し、 動画の再生やメダルの描画を行うTouchDesignerとは、Touch InやTouch Outで通信するように構築しました。
def onValueChange(channel, sampleIndex, val, prev):
url = "AppSync GraphQLエンドポイントURL"
api_key = "APIキー"
# GraphQLクエリ
query = """
query MyQuery {
getCounter(id: "countid") {
count
}
}
"""
TouchDesignerでの描画
以上の過程で1秒間隔でいいねメダルの枚数を取得することができたので、その値をテロップに連携します。
今回の発表資料はPremiere Proから再生する動画素材での発表を行ったので、シーケンスを再生したNDI outputの映像をNDI Virtual Inputを使って仮想Webカメラとし、それをVideo Device Inで映像取得しました。その映像をTouchDesigner上で合成し、スクリーンなどに映し出すというシステムで構築しました。
まとめ
今回、AppSyncとTouchDesignerを組み合わせてインタラクティブな報告会の仕組みを作成しました。今後も、報告会で楽しんでもらえるTouchDesignerやUnityなどの制作ソフトとwebシステムを組み合わせた簡易的なインタラクティブコンテンツを作成していきたいと思います。