Amazon Chime SDK について調べた
https://gyazo.com/abd22389a3479173114a64db65c739d5
はじめここが理解できず、右往左往していた。
サンプル
Github にサンプルがある。
こちらのサンプルはローカルで動かすことができる。
Node.js 17 で試したらエラーになったので、Node.js 14 で動かしたら問題なかった。
権限周りの問題だろうか。
これでミーティングを作成し、画面に同表示するか確認ができた。
また、以下の内容も確認できる。
チャット
画面共有
背景ぼかし
classmethod さんの記事に詳しい解説があった。
API での操作が必要なこと、例えばコンソールのどこかにミーティングを作成した記録が出るんじゃないかなと思ってたけど、そもそも Amazon Chime のバックエンドに丸っと含められているっぽくて、接続した分だけの課金ということになりそう。
https://d2908q01vomqb2.cloudfront.net/98fbc42faedc02492397cb5962ea3a3ffc0a9243/2020/04/08/amazon-chime-sdk-workflow-1024x512.jpg https://d2908q01vomqb2.cloudfront.net/98fbc42faedc02492397cb5962ea3a3ffc0a9243/2020/04/08/amazon-chime-sdk-workflow-1024x512.jpg
↑のサンプルはローカルで動かすものだったが、こちらのサンプルでは Lambda のデプロイなんかまでやってくれる。
パーミッションによるが、全機能を使うには region が限られているっぽい。
作成されるリソースは、
IAM
Lambda(サーバーサイド処理)
API Gateway
SQS(Chime からイベントを送信し、 Lambda におくる。このサンプルでは何もしてない)
DynamoDB(ミーティング情報を管理)
Meetings Media Capture Pipeline というのも新しくできたらしい。
ミーティングを作成した後、 aws cli 経由で作成されたミーティングを確認することができる。
Chime のリージョンに合わせる必要がある。
code:zsh
aws chime list-meetings --region us-east-1 --output json
料金
基本的には接続数で課金されるよう。
接続数なので、同じユーザーが異なるデバイスで接続しても課金対象になる。
ミーティングは特定の条件でも自動で終了するようなので、無限に課金されることはなさそう。
DeleteMeeting APIアクションを実行すると、会議が終了します。以下のような非アクティブな状態が一定時間続くと、ミーティングは自動的に終了します。
> 会議中に5分以上音声接続がない。
> 30分以上、会議中の音声接続が2つ以下である。
> 画面共有ビューアーの接続が30分以上無効である。
> 会議時間が24時間を超えている。>
こちらのサンプルでは React を使用して作成されているので、こちらも見ると良さそう。
ミーティングを作成すると
ミーティング作成 API のレスポンスに、 WebSocket の URL が返される。
それを使って、 SDK のライブラリが WebSocket で通信を行うよう。
音声や画面共有など、それぞれで URL が発行されるよう。
React 用コンポーネント
React の場合、コンポーネントが用意されているらしい。
ここでサンプルが見れる。
このコード読んでいるときに初めて知ったが、このライブラリが UI に関する共通 props を提供してくれて便利そう。
チャット機能
ただ、よく調べると、Meeting API の AudioVideo にリアルタイムチャットのコネクションを貼るメソッドが準備されていた。
ミーティングのコネクションが確立すると、RealtimeController のメソッド経由で subscribe することができる。
例として、 React のコードを載せる。
Provider として定義し、マウント時に subscribe を開始し、メッセージの送信を各コンポーネントに渡してあげればいいのではないかと考えた。
こちらのコードはサンプルの TypeScript のコードを流用している。
code:js
const MessagingProvider = ({children}: Props) => {
const audioVideo = useAudioVideo();
const meetingManager = useMeetingManager();
// 初期化
useEffect(() => {
audioVideo.realtimeSubscribeToReceiveDataMessage(
messagingConfig.dataMessageTopic,
receiveNewMessage
);
return () => {
audioVideo.realtimeUnsubscribeFromReceiveDataMessage(
messagingConfig.dataMessageTopic
);
}
}, []);
const receiveNewMessage = (dataMessage: DataMessage) => {
// ...
}
const sendMessage = (input: string) => {
audioVideo.realtimeSendDataMessage(
messagingConfig.dataMessageTopic,
input,
messagingConfig.dataMessageLifetimeMs
);
receiveNewMessage(
new DataMessage(
Date.now(),
messagingConfig.dataMessageTopic,
new TextEncoder().encode(input),
meetingManager.meetingSession.configuration.credentials.attendeeId,
meetingManager.meetingSession.configuration.credentials.externalUserId,
)
)
}
const providerValue = {
receiveNewMessage,
sendMessage,
};
return (
<MessagingContext.Provider value={providerValue}>
{children}
</MessagingContext.Provider>
);
}
こちらの記事が参考になった。
Slack みたいなチャットツールを作るなら、このサンプルコードが参考になる。
録画機能
ECS をキックして、コンテナ内で firefox ブラウザを使い、画面を開いているよう。
デプロイすれば、あとは URL を指定すればそのまま使えそう。
と思ったら、昨年メディアパイプラインで、この録画処理もサービスに含まれるようになった。
こちらは自分でインフラを作る必要はなく、コード上からパイプラインを開始すればいいが、デフォルトの出力は 5 秒ごとのチャンクされたデータなので、それを結合する必要がある。
こちらのサンプルで、 EventBridge からイベントを受け取り、バッチ処理を実行するサンプルが公開されている。
今までは、音声、動画、画面キャプチャ、をそれぞれ分割して出力されていたが、 CompositedVideo オプションを指定することで MediaCapture 側で音声と動画をまとめて出力してくれる。
ただ、 Ruby SDK で使う場合は ChimeSDK クラスではなく、ChimeSDKMediaPipelines クラスを使う必要がある。
SIP
SIP はセッション開始プロトコルで、Chime の場合 Direct Connect みたいなサービスで電話番号を発行すると使えるよう。