DashScope Java SDK と qwen3.5-livetranslate-flash-realtime モデルを使用して、音声をリアルタイムで翻訳します。SDK は WebSocket 経由で接続し、音声入力をストリーミングして、翻訳されたテキストと合成音声を返します。
事前準備
- DashScope SDK バージョン 2.22.5 以降をインストールします。
- API キーを取得します。
- API キーを環境変数として設定します:
# Linux / macOS
export DASHSCOPE_API_KEY=<your-api-key>
source ~/.bashrc
# Windows
set DASHSCOPE_API_KEY=<your-api-key>
- Qwen-LiveTranslate モデルの概要で、サポートされている言語と音声を確認します。
重要Alibaba Cloud Model Studio は、中国 (北京) およびシンガポールリージョン向けにワークスペース固有のドメインをリリースしました。新しい専用ドメインは、推論リクエストに対して優れたパフォーマンスと高い安定性を提供します。新しいドメインへの移行を推奨します:
- 中国 (北京):
wss://dashscope.aliyuncs.comからwss://{WorkspaceId}.cn-beijing.maas.aliyuncs.comへ - シンガポール:
wss://dashscope-intl.aliyuncs.comからwss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.comへ
{WorkspaceId} は、Alibaba Cloud Model Studio コンソールの [ワークスペース詳細] ページで確認できるワークスペース ID です。既存のドメインも引き続き完全に機能します。
クイックスタート
接続し、音声を送信し、翻訳されたテキストを受信します:
import com.alibaba.dashscope.audio.omni.*;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.google.gson.JsonObject;
import java.util.Arrays;
// 1. 接続パラメーターを構築します
OmniRealtimeParam param = OmniRealtimeParam.builder()
.model("qwen3.5-livetranslate-flash-realtime")
// 以下はシンガポールリージョンの URL です。{WorkspaceId} を実際のワークスペース ID に置き換えてください。URL はリージョンによって異なります。
.url("wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/realtime")
.apikey(System.getenv("DASHSCOPE_API_KEY"))
.build();
// 2. サーバーイベントを処理するためのコールバックを定義します
OmniRealtimeCallback callback = new OmniRealtimeCallback() {
@Override public void onOpen() { System.out.println("Connected"); }
@Override
public void onEvent(JsonObject message) {
String type = message.get("type").getAsString();
if ("response.audio_transcript.done".equals(type)) {
System.out.println("Translation: " + message.get("transcript").getAsString());
}
}
@Override
public void onClose(int code, String reason) {
System.out.println("Closed: " + code + " " + reason);
}
};
// 3. セッションを開き、音声のストリーミングを開始します
OmniRealtimeConversation conversation = new OmniRealtimeConversation(param, callback);
conversation.connect();
// 4. 翻訳のターゲット言語を設定します
OmniRealtimeConfig config = OmniRealtimeConfig.builder()
.modalities(Arrays.asList(OmniRealtimeModality.AUDIO, OmniRealtimeModality.TEXT))
.translationConfig(OmniRealtimeTranslationParam.builder()
.language("en")
.build())
.build();
conversation.updateSession(config);
// 5. Base64 エンコードされた音声チャンク (PCM 16 kHz, 16-bit, モノラル) を送信します
conversation.appendAudio(audioBase64);
// 6. 完了したらセッションを終了します
conversation.endSession();
リクエストパラメーター
OmniRealtimeParam
WebSocket 接続を確立するために、OmniRealtimeParam.builder() を使用してこれらを構築します。
サンプルコードを表示するにはクリックしてください
OmniRealtimeParam param = OmniRealtimeParam.builder()
.model("qwen3.5-livetranslate-flash-realtime")
// 以下はシンガポールリージョンの URL です。{WorkspaceId} を実際のワークスペース ID に置き換えてください。URL はリージョンによって異なります。
.url("wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/realtime")
// API キーはリージョンによって異なります。API キーを取得するには、https://www.alibabacloud.com/help/model-studio/get-api-key をご参照ください
// 環境変数が設定されていない場合は、次の行をお使いの Model Studio API キーに置き換えてください: .apikey("sk-xxx")
.apikey(System.getenv("DASHSCOPE_API_KEY"))
.build();
パラメーター | タイプ | 必須 | 説明 |
|---|---|---|---|
|
| はい | モデル名。 |
|
| はい | WebSocket エンドポイント。
|
|
| いいえ | 認証用の API キー。設定しない場合は、 |
OmniRealtimeConfig
OmniRealtimeConfig.builder() でこれらを構築し、接続後に conversation.updateSession(config) を呼び出します。
サンプルコードを表示するにはクリックしてください
// カスタム翻訳フレーズを設定します
Map<String, Object> phrases = new HashMap<>();
phrases.put("Inteligencia Artificial", "Artificial Intelligence");
phrases.put("Aprendizaje Automático", "Machine Learning");
OmniRealtimeConfig config = OmniRealtimeConfig.builder()
.modalities(Arrays.asList(OmniRealtimeModality.AUDIO, OmniRealtimeModality.TEXT))
.voice("Cherry")
.inputAudioFormat(OmniRealtimeAudioFormat.PCM_16000HZ_MONO_16BIT)
.outputAudioFormat(OmniRealtimeAudioFormat.PCM_24000HZ_MONO_16BIT)
.InputAudioTranscription("qwen3-asr-flash-realtime")
.translationConfig(OmniRealtimeTranslationParam.builder()
.language("en")
.corpus(OmniRealtimeTranslationParam.Corpus.builder()
.phrases(phrases)
.build())
.build())
.build();
conversation.updateSession(config);
パラメーター | タイプ | 必須 | 説明 |
|---|---|---|---|
|
| いいえ | 出力モダリティ。デフォルト: |
|
| いいえ | 合成音声のボイス。デフォルトのボイスはモデルによって異なります: |
|
| いいえ | 入力音声フォーマット。デフォルト: |
|
| いいえ | 出力音声フォーマット。デフォルト: |
|
| いいえ | 元の音声を文字起こしするための ASR モデル。 |
|
| いいえ | 翻訳設定。下記の OmniRealtimeTranslationParam をご参照ください。 |
|
| いいえ | VAD (音声アクティビティ検出) を有効にするかどうか。 デフォルト値:
|
OmniRealtimeTranslationParam
OmniRealtimeTranslationParam.builder() を使用して、ターゲット言語とカスタム用語を構築します。
サンプルコードを表示するにはクリックしてください
// 翻訳フレーズを設定します
Map<String, Object> phrases = new HashMap<>();
phrases.put("Inteligencia Artificial", "Artificial Intelligence"); // ソース言語の単語:ターゲット言語の翻訳
phrases.put("Aprendizaje Automático", "Machine Learning");
OmniRealtimeTranslationParam translationParam = OmniRealtimeTranslationParam.builder()
.language("en") // ターゲット言語コード
.corpus(OmniRealtimeTranslationParam.Corpus.builder()
.phrases(phrases)
.build())
.build();
パラメーター | タイプ | 必須 | 説明 |
|---|---|---|---|
|
| いいえ | ターゲット言語コード。デフォルト: |
|
| いいえ | ドメイン固有の用語のためのカスタム用語。 |
|
| いいえ | 用語マッピング:キーはソース用語、値はターゲット翻訳です。例: |
主要なインターフェイス
OmniRealtimeConversation
WebSocket 接続と音声ストリーミングのライフサイクルを管理します。
インポート:com.alibaba.dashscope.audio.omni.OmniRealtimeConversation
メソッド | 説明 |
|---|---|
| 接続パラメーターとイベントコールバックを持つ会話インスタンスを作成します。 |
| WebSocket 接続を開きます。session.created および session.updated イベントをトリガーします。 |
| 接続後にセッション構成を更新します。session.updated イベントをトリガーします。必要なパラメーターのみを設定してください。省略されたパラメーターにはデフォルト値が適用されます。 |
| Base64 エンコードされた音声チャンクをサーバーに送信します。サーバーは自動的に発話の境界を検出し、翻訳をトリガーします。 |
| 手動モードでは、 |
| サーバーバッファーからコミットされていない音声データをクリアします。input_audio_buffer.cleared イベントをトリガーします。 |
| セッションを正常に終了します。サーバーは、session.finished を送信する前に、進行中の翻訳を完了します。 |
| タスクを停止し、WebSocket 接続を閉じます。 |
| セッション ID を返します。 |
| 最新のサーバー応答の応答 ID を返します。 |
| 最新の応答の最初のテキスト遅延 (ミリ秒) を返します。 |
| 最新の応答の最初の音声遅延 (ミリ秒) を返します。 |
OmniRealtimeCallback
WebSocket を介して配信されるサーバーイベントを処理します。このクラスを拡張し、各メソッドを実装してイベントを処理します。
インポート:com.alibaba.dashscope.audio.omni.OmniRealtimeCallback
メソッド | パラメーター | 説明 |
|---|---|---|
| なし | WebSocket 接続が確立されたときに呼び出されます。 |
|
| 各サーバーイベントに対して呼び出されます。 |
|
| WebSocket 接続が閉じられたときに呼び出されます。 |
onEvent で受信される一般的なイベントタイプ:
イベントタイプ | 説明 |
|---|---|
| サーバーが音声ストリームで発話を検出しました。 |
| サーバーが発話セグメントの終了を検出しました。 |
| ソース言語の文字起こしが準備完了です。 |
| 翻訳されたテキストが準備完了です。 |
| 翻訳された音声のチャンクが利用可能です。Base64 エンコードされた音声データについては |
| エラーが発生しました。詳細については |
完全な例
この例では、マイクの音声をキャプチャし、リアルタイムで翻訳し、翻訳された音声をシステムスピーカーで再生します。
この例の動作:
- WebSocket を介して Qwen-LiveTranslate に接続します。
- カスタム用語を使用して、スペイン語から英語への翻訳を設定します。
- マイクの音声を 100 ms のチャンクでストリーミングします。
- 元の文字起こしと翻訳されたテキストを出力します。
- 翻訳された音声をスピーカーで再生します。
リアルタイムマイク翻訳のサンプルコード
import com.alibaba.dashscope.audio.omni.*;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.google.gson.JsonObject;
import javax.sound.sampled.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* マイクをリアルタイム音声・動画翻訳モデルで使用する例です。
*/
public class Main {
private static final int INPUT_CHUNK_SIZE = 3200; // 16 kHz、16-bit、モノラル音声の 100 ms
private static final int OUTPUT_CHUNK_SIZE = 4800; // 24 kHz、16-bit、モノラル音声の 100 ms
private static final AtomicBoolean running = new AtomicBoolean(true);
private static SourceDataLine speaker; // スピーカー
public static void main(String[] args) throws InterruptedException {
String apiKey = System.getenv("DASHSCOPE_API_KEY");
if (apiKey == null || apiKey.isEmpty()) {
System.err.println("DASHSCOPE_API_KEY 環境変数を設定してください。");
System.exit(1);
}
// 接続パラメーターを作成します。
OmniRealtimeParam param = OmniRealtimeParam.builder()
.model("qwen3.5-livetranslate-flash-realtime")
.url("wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/realtime")
.apikey(apiKey)
.build();
// コールバックハンドラを作成します。
OmniRealtimeCallback callback = new OmniRealtimeCallback() {
@Override
public void onOpen() {
System.out.println("[接続が確立されました]");
}
@Override
public void onEvent(JsonObject message) {
String type = message.get("type").getAsString();
switch (type) {
case "input_audio_buffer.speech_started":
System.out.println("====== 音声入力が検出されました ======");
break;
case "input_audio_buffer.speech_stopped":
System.out.println("====== 音声入力が終了しました ======");
break;
case "conversation.item.input_audio_transcription.completed":
String originalText = message.get("transcript").getAsString();
System.out.println("[元のテキスト] " + originalText);
break;
case "response.audio_transcript.done":
String translatedText = message.get("transcript").getAsString();
System.out.println("[翻訳結果] " + translatedText);
break;
case "response.audio.delta":
// 翻訳された音声をデコードして再生します。
String audioB64 = message.get("delta").getAsString();
byte[] audioBytes = Base64.getDecoder().decode(audioB64);
if (speaker != null) {
speaker.write(audioBytes, 0, audioBytes.length);
}
break;
case "error":
JsonObject error = message.get("error").getAsJsonObject();
System.err.println("[エラー] " + error.get("message").getAsString());
break;
}
}
@Override
public void onClose(int code, String reason) {
System.out.println("[接続が閉じられました] code: " + code + ", reason: " + reason);
}
};
// セッションを作成します。
OmniRealtimeConversation conversation = new OmniRealtimeConversation(param, callback);
try {
// スピーカーを初期化します (翻訳された音声を再生するため)。
AudioFormat speakerFormat = new AudioFormat(24000, 16, 1, true, false);
DataLine.Info speakerInfo = new DataLine.Info(SourceDataLine.class, speakerFormat);
speaker = (SourceDataLine) AudioSystem.getLine(speakerInfo);
speaker.open(speakerFormat, OUTPUT_CHUNK_SIZE * 4);
speaker.start();
// マイクを初期化します (音声入力をキャプチャするため)。
AudioFormat micFormat = new AudioFormat(16000, 16, 1, true, false);
DataLine.Info micInfo = new DataLine.Info(TargetDataLine.class, micFormat);
if (!AudioSystem.isLineSupported(micInfo)) {
System.err.println("マイクが利用できません。");
System.exit(1);
}
TargetDataLine microphone = (TargetDataLine) AudioSystem.getLine(micInfo);
microphone.open(micFormat);
microphone.start();
// サーバーに接続します。
conversation.connect();
// 翻訳パラメーターを設定します。
Map<String, Object> phrases = new HashMap<>();
phrases.put("Inteligencia Artificial", "Artificial Intelligence");
phrases.put("Aprendizaje Automático", "Machine Learning");
OmniRealtimeConfig config = OmniRealtimeConfig.builder()
.modalities(Arrays.asList(OmniRealtimeModality.AUDIO, OmniRealtimeModality.TEXT))
.voice("Cherry")
.inputAudioFormat(OmniRealtimeAudioFormat.PCM_16000HZ_MONO_16BIT)
.outputAudioFormat(OmniRealtimeAudioFormat.PCM_24000HZ_MONO_16BIT)
.InputAudioTranscription("qwen3-asr-flash-realtime")
.translationConfig(OmniRealtimeTranslationParam.builder()
.language("en")
.corpus(OmniRealtimeTranslationParam.Corpus.builder()
.phrases(phrases)
.build())
.build())
.build();
conversation.updateSession(config);
// シャットダウンフックを登録します。
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
System.out.println("\n[終了中...]");
running.set(false);
microphone.stop();
microphone.close();
speaker.stop();
speaker.close();
try {
conversation.endSession();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
conversation.close(1000, "User stopped");
}));
System.out.println("[リアルタイム翻訳を開始します] マイクに向かって話してください。Ctrl+C で終了します。");
// マイクの音声を継続的にキャプチャして送信します。
byte[] buffer = new byte[INPUT_CHUNK_SIZE];
while (running.get()) {
int bytesRead = microphone.read(buffer, 0, buffer.length);
if (bytesRead > 0) {
conversation.appendAudio(Base64.getEncoder().encodeToString(buffer));
}
}
} catch (NoApiKeyException e) {
System.err.println("API キーエラー: " + e.getMessage());
} catch (Exception e) {
System.err.println("例外が発生しました: " + e.getMessage());
e.printStackTrace();
}
}
}
プレースホルダーを実際の値に置き換えてください:
プレースホルダー | 説明 | 例 |
|---|---|---|
| Model Studio API キー |
|
関連トピック
- Qwen-LiveTranslate モデルの概要 -- サポートされている言語、音声、機能
- サーバー側イベントリファレンス -- イベントタイプ、JSON スキーマ、エラーコード
- DashScope SDK のインストール -- インストールと依存関係の設定
- API キーの取得 -- 作成と管理