Amazon Web Services ブログ
Amazon Chime SDK for JavaScriptでオーディオやコンテンツを会議で共有する方法
バーチャル会議では参加者は通常の音声やビデオに加えて、リッチメディアを共有したいというお客様の要望を聞きます。Amazon Chime SDKは、アプリケーションやブラウザからのメディアを会議で共有することを可能にします。例えば、オンライン・フィットネス・クラスの音楽などです。オーディオやビデオはローカルコンピュータ、ローカルメディアファイル、ブラウザタブ、またはインターネット上の他のソースから共有できます。
しかし、音声やビデオのソースは必ずしも他の参加者と同条件で共有できる状態にあるとは限りません。音声の音量が大きすぎたり小さすぎたりして、リアルタイムに調整する必要があるかもしれません。また、ビデオやプレゼンテーションをトリミングしたり、回転させたりする必要があるかもしれません。
よくお客様から聞くのは講師やプレゼンターが話している間、あるいは翻訳者がライブで翻訳している間に、音楽やビデオのオーディオトラックの音量を一時的に下げることです。この作業をダッキングと呼びます。Amazon Chime SDK for JavaScriptでは、Webオーディオとビデオの変換パイプラインを利用して、これらの手順を表現するトランスフォームデバイスを定義することができます。
このブログ記事ではマイクの入力とコンテンツの共有音声に Webオーディオ トランスフォームを適用する方法を紹介します。さらに、このロジックをダッカーに拡張して、ユーザーが話している間にコンテンツ共有の音量を自動的に下げるために使用します。
前提条件
- Building a Meeting Application using the Amazon Chime SDKに記載されているようにAmazon Chime SDKをアプリケーションに統合する方法の基本を理解していること。
meetingV2
デモアプリケーションをお客様の開発ツールに組み込み、実行していること。- 1台のデバイスでテストする場合は、ヘッドフォンと音声出力の選択をサポートするブラウザ(Google Chromeなど)が必要です。
注:デモコードをデプロイして実行すると、AWSの料金が発生する場合があります。
ライセンス
このブログ記事に掲載されているコードは、amazon-chime-sdk-jsリポジトリの他のコードと同様に、Apache License 2.0の条件でライセンスされています。
はじめに
Amazon Chimeが他の参加者とオーディオを交換するために使用するマイク入力、オーディオエレメント出力、およびWebRTCレイヤーは、すべてウェブのmedia stream抽象化を利用して、アプリケーション内のオーディオの通過を定義されます。各ストリームは、オーディオまたはビデオの複数のトラックで構成されています。
Web Audioは入力ストリームを、audio context内のaudio nodeのグラフに接続するWeb技術です。これらのノードはオーディオトラックの変換や生成に使用できます。各ノードは少なくとも1つの入力または少なくとも1つの出力を持ち、多くの場合その両方を持ちます。オーディオノードについては、MDNのAudioNode
ドキュメントで詳しく説明されています。Amazon Chime SDKは、ビデオの処理についても同様のコンセプトを提供しています。詳しくは、Video Processorのドキュメントをご覧ください。
Web Audio を使用して、マイク入力の音量を調整できる音声変換デバイスを定義し、MeetingV2
デモを使用して Web ブラウザでテストします。
同じ手法でデモを修正してコンテンツ共有音声の音量を調整し、デモの既存のリアルタイムボリュームオブザーバーにリンクして音量を自動調整します。
シンプルなオーディオトランスフォームの定義と使用
Amazon Chime SDK for JavaScriptでは、Web Audioノードをマイクの入力に適用するために必要な作業の多くが実装されています。AudioTransformDevice
を実装した JavaScript クラスは、入力オーディオを変更する別のデバイスやオーディオノードのグラフの制約に対する変更を定義することができ、残りの処理はデバイスコントローラが行います。SingleNodeAudioTransformDevice
抽象クラスを使用すれば、シンプルに1つのオーディオノードに対してトランスフォームを定義できます。
音量を調整する AudioTransformDevice
を作成するにはGainNode
を使用します。ゲインノードは1つのストリームを入力として受け取り、音量を調整して、1つのストリームを出力として放出します。オーディオトランスフォームデバイスは、GainNodeの設定を調整するメソッドを公開しています。アプリケーションコードは、マイクデバイスを使用する場合と同様に、DeviceController.chooseAudioInputDevice
を使用して、新しいトランスフォームデバイスのインスタンスを直接選択できます。
新規ファイル meetingV2/audiotransform/VolumeTransformDevice.ts
を作成し、以下のコードを記述します。
meetingV2.ts
に上述のクラスをインポートして、デモアプリケーションで利用できます。
selectAudioInputDevice
の上にコードの一部を追加します。
リビルドしてリローンチします。
ヘッドホンをつけて、2つのブラウザウィンドウからテスト会議に参加します。「Web Audio」のチェックボックスにチェックを入れてください。
片方のウィンドウをミュートにして、もう片方のウィンドウでコンソールを開きます(Firefoxの場合は「ツール」→「Web開発者」→「Webコンソール」、Chromeの場合は「表示」→「開発者」→「JavaScriptコンソール」)。以下のように音量を調整します。話をするともう一方のウィンドウからの出力で音量が変化するのがわかります。
この例は、要点を説明しておりこのトランスフォームデバイス用のユーザーインターフェースをどのように構築するかの詳細はここでは説明しません。さらに詳細を見るために、HTMLに入力スライダーを追加することができます。
window
オブジェクトのsetVolume
関数を格納する代わりに、入力の変更ハンドラにアタッチします。
アプリケーションにはVue、React、jQueryなどのフレームワークが使われていると思いますが、コンセプトは同じで、入力要素の変化を関連付けて、GainNode
でlinearRampToValueAtTime
を呼び出すまでの流れです。
コンテンツ共有の音量変更
Google Chromeをはじめとする一部のブラウザでは、タブ内で再生されている音声とそのビジュアルコンテンツを共有したり、コンピュータのスピーカーから再生されている音声とデスクトップ全体を共有したりすることができます。Amazon Chime SDKではコンテンツ共有を利用して、プレゼンテーション、ビデオ、音楽などを他の参加者と共有することができます。
マイクやカメラの入力と同様に、コンテンツ共有にはmedia streamを使用します。音声付きのコンテンツ共有の場合、ストリームには音声トラックとビデオトラックの両方が含まれます。
Amazon Chime SDKは、コンテンツ共有にAudioTransformDevice
トランスフォームを直接適用することをサポートしておらず、Web Audioノードはビデオトラックを通過しません。代わりに、AudioTransformDevice
のコードを翻訳してオーディオストリームに直接作用させ、結合されたストリームをトラックに分離し、オーディオトランスフォームを適用して、再び結合して使用することができます。
meetingV2/audiotransform/volume.ts
という新しいファイルを作成します。このファイルに、ビデオトラックとオーディオトラックの両方を含むストリームにAudioNode
を適用するヘルパー関数を定義します。
ヘルパーを使って、gain nodeにコンテンツ共有ストリームを適用します。
meetingV2.tsにaddAudioVolumeControlToStreamをインポートします。
これで、meetingV2.ts
のcontentShareStart
の定義を拡張して、コンテンツ共有ストリームに音量調整機能を追加することができます。1つ目のswitch
ケースを置き換え、2つ目を修正し、ファイルの先頭のインポートブロックにContentShareMediaStreamBroker
のインポートを追加します。
前述のようにリビルドとリローンチを行います。下の例にのように共有タブでオーディオ共有を行います。
先ほど変換したマイク入力と同様に、window.setVolume
を使って、共有タブで再生しているものの音量を調整できるようになりました。
これらの変更をテストする方法の詳細については、後述の「シングルマシンでのテスト」を参照してください。
スピーチ中のコンテンツ共有のダッキング
先ほど追加したコードで、コンテンツ共有のオーディオストリームの音量を調整できるようになりました。この調整のダッキングを実装するためには、ユーザーが話しているときにリアルタイムでトリガーする必要があります。
AudioVideoFacade
インターフェースは、リアルタイム・オブザーバー・インターフェースを公開しています。realtimeSubscribeToVolumeIndicator
を参加者のIDと一緒に使うことで、その参加者の入力音量をモニターすることができます。これは、デモ・アプリが誰が話しているかを示すために使用しているオブザーバーと同じです。
ユーザー自身のAttendeeIdを使用することで、マイクの入力を監視することなく、音声検出のためのきちんとしたインターフェースが得られます。同様の方法は、入力グラフにAnalyserNode
を追加することでも実装できます。ロビービューでは、このようにしてマイク入力のプレビューをアニメーションで表示しています。
ユーザーのマイクにVoiceFocusTransformDevice
を介してAmazon Voice Focusを使用する場合、Amazon Voice Focusはほとんどの非音声を含む環境ノイズを低減するように設計されているため、ボリュームは人間の音声のみを表すべきです。
setVolume
関数の呼び出しは、音量を下げるときには非常に短いランプタイムで、元の音量に戻すときには長いランプタイムで行うことで、応答時間とスムーズさのバランスを取っています。
次のメソッドでは、コンテンツ共有の開始イベントと停止イベントを利用して、動作の有効化と無効化を行います。
この新しいメソッドを使って、会議のデモでcontentShareStart
を再実装することができます。
このコードを導入すると、ユーザーが発言したときにコンテンツのシェアボリュームが自動的にダッキングされるようになります。このコードを使って録音したデモをご紹介します。
Credit: NASA’s Goddard Space Flight Center (the SDO Team, Genna Duberstein and Scott Wiessinger, Producers)
1台のマシンでのテスト
このシナリオを1台のコンピュータでテストすることは可能ですが次のような準備と2つのオーディオ出力デバイスが必要です。内蔵スピーカーとUSBまたはBluetoothヘッドセットがあれば十分です。
Google Chromeで2つのウィンドウを使用し異なるオーディオデバイスを選択できるようにします。1つはプレゼンター用、もう1つはリスナー用になります。またハウリングを防ぐために内蔵のオーディオ機器はミュートにします。
音声出力デバイスの設定
ヘッドセットをコンピュータに接続します。Macの場合ヘッドフォンジャックにヘッドフォンを接続するとOSが自動的にスピーカーを無効にするため、有線のヘッドフォンは使用できません。USBヘッドセット、Thunderboltドックなどの外部オーディオ機器、またはBluetoothヘッドフォンが使用できます。
デバイスを接続したら、Macの内蔵スピーカーがデフォルトのデバイスになっていることを確認します。
macOSではメニューバーの音量インジケーターをクリックし、「内蔵スピーカー」がチェックされていることを確認します。必要に応じて、デバイス名をクリックして切り替えてください。
Windowsでは、設定>システム>サウンドを開き、出力デバイスをドロップダウンメニューから選択してください。
Google Chromeの設定
2つのウィンドウを開き、隣り合って配置します。プレゼンターを左にリスナーを右に配置します。デモアプリをそれぞれのウィンドウに1回ずつ、計2回開きます。まだ会議には参加しないでください。
プレゼンターのウィンドウで、新しいタブを開いてコンテンツを共有します。今回はNASAのビデオを使用しましたが、リズミカルな音楽でも問題ありません。ビデオの再生を開始します。スピーカーから音声が聞こえることを確認してください。
ビルトインオーディオ出力をミュート
次にデフォルトのオーディオデバイスの音量を下げます。ほとんどの場合ミュートキーを押すか、ボリュームスライダをゼロまでドラッグします。これでハウリングを防ぐことができ、複数のデバイスから同時に聞くのではなく、リスナーのコンテンツ共有音声だけを聞くことができます。
ミーティングへの参加
リスナーのデモアプリのタブで、会議に参加し、上部のマイクをクリックして自分をミュートします。スピーカーアイコンの横にあるドロップダウンをクリックし、出力としてヘッドホンまたはヘッドフォンを選択します。
プレゼンターのデモアプリのタブで、同じ会議に参加しますが、音声出力はデフォルトのままで、ミュートされた内蔵スピーカーにします。
あなたが話すとプレゼンターのミュートされていないマイク入力があなたの声を拾い、リスナーのミュートされていないヘッドフォン出力があなたのヘッドフォンで自分の声を聞くことができます。
次にプレゼンターのウィンドウで、カメラボタンをクリックしてコンテンツを共有します。表示されたダイアログボックスでビデオとオーディオを再生しているタブを選択し、左下の「オーディオを共有」チェックボックスをクリックし、右下の「共有」をクリックします。
これで内蔵スピーカーからは何も聞こえなくなりますが、ヘッドフォンからは自分の声と、それまでミュートになっていたコンテンツ共有の音声が聞こえるようになります。話しを始めると、コンテンツ共有音声の音量が一時的に小さくなります。
クリーンアップ
デモ会議の終了は、どちらのデモウィンドウでも右上の赤いボタンを忘れずにクリックしてください。開いていたタブを閉じたり、ヘッドフォンを外したり、スピーカーのミュートを解除したりすることができます。
この記事に沿ってデモのサーバーレスアプリケーションをデプロイした場合、将来的なコストの発生を避けるために、CloudFormationスタックを削除することを忘れないでください。
結論
このブログ記事では、Web Audio APIを使ってマイク入力のオーディオトランスフォームを定義する方法と、そのトランスフォームを拡張してコンテンツ共有のオーディオに適用する方法を紹介しました。この2つをmeetingV2
のデモに組み込み、さらにAmazon Chime SDKで利用可能なリアルタイムAPIを使用してスピーチの音量を監視することでダッキングを実装しました。最後に、2つのブラウザウィンドウで2つのオーディオデバイスを使用してテストしました。
これらの機能を自分のアプリケーションに拡張して、ボリュームコントロールを構築したり、他の種類のトランスフォーム(空間オーディオ用のパンナーノード、ディストーション、リバーブ、フィルタリング、コンプレッション、さらにはプログラムによるオーディオの生成など)を試してみましょう。MDNのWeb Audio APIドキュメントには、Web Audioができることについての概要が記載されています。
Amazon Chime SDKのドキュメントでは、音声変換デバイスやこれらのインターフェースと技術を使用してノイズ抑制を実装するAmazon Voice Focusについて詳しく知ることができます。ご質問やご提案がありましたら、コメント欄またはGitHub issuesからご連絡ください。
著者について
Richard Newman はAmazon Chime チームのPrincipal Engineerです。テレフォニーとWebブラウザの構築に精通しています。
参考リンク
AWS Media Services
AWS Media & Entertainment Blog (日本語)
AWS Media & Entertainment Blog (英語)
AWSのメディアチームの問い合わせ先: awsmedia@amazon.co.jp
※ 毎月のメルマガをはじめました。最新のニュースやイベント情報を発信していきます。購読希望は上記宛先にご連絡ください。
翻訳は BD山口とSA小林が担当しました。原文はこちらをご覧ください。