このチュートリアルでは、Androidを用いてAOQ Client SDKとqwen3.8-livetranslate-flash-realtimeを統合し、リアルタイム音声翻訳を実現する方法を示します。他のプラットフォームでも、対応するSDKメソッドを用いた類似した統合およびモデルイベント処理フローが適用されます。以下に示すすべてのクライアントサイドの例はJavaで記述されています。
モデルの機能は、リアルタイム音声・音声動画翻訳をご覧ください。メディアとモデルイベントの役割分担は、AOQ アクセスをご覧ください。
SDKのダウンロード
AOQ Client SDKおよびOpus音声プラグインについては、SDKダウンロードをご参照ください。このチュートリアルの音声送信の例ではOpusを使用するため、プラットフォームに対応するプラグインも必ずインポートしてください。対応地域、対応言語、料金、レート制限については、リアルタイム音声および音声/動画翻訳をご参照ください。
SDKのインポート
- Android
- iOS
- HarmonyOS
AoqClientSdk-release.aarをapp/libs/に配置します。libPluginOpus.soはABIに応じてapp/libs/armeabi-v7a/およびapp/libs/arm64-v8a/に配置します。app/build.gradleで依存関係を宣言します:AndroidManifest.xmlで権限を宣言します:RECORD_AUDIO権限を要求し、ユーザーの承認を得てください。音声のみの翻訳にはカメラ権限は不要です。視覚的強化を有効化する場合にのみ、CAMERAを宣言および要求してください。Javaの例では、以下のインポートを使用します:AppServer経由でのトークン取得
Model StudioのAPIキーをクライアント側に保存しないでください。AppServerは、対応するリージョンおよびワークスペースのAPIキーを用いて、各翻訳接続ごとに一時的な資格情報を要求します。AppServerは、アプリケーションの認証を通過したクライアントに対してHTTPS経由で資格情報を返します。
Qwen-LiveTranslate-Realtime の AOQ 認証手順に従って AppServer を構築します。リアルタイム翻訳は Realtime プロトコルを使用します。認証情報の要求時には、次を指定してください。
BAILIAN_ENDPOINTをワークスペースのエンドポイント({WorkspaceId}.cn-beijing.maas.aliyuncs.comまたは{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com)に設定してください。DASHSCOPE_API_KEYはサーバーサイドの環境変数またはシークレット管理サービスから読み込んでください。
clientIpを含めてください。
レスポンスフィールドをクライアント側のAoqConnectConfigにマッピングします:
| ゲートウェイレスポンスフィールド | SDKフィールド | 説明 |
|---|---|---|
aoqTokenForClient | token | この接続のための一時トークン |
sid | sid | このセッションの識別子 |
clientRelayCertFingerprint | certFingerprint | 返されたままの証明書フィンガープリントを正確に使用してください |
clientRelayEndpoints | relayEndpoints | 完全なアクセスポイントリストをSDK構造に変換してください |
extraInfo.workspaceIdHash | workspaceIdHash | 返された値を使用してください。値が存在しない場合は、SDKの要件に従ってください |
リアルタイム音声翻訳の実装
インタラクションフロー

エンジンの作成およびコールバックの設定
createEngineを呼び出してエンジンを作成し、接続ステータス、Dataメッセージ、およびエラーのコールバックを登録します。アプリケーションは、セッション中を通してエンジンおよびリスナー・オブジェクトを保持する必要があります。
AoqClientListenerを実装し、エンジン作成時にこれを渡します。
音声キャプチャおよび再生の開始
マイク権限を取得した後、音声キャプチャおよび再生を準備します。キャプチャ開始前に音声送信を無効化してください。これにより、接続後にエンジンが自動的にメディアを送信するのを防ぎます。
キャプチャを開始しても、モデルが音声を受信できる状態になるわけではありません。session.updatedを受信し、送信を正常に有効化した後にのみ、ユーザーに話すよう促してください。このチュートリアルでは、接続前の音声バッファリングは実装していません。
コーデックの設定および接続の確立
主なシナリオでは、以下のトラックが必要です:
| 方向 | トラック | 目的 |
|---|---|---|
| Publish | Audio | モデルへ音声を送信 |
| Publish | Data | セッション設定および完了イベントを送信 |
| Subscribe | Audio | 翻訳された音声を受信 |
| Subscribe | Data | 原文テキスト、翻訳テキスト、およびステータスイベントを受信 |
connectからの成功した戻り値は、呼び出しが受理されたことを意味します。モデル設定を送信する前に、onConnectionStatusChangeが成功した接続を報告するのを待ってください。
翻訳セッションの設定
接続後に、Dataトラックを介して以下のsession.updateイベントを送信します。この設定ではデフォルトの音声を使用し、ボイスクローンは有効化しません:
session.updateパラメーターについては、リアルタイム翻訳クライアントイベントをご参照ください。
JSONをUTF-8バイトとしてエンコードし、sendDataMsgで送信します。
session.updatedを受信後のメディア送信の有効化
onDataMsgでイベントタイプを解析します。
以下のスニペットは制御イベントをルーティングします。サーバーイベントをご参照ください。session.finishedを受信した後、アプリケーションの完了状態を設定し、「切断およびエンジンの破棄」で説明されている解放メソッドを使用してクリーンアップを完了します。
AOQ と WebSocket の違い:このサンプルでは Audio トラックで音声を直接送受信します。同じ音声を重複してアップロードする
input_audio_buffer.append の送信や、WebSocket のサンプルをそのまま使用し、response.audio.delta の受信時に別のプレイヤーで再生することは避けてください。翻訳音声は SDK の音声サブスクリプションとプレイヤーが処理します。Data トラックは字幕とモデルイベントに使用します。メディアと Data トラックの使い方は、AOQ アクセスをご覧ください。入力の終了および最終翻訳の待機
ユーザーが翻訳を停止した場合、以下の順序で処理してください:
- 新しい入力が送信されないように、キャプチャを停止します。
- 入力を確定した後、アップストリーム音声を無効化し、
session.finishを1回送信します。AOQ接続、Dataサブスクリプション、および音声再生は有効なままにしてください。 - 最終的な原文テキスト、翻訳テキスト、および翻訳音声の受信を継続します。
session.finishedを待ってください。 - ローカル再生の完了ポリシーに従って、切断およびリソースの解放を行います。
session.finishの送信要件については、リアルタイム翻訳クライアントイベントをご参照ください。session.finishedのフィールドおよび意味については、リアルタイム翻訳サーバーイベントをご参照ください。
切断およびエンジンの破棄
session.finishedを受信した後、サーバーはこのセッションの処理を終了しました。これは、ローカルスピーカーが最後の音声セグメントの再生を終了したことを意味するものではありません。 アプリケーションがすべての翻訳音声を再生する必要がある場合、以下のメソッドを実行する前にローカル再生を完了させてください。