次の方法で共有


リアルタイム合成でテキスト読み上げアバターを使用する方法

このハウツー ガイドでは、リアルタイム合成でテキスト読み上げアバターを使用する方法について説明します。 合成アバター ビデオは、システムがテキスト入力を受信した後、ほぼリアルタイムで生成されます。

前提条件

開始する前に、次の前提条件が満たされていることを確認してください:

  • Azure サブスクリプション: 無料アカウントを作成します
  • 音声リソース: Azure portal で音声リソースを作成します。 アバターにアクセスする音声リソースを作成する場合、"Standard S0" 価格レベルを選択します。
  • 音声リソースのキーとリージョン: 音声リソースのデプロイ後、[リソースに進む] を選択し、キーを表示し、管理します。

環境を設定する

リアルタイムのアバター合成を行うには、Web ページで使用する Speech SDK for JavaScript をインストールする必要があります。 詳しいインストール手順については、「Speech SDK のインストール」を参照してください。

さまざまなプラットフォームとブラウザーでのリアルタイム アバターの互換性を次に示します:

プラットフォーム Chrome Microsoft Edge Safari Firefox Opera
Windows Y Y 該当なし Y1 Y
Android Y Y 該当なし Y12 N
iOS Y Y
macOS Y Y Y1 Y

1 通信サービスによる ICE サーバーでは動作しませんが、Coturn で動作します。

2 背景の透明度が機能しません。

テキスト読み上げ言語と音声変換を選択する

音声サービスのテキスト読み上げ機能は、言語と音声の幅広いポートフォリオをサポートしています。 完全なリストを取得したり、音声ギャラリーで試すことができます。

入力テキストに合わせて SpeechConfig の言語または音声を指定し、必要な音声を使用します。 次のコード スニペットは、この手法のしくみを示しています:

const speechConfig = SpeechSDK.SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
// Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
speechConfig.speechSynthesisLanguage = "en-US";
speechConfig.speechSynthesisVoiceName = "en-US-AvaMultilingualNeural";   

すべてのニューラル音声は多言語で、独自の言語と英語で流暢に読み上げます。 たとえば、英語の入力テキストが "テキスト読み上げを試すのが楽しみです" で、es-ES-ElviraNeural を選択した場合、テキストはスペイン語のアクセントの英語で読み上げられます。

入力テキストの言語が音声で読み上げられない場合、Speech サービスでは合成された音声が作成されません。 サポートされているニューラル音声の完全な一覧については、「Azure Cognitive Service for Speech サービスの言語と音声のサポート」を参照してください。

既定の音声は、Voice List API からロケールに従って返される最初の音声です。 話す優先順位は次のとおりです:

  • SpeechSynthesisVoiceName または SpeechSynthesisLanguage を設定していない場合、en-US の既定の音声で読み上げられます。
  • SpeechSynthesisLanguage のみを設定した場合、指定したロケールの既定の音声で読み上げられます。
  • SpeechSynthesisVoiceNameSpeechSynthesisLanguage の両方を設定した場合、SpeechSynthesisLanguage の設定は無視されます。 SpeechSynthesisVoiceName を使用して指定した音声が読み上げられます。
  • 音声要素を音声合成マークアップ言語 (SSML) で設定した場合、SpeechSynthesisVoiceNameSpeechSynthesisLanguage の設定は無視されます。

アバターのキャラクターとスタイルを選択する

サポートされているアバターのキャラクターとスタイルは、ここで見つけることができます。

次のコード スニペットは、アバターの文字とスタイルを設定する方法を示しています:

const avatarConfig = new SpeechSDK.AvatarConfig(
    "lisa", // Set avatar character here.
    "casual-sitting", // Set avatar style here.
);  

リアルタイム アバターへの接続を設定する

リアルタイム アバターは、WebRTC プロトコルを使用してアバター ビデオ ストリームを出力します。 WebRTC ピア接続を介してアバター サービスとの接続を設定する必要があります。

まず、WebRTC ピア接続オブジェクトを作成する必要があります。 WebRTC は、ネットワーク リレーに ICE サーバーに依存する P2P プロトコルです。 音声サービスは、ネットワーク リレー機能を提供し、REST API を公開して ICE サーバー情報を発行します。 そのため、音声サービスから ICE サーバーをフェッチすることをお勧めします。 独自の ICE サーバーを使用するように選択することもできます。

音声サービス エンドポイントから ICE 情報をフェッチする要求の例を次に示します。

GET /cognitiveservices/avatar/relay/token/v1 HTTP/1.1

Host: westus2.tts.speech.microsoft.com
Ocp-Apim-Subscription-Key: YOUR_RESOURCE_KEY

次のコード スニペットは、WebRTC ピア接続を作成する方法を示しています。 ICE サーバー URL、ICE サーバー ユーザー名、および ICE サーバー資格情報はすべて、上記の HTTP 要求のペイロードからフェッチできます。

// Create WebRTC peer connection
peerConnection = new RTCPeerConnection({
    iceServers: [{
        urls: [ "Your ICE server URL" ],
        username: "Your ICE server username",
        credential: "Your ICE server credential"
    }]
})

Note

ICE サーバー URL には、プレフィックス turn (turn:relay.communication.microsoft.com:3478 など) とプレフィックス stun (stun:relay.communication.microsoft.com:3478 など) の 2 種類があります。 前のシナリオ例では、urls の場合、turn プレフィックスを持つ URL のみを含める必要があります。

次に、ピア接続の ontrack コールバック関数でビデオとオーディオ プレーヤーの要素を設定する必要があります。 このコールバックは、接続中に 2 回、ビデオ トラック用に 1 回、オーディオ トラック用に 1 回呼び出されます。コールバック関数では、ビデオとオーディオの両方のプレーヤー要素を作成する必要があります。

次のコード スニペットは、その方法を示しています:

// Fetch WebRTC video/audio streams and mount them to HTML video/audio player elements
peerConnection.ontrack = function (event) {
    if (event.track.kind === 'video') {
        const videoElement = document.createElement(event.track.kind)
        videoElement.id = 'videoPlayer'
        videoElement.srcObject = event.streams[0]
        videoElement.autoplay = true
    }

    if (event.track.kind === 'audio') {
        const audioElement = document.createElement(event.track.kind)
        audioElement.id = 'audioPlayer'
        audioElement.srcObject = event.streams[0]
        audioElement.autoplay = true
    }
}

// Offer to receive one video track, and one audio track
peerConnection.addTransceiver('video', { direction: 'sendrecv' })
peerConnection.addTransceiver('audio', { direction: 'sendrecv' })

第 3 に、Speech SDK を呼び出してアバター シンセサイザーを作成し、ピア接続をパラメーターとしてアバター サービスに接続する必要があります。

// Create avatar synthesizer
var avatarSynthesizer = new SpeechSDK.AvatarSynthesizer(speechConfig, avatarConfig)

// Start avatar and establish WebRTC connection
avatarSynthesizer.startAvatarAsync(peerConnection).then(
    (r) => { console.log("Avatar started.") }
).catch(
    (error) => { console.log("Avatar failed to start. Error: " + error) }
);

リアルタイム API は、アバターのアイドル状態が 5 分続くと切断されます。 アバターがアイドル状態ではなく正常に機能している場合でも、リアルタイム API は 10 分の接続後に切断されます。 リアルタイム アバターを 10 分以上継続的に操作するには、自動再接続を有効にします。 自動再接続を設定する方法については、こちらのサンプル コードを参照してください ("Auto Reconnect"を検索してください)。

テキスト入力から話すアバター ビデオを合成する

上記の手順の後、Web ブラウザーでアバター ビデオが再生されていることがわかります。 アバターはアクティブで、目がまばたき、わずかな体の動きがありますが、まだ話し出しません。 アバターはテキスト入力が読み上げを開始するのを待っています。

次のコード スニペットは、アバター シンセサイザーにテキストを送信し、アバターが話す方法を示しています:

var spokenText = "I'm excited to try text to speech avatar."
avatarSynthesizer.speakTextAsync(spokenText).then(
    (result) => {
        if (result.reason === SpeechSDK.ResultReason.SynthesizingAudioCompleted) {
            console.log("Speech and avatar synthesized to video stream.")
        } else {
            console.log("Unable to speak. Result ID: " + result.resultId)
            if (result.reason === SpeechSDK.ResultReason.Canceled) {
                let cancellationDetails = SpeechSDK.CancellationDetails.fromResult(result)
                console.log(cancellationDetails.reason)
                if (cancellationDetails.reason === SpeechSDK.CancellationReason.Error) {
                    console.log(cancellationDetails.errorDetails)
                }
            }
        }
}).catch((error) => {
    console.log(error)
    avatarSynthesizer.close()
});

エンド ツー エンドの作業サンプルは、GitHub にあります。

リアルタイム アバターの接続を閉じる

リアルタイム アバターを使い終わった後で不要なコストがかからないように、接続を閉じることが重要です。 これにはいくつかの方法があります。

  • ブラウザーの Web ページを閉じると、WebRTC クライアント側のピア接続オブジェクトが解放され、アバター接続は数秒後に自動的に閉じられます。

  • アバターが 5 分間アイドルのままになっていると、接続はアバター サービスによって自動的に閉じられます。

  • 次のコードを実行すると、アバターの接続を事前に閉じることができます。

    avatarSynthesizer.close()
    

    エンド ツー エンドの作業サンプルは、GitHub にあります。

背景の編集

アバターのリアルタイム合成 API は現在、背景画像/ビデオの設定をサポートしていません。また、透明な背景をサポートしておらず、単色の背景の設定のみをサポートしています。 ただし、次のガイドラインに従って、クライアント側で背景のカスタマイズを実装する別の方法があります:

  • アバターのリアルタイム合成 API がサポートする背景色を (マットを簡単にするため)緑に設定します。
  • アバター ビデオと同じサイズのキャンバス要素を作成します。
  • アバター ビデオの各フレームをキャプチャし、ピクセル単位の計算を適用して緑色のピクセルを透明に設定し、再計算されたフレームをキャンバスに描画します。
  • 元のビデオを非表示にします。

この方法を使えば、透明な背景を持つ、動画のように再生されるアニメーション・キャンバスが得られます。 このようなアプローチを示すサンプル コードを次に示します。

透明な背景アバターを作成したら、キャンバスの背後に画像またはビデオを配置することで、背景を任意の画像またはビデオに設定できます。

次のステップ