AOQ を使用して qwen-audio-3.0-tts-flash に接続し、テキストをセグメントに分割して送信し、合成された音声をリアルタイムで再生します。クライアントコードには Android Java を使用します。
ソリューションの概要
qwen-audio-3.0-tts-flash は、AOQ 推論イベントプロトコルをサポートしています。このチュートリアルでは、このモデルを使用して、AOQ を介したストリーミング音声合成をデモンストレーションします。クライアントは、データトラックを介して run-task、continue-task、finish-task を送信します。サービスは、オーディオトラックを介してオーディオをストリーミングし、データトラックを介してタスクイベントを返します。
1 つのタスクには、複数の continue-task イベントを含めることができます。完全な文は迅速に合成されます。不完全な文は、後続のテキストによって完全な文になるか、クライアントが finish-task を送信するまでバッファリングされたままになります。このアプローチは、モバイルでの再生、分割された長文テキストの入力、および低レイテンシーの音声出力に適しています。
前提条件
- Alibaba Cloud Model Studio を有効化し、「APIキーの取得と設定」に従ってください。API キーはアプリケーションサーバーにのみ保存してください。クライアントコードに含めたり、コードリポジトリにコミットしたりしないでください。
- アプリケーションがデプロイされているリージョンの AOQ エンドポイントを確認してください。選択ガイダンスについては、「リージョン、デプロイ範囲、およびエンドポイントの選択」をご参照ください。
- 「SDKのダウンロード」で説明されているように、最新の AOQ クライアント SDK をダウンロードしてください。
- Qwen-Audio-TTS の AOQ 認証手順に従って AppServer を構築します。新しい接続のたびに、クライアントは AppServer から新しい接続認証情報を取得する必要があります。
SDKのインポート
開発プラットフォーム用の SDK をインポートしてください。クライアントの実装には Android Java を使用します。他のプラットフォームでも同じインターフェースとイベントフローが提供されます。このチュートリアルでは PCM オーディオストリームを使用します。アプリケーションが Opus を選択した場合は、「SDKのダウンロード」のトピックで説明されているように、対応するプラグインをインポートしてください。
- Android
- iOS
- HarmonyOS
- Linux (Python)
- AoqClientSdk-release.aar を app/libs に配置し、app/build.gradle で依存関係と SDK がサポートする ABI を設定してください:
- AndroidManifest.xml で次の権限を宣言してください:
- このシナリオでは、マイクやカメラの権限は必要ありません。
デモの試用
Alibaba Cloud Model Studio の Android デモを使用すると、AOQ 接続を迅速に検証できます。APK をダウンロードし、API キーと workspaceId を設定して、選択したモデルを試してください。
次の QR コードをスキャンしてデモをダウンロードしてください:

実装フロー
- アプリケーションサーバーは、推論トークン URL から qwen-audio-3.0-tts-flash の AOQ 接続パラメーターを取得します。
- クライアントはデータトラックをパブリッシュし、オーディオトラックとデータトラックをサブスクライブし、run-task で選択した出力オーディオフォーマットに合わせて SDK デコーダーを設定します。
- クライアントはローカルプレーヤーを起動し、AOQ に接続します。接続が成功した後、新しい task_id を使用して run-task を送信します。
- task-started を受信した後、クライアントはアプリケーションが必要とするペースで 1 つ以上の continue-task テキストセグメントを送信します。
- すべてのテキストを送信した後、クライアントは finish-task を送信します。サービスは残りのオーディオを返し、最後に task-finished を返します。
- task-finished を受信した後、同じ AOQ 接続で新しい task_id を使用して別のタスクを開始するか、エンジンを切断して破棄します。

アプリケーションサーバーからのトークン取得
アプリケーションサーバーで DASHSCOPE_API_KEY を設定し、選択したリージョンのエンドポイントにリクエストを送信してください。clientIp は、クライアントの実際のパブリック IP アドレスです。このフィールドはオプションですが、指定すると、サービスが適切なリレーエンドポイントを割り当てるのに役立ちます。
応答フィールド | SDKフィールド |
aoqTokenForClient | AoqConnectConfig.token |
sid | AoqConnectConfig.sid |
clientRelayCertFingerprint | AoqConnectConfig.certFingerprint |
clientRelayEndpoints | AoqConnectConfig.relayEndpoints |
extraInfo.workspaceIdHash | AoqConnectConfig.workspaceIdHash |
Androidクライアントの実装
クライアントがアプリケーションサーバーから AoqConnectConfig を取得した後、次の手順に従って Android でストリーミング音声合成を実装してください。
1. エンジンの作成とコールバックの登録
シングルトン AOQ エンジンを作成し、接続イベントとデータトラックイベントのコールバックを登録します。接続コールバックで接続準備状態を維持し、タスクイベントをアプリケーションのステートマシンに渡します。
2. オーディオ再生の開始
TTS はマイクのオーディオをキャプチャしません。ローカルプレーヤーのみを初期化します。スピーカーまたはイヤーピースをデフォルトの出力として選択します。SDK は、オーディオトラックからサーバーのオーディオを自動的に再生します。
3. デコーダーとトラックの設定、および接続
run-task で選択した出力オーディオフォーマットに合わせて SDK デコーダーを設定します。次に、データトラックをパブリッシュし、オーディオトラックとデータトラックをサブスクライブします。次の値は、このチュートリアルの PCM の例です。アプリケーションサーバーのトークン応答から AoqConnectConfig フィールドに値を入力します。
4. sendDataMsgを呼び出してrun-taskイベントを送信
接続が成功したら、新しい UUID task_id を生成し、モデル、ボイス、テキストタイプ、オーディオフォーマット、およびサンプルレートを設定します。オプションのパラメーターについては、「クライアントイベント」をご参照ください。
5. sendDataMsgを呼び出してcontinue-taskイベントを送信
task-started を受信した後にのみ continue-task を送信してください。1 つのタスクには複数のセグメントを含めることができます。各イベントは最大 20,000 文字をサポートし、タスク全体では合計で最大 200,000 文字をサポートします。後続のセグメントを送信するか、タスクを迅速に終了してください。固定の接続タイムアウト値に依存しないでください。
6. サーバーイベントの処理
onDataMsg で、header.event を読み取ってタスクの状態を維持し、障害を処理してください。result-generated は文が合成されたことを示しますが、オーディオは引き続きオーディオトラックを介して返されます。すべてのフィールドについては、「サーバーイベント」をご参照ください。
7. sendDataMsgを呼び出してfinish-taskイベントを送信
すべてのテキストを送信した直後に、finish-task を送信して、サービスによってバッファリングされた不完全なテキストを合成し、task-finished を待ってください。詳細については、「クライアントイベント」をご参照ください。
8. エンジンの切断と破棄
finish-task を送信した直後に切断しないでください。task-finished または task-failed を受信した後、後続のタスクが開始されない場合は、エンジンを切断して破棄してください。SDK は自動的にオーディオプレーヤーを閉じます。
主要なサーバーイベント
イベント | 説明 |
task-started | タスクが開始され、continue-task を送信できます |
result-generated | 完全な文が合成され、そのオーディオがオーディオトラックを介して返されます |
task-finished | バッファリングされたすべてのテキストが処理され、タスクは完了です |
task-failed | タスクが失敗しました。エラーコードとメッセージを読み取ってください |
完全な例
次のクラスは、アプリケーションサーバーのトークン応答からマッピングされた AoqConnectConfig を受け取ります。接続が成功したら、synthesize(text, voice) を呼び出してください。本番環境では、権限、UI の状態、および再接続ロジックを追加してください。
実行と検証
- テキストは task-started を受信した後にのみ送信されます。
- 完全な文のオーディオは、オーディオトラックを介して継続的に再生されます。不完全な文は finish-task の後に合成されます。
- すべてのオーディオが完了した後に task-finished が受信されます。その後、新しい task_id を使用して別のタスクを開始できます。
適用シナリオ
1つの接続での複数タスク
task-finished を受信した後、同じ AOQ 接続で新しい task_id を使用して別の run-task を送信できます。接続がアクティブな間は、新しいトークンは必要ありません。接続が閉じられた場合は、新しい接続認証情報を取得してください。
ボイスの変更
各 run-task では、parameters.voice でシステムボイスまたは有効な voice_id を選択できます。そのため、同じ接続でタスク間でボイスを変更できます。
スピーカーまたはイヤーピース
AoqAudioPlaybackConfig.isDefaultSpeaker を使用してデフォルトの出力を設定し、接続がアクティブな間に enableSpeakerphone を呼び出して切り替えることができます。
トラブルシューティング
問題 | 解決策 |
接続は成功するが、タスクが開始されない | 認証情報が推論トークン URL から取得されていることを確認し、run-task のモデル名、task_id、およびデータトラックがパブリッシュされていることを確認してください。 |
continue-taskが拒否される | task-started を待機し、run-task、continue-task、および finish-task で同じ task_id を使用してください。 |
タスクは成功するが、オーディオが再生されない | オーディオトラックがサブスクライブされていること、およびプレーヤーが実行中であることを確認し、SDK デコーダーが run-task で選択した出力オーディオフォーマットと一致することを確認してください。 |
最後のテキストにオーディオがない | すべてのテキストを送信した後に finish-task を送信し、切断する前に残りのオーディオと task-finished を待機してください。 |