即時音視頻翻譯(Qwen-Livetranslate-Realtime)
即時音視頻翻譯(Qwen-LiveTranslate)Java SDK-API參考
本文檔介紹如何使用 DashScope Java SDK 調用即時音視頻翻譯(Qwen-LiveTranslate)模型。
前提條件
- 安裝SDK,確保DashScope SDK版本不低於2.22.5。
- 擷取API Key。
- 瞭解即時語音/音視頻翻譯-千問。
阿里雲百鍊為華北2(北京)、新加坡地區推出了業務空間專屬網域名稱,能夠為推理請求提供卓越的效能和更高的穩定性,建議遷移至新網域名稱:
- 華北2(北京)地區:從
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} 為您的業務空間 ID,可在阿里雲百鍊控制台的業務空間詳情頁面查看。現有網域名稱仍可正常使用。
請求參數
-
以下參數通過
OmniRealtimeParam的鏈式方法設定。
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 Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
// 若沒有配置環境變數,請用百鍊API Key將下行替換為:.apikey("sk-xxx")
.apikey(System.getenv("DASHSCOPE_API_KEY"))
.build();
| 參數 | 類型 | 是否必須 | 說明 |
|---|
model | String | 是 | 指定要使用的模型名稱,推薦使用qwen3.5-livetranslate-flash-realtime。
qwen3-livetranslate-flash-realtime為舊版模型。
|
url | String | 是 | 即時翻譯服務地址:
- 華北2(北京):
wss://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api-ws/v1/realtime
- 新加坡:
wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/realtime
調用時請將{WorkspaceId}替換為真實的業務空間ID。 |
apikey | String | 否 | 設定API Key。 |
-
以下參數通過
OmniRealtimeConfig的鏈式方法設定。
// 設定翻譯熱詞
Map<String, Object> phrases = new HashMap<>();
phrases.put("人工智慧", "Artificial Intelligence");
phrases.put("機器學習", "Machine Learning");
OmniRealtimeConfig config = OmniRealtimeConfig.builder()
.modalities(Arrays.asList(OmniRealtimeModality.AUDIO, OmniRealtimeModality.TEXT))
.voice("Tina")
.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);
-
以下參數通過OmniRealtimeTranslationParam的鏈式方法設定。
// 設定翻譯熱詞
Map<String, Object> phrases = new HashMap<>();
phrases.put("人工智慧", "Artificial Intelligence"); // 源語言詞: 目標語言翻譯
phrases.put("機器學習", "Machine Learning");
OmniRealtimeTranslationParam translationParam = OmniRealtimeTranslationParam.builder()
.language("en") // 翻譯目標語言代碼
.corpus(OmniRealtimeTranslationParam.Corpus.builder()
.phrases(phrases)
.build())
.build();
參數 | 類型 | 是否必須 | 說明 |
|---|
language
| String
| 否 | 翻譯目標語言代碼。 預設值:en。 可選值:參見支援的語種。 |
corpus
| OmniRealtimeTranslationParam.Corpus
| 否 | 熱詞配置,用於提升特定詞彙的翻譯準確性。 |
corpus.phrases
| Map<String, Object>
| 否 | 熱詞映射表。key 為源語言詞彙,value 為目標語言對應翻譯。 樣本:{"人工智慧": "Artificial Intelligence"} |
關鍵介面
OmniRealtimeConversation類
OmniRealtimeConversation通過import com.alibaba.dashscope.audio.omni.OmniRealtimeConversation;方法引入。
| 方法簽名 | 服務端響應事件(通過回調下發) | 說明 |
|---|
public OmniRealtimeConversation(OmniRealtimeParam param, OmniRealtimeCallback callback)
| 無 | 構造方法。 |
public void connect() throws NoApiKeyException, InterruptedException
| 服務端事件
會話已建立
服務端事件
會話配置已更新
| 和服務端建立串連。 |
public void updateSession(OmniRealtimeConfig config)
| 服務端事件
會話配置已更新
| 用於更新會話配置,建議在串連建立後首先調用該方法進行設定。若未調用該方法,系統將使用預設配置。只需關注OmniRealtimeConfig中涉及的參數。 |
public void appendAudio(String audioBase64)
| 無 | 將Base64編碼後的音頻資料片段追加到雲端輸入音頻緩衝區。服務端會自動檢測語音起止並觸發翻譯。 |
| input_audio_buffer.committed
輸入音頻緩衝區已提交
| Manual 模式下,提交之前通過appendAudio方法追加到雲端緩衝區的音頻,服務端收到後自動開始產生翻譯響應。VAD 模式下無需調用此方法,服務端會自動認可。 |
public void clearAppendedAudio()
| input_audio_buffer.cleared
輸入音頻緩衝區已清空
| 清空當前雲端緩衝區中尚未提交的音頻資料。 |
public void endSession() throws InterruptedException
| session.finished
服務端完成語音翻譯,結束會話
| 通知服務端結束會話,服務端收到會話結束通知後將完成最後的語音翻譯。 |
public void close(int code, String reason)
| 無 | 終止任務,並關閉串連。 |
public String getSessionId()
| 無 | 擷取當前任務的session_id。 |
public String getResponseId()
| 無 | 擷取最近一次response的response_id。 |
public long getFirstTextDelay()
| 無 | 擷取最近一次響應的首個文本延遲(毫秒)。 |
public long getFirstAudioDelay()
| 無 | 擷取最近一次響應的首個音頻延遲(毫秒)。 |
回調介面(OmniRealtimeCallback)
服務端會通過回調的方式,將服務端響應事件和資料返回給用戶端。
繼承此類並實現相應方法以處理服務端事件。
通過import com.alibaba.dashscope.audio.omni.OmniRealtimeCallback;引入。
| 方法簽名 | 參數 | 說明 |
|---|
| 無 | WebSocket串連成功建立時觸發。 |
public abstract void onEvent(JsonObject message)
| message:服務端事件 | 收到服務端事件時觸發。 |
public abstract void onClose(int code, String reason)
| code:狀態代碼reason:WebSocket串連關閉時的日誌資訊 | WebSocket串連關閉時觸發。 |
完整樣本
以下樣本展示如何從麥克風即時錄音並進行翻譯。
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; // 100ms 的 16kHz 16bit 單聲道音頻
private static final int OUTPUT_CHUNK_SIZE = 4800; // 100ms 的 24kHz 16bit 單聲道音頻
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("人工智慧", "Artificial Intelligence");
phrases.put("機器學習", "Machine Learning");
OmniRealtimeConfig config = OmniRealtimeConfig.builder()
.modalities(Arrays.asList(OmniRealtimeModality.AUDIO, OmniRealtimeModality.TEXT))
.voice("Tina")
.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, "使用者停止");
}));
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 Key 錯誤: " + e.getMessage());
} catch (Exception e) {
System.err.println("發生異常: " + e.getMessage());
e.printStackTrace();
}
}
}