AOQ を使用して qwen-audio-3.0-realtime-plus に接続し、サーバーサイド VAD を使用して低遅延のリアルタイム音声会話を構築します。クライアントコードは Android Java を使用します。
ソリューションの概要
Qwen-Audio は、音声アシスタント、カスタマーサービス、AI コンパニオンなどの低遅延シナリオ向けのエンドツーエンドのリアルタイム音声対話モデルです。AOQ は、音声とイベントを別々のトラックで転送します。音声トラックはマイクからの PCM アップリンクとモデルからの PCM ダウンリンクを伝送し、データトラックはリアルタイムのプロトコルイベントを伝送します。
このチュートリアルでは、server_vad を使用します。クライアントは継続的に音声を送信し、サービスはユーザーが話し始めたときと話し終えたときを検出し、応答をトリガーします。
前提条件
- Model Studio をアクティブ化し、「API キーの取得と設定」を参照してください。API キーはアプリケーションサーバーにのみ保存してください。クライアントコードに含めたり、コードリポジトリにコミットしたりしないでください。
- アプリケーションがデプロイされているリージョンの AOQ エンドポイントを確認してください。選択ガイダンスについては、「リージョン、デプロイスコープ、エンドポイントの選択」をご参照ください。
- 「SDK のダウンロード」で説明されているように、最新の AOQ クライアント SDK をダウンロードしてください。
- Qwen-Audio-Realtime の AOQ 認証手順に従って AppServer を構築します。新しい接続のたびに、クライアントは AppServer から新しい接続認証情報を取得する必要があります。
SDK のインポート
開発プラットフォーム用の SDK をインポートしてください。クライアントの実装には Android Java を使用します。他のプラットフォームも同じインターフェースとイベントフローを提供します。このチュートリアルでは PCM 音声ストリームを使用します。Opus エンコーディングはプラグインによって提供されます。アップリンクで Opus を使用する場合は、Opus プラグインをインポートしてください。
- Android
- iOS
- HarmonyOS
- Linux (Python)
- AoqClientSdk-release.aar を app/libs に配置し、app/build.gradle で依存関係と SDK がサポートする ABI を設定してください。
- AndroidManifest.xml で次の権限を宣言してください。
- 対応するデバイスを使用する前に、ランタイムで RECORD_AUDIO 権限を要求してください。
デモの試用
Alibaba Cloud Model Studio の Android デモを使用して AOQ の接続性を素早く検証するには、APK をダウンロードし、API キーと workspaceId を設定して、選択したモデルをお試しください。
次の QR コードをスキャンしてデモをダウンロードしてください。

実装フロー
- アプリケーションサーバーは、リアルタイムトークン URL から、qwen-audio-3.0-realtime-plus への現在の AOQ 接続用の認証情報を取得します。
- クライアントは、選択したモデルとアプリケーションの音声フォーマットに合わせて、SDK のアップリンクエンコーダーとダウンリンクデコーダーを設定します。
- クライアントは、録音および再生デバイスを初期化し、AoqConnectConfig を作成します。現在の接続の認証情報フィールドを入力し、パブリッシュおよびサブスクライブする音声トラックとデータトラックを設定します。クライアントは、音声トラックの送信を無効にしたまま
connectを呼び出して AOQ 接続を確立します。 - 接続が確立された後、クライアントは
session.updateを送信します。session.updatedを受信した後にのみ、音声トラックを有効にします。 - サーバーサイド VAD は、ターンの境界を自動的に判断します。モデルの音声は音声トラックで再生され、会話イベントはデータトラックで返されます。
- 終了するには、エンジンを切断して破棄してください。SDK は自動的にオーディオデバイスを閉じます。

アプリケーションサーバーからのトークンの取得
アプリケーションサーバーで DASHSCOPE_API_KEY を設定し、選択したリージョンのエンドポイントにリクエストを送信してください。clientIp はクライアントの実際のパブリック IP アドレスです。このフィールドはオプションですが、指定するとサービスが適切なリレーエンドポイントを割り当てるのに役立ちます。
clientIp を省略してください。connect を呼び出すたびに、新しい Token を要求する必要があります。API キーは AppServer にのみ保存してください。
レスポンスフィールド | SDK フィールド |
aoqTokenForClient | AoqConnectConfig.token |
sid | AoqConnectConfig.sid |
clientRelayCertFingerprint | AoqConnectConfig.certFingerprint |
clientRelayEndpoints | AoqConnectConfig.relayEndpoints |
extraInfo.workspaceIdHash | AoqConnectConfig.workspaceIdHash |
Android クライアントの実装
各接続の前に、クライアントはアプリケーションサーバーから新しい接続認証情報を取得し、AoqConnectConfig を作成してください。トークンのレスポンスフィールドをマッピングし、パブリッシュおよびサブスクライブトラックなどのクライアント側の接続設定を追加してください。Android でリアルタイム音声会話を実装するには、次の手順に従ってください。
1. エンジンの作成とコールバックの登録
シングルトンの AOQ エンジンを作成し、イベントコールバックを登録してください。接続が成功した後でセッションを設定し、サーバーイベントを UI とアプリケーションのステートマシンにディスパッチしてください。
2. オーディオコーデックの設定
選択したモデルとアプリケーションの音声フォーマットに合わせて、SDK のアップリンクエンコーダーとダウンリンクデコーダーを設定してください。以下の値はこのチュートリアルの PCM の例であり、アプリケーションの音声フォーマットを制限するものではありません。
3. トラックの設定と接続
SDK インターフェースを使用して、オーディオキャプチャと再生を開始してください。現在のアプリケーションサーバートークンのレスポンスを AoqConnectConfig の認証情報フィールドにマッピングし、publishTracks と subscribeTracks で音声トラックとデータトラックを設定してください。connect を呼び出すときは、音声トラックの送信を無効にしたままにしてください。session.updated を受信した後にのみ送信を有効にしてください。
4. session.update の送信
接続が成功した後、出力モダリティ、音声、音声フォーマット、指示、および VAD を設定してください。input_audio_format と output_audio_format の両方に pcm を使用してください。サンプルレートは SDK のコーデック設定によって決まります。すべてのパラメーターについては、「クライアントイベント」をご参照ください。
5. session.updated 後のアップリンクの有効化
session.updated は、セッション設定がアクティブであることを示します。この時点で初めて音声トラックの送信を有効にし、それ以前にキャプチャされた音声がモデルに送信されないようにします。
6. サーバーイベントの処理
onDataMsg で、type を使用してユーザーとモデルのトランスクリプトを表示し、エラーを処理してください。すべてのイベントフィールドについては、「サーバーイベント」をご参照ください。
7. エンジンの切断と破棄
会話が終了したら、シングルトンエンジンを切断して破棄してください。disconnect または destroy は自動的にオーディオキャプチャと再生を閉じるため、デバイスを個別に停止する必要はありません。
主なサーバーイベント
データトラックのイベントは type で識別されます。クライアントは、以下の主要なイベントを処理する必要があります。完全なイベントスキーマについては、「サーバーイベント」をご参照ください。
イベント | 説明 |
session.created | セッションが作成され、デフォルト設定が返されます |
session.updated | クライアント設定がアクティブになり、音声アップリンクを有効にできます |
input_audio_buffer.speech_started | サービスがユーザーの発話開始を検出します |
input_audio_buffer.speech_stopped | サービスがユーザーの発話停止を検出します |
input_audio_buffer.committed | ターンの音声がコミットされます |
response.created | モデルがレスポンスの生成を開始します |
response.audio_transcript.delta | インクリメンタルなモデルトランスクリプト |
conversation.item.input_audio_transcription.completed | 最終的なユーザートランスクリプトが利用可能になります |
response.done | レスポンスが完了しました |
error | サーバーエラーが発生しました |
完全な例
以下のクラスは、現在の接続の認証情報が入力された AoqConnectConfig を受け取り、オーディオデバイス、パブリッシュトラック、およびサブスクライブトラックの設定を追加します。再接続のたびに新しい認証情報を取得し、新しい接続設定を作成してください。本番環境では、権限、UI の状態、および再接続ロジックを追加してください。
実行と検証
- マイク音声のストリーミングは、
session.updatedを受信した後にのみ開始されます。 - ユーザーが話し終えると、サービスは音声をコミットし、応答を開始します。テキストイベントと音声トラックの音声は継続的に返されます。
一般的なシナリオ
インタラクションモードの変更
無音ベースのターン検出には server_vad を、音響的および意味的なターン検出には smart_turn を使用するか、プッシュツートークの場合は turn_detection を null に設定してください。turn_detection は、最初の音声入力の前にのみ変更できます。モードを変更するには、新しいセッションを確立してください。
音声の変更
最初の session.update で session.voice を設定してください。サポートされているシステム音声はモデルによって異なります。サポートされている音声と音声クローニングについては、「Qwen-Audio リアルタイム音声会話ユーザーガイド」をご参照ください。
スピーカーまたはイヤピース
AoqAudioPlaybackConfig.isDefaultSpeaker を使用してデフォルトの出力デバイスを設定し、セッションがアクティブな間に enableSpeakerphone を呼び出して切り替えてください。
Android でのバックグラウンド通話
Android 10 以降では、foregroundServiceType="microphone|mediaPlayback" を持つフォアグラウンドサービスを使用して、バックグラウンドでのキャプチャと再生を継続してください。アプリがユーザーに表示されている間に開始してください。
トラブルシューティング
問題 | 解決策 |
接続に失敗する | トークンが有効であること、エンドポイントがデプロイリージョンと一致していること、および AoqConnectConfig フィールドが正しくマッピングされていることを確認してください。 |
セッションは確立されたが、応答が返されない | 音声トラックが |
レスポンスに音声がない | 音声トラックがサブスクライブされており、オーディオプレーヤーが実行中であることを確認してから、SDK のダウンリンクデコーダーがモデルの出力音声フォーマットと一致していることを確認してください。 |