本文檔介紹如何使用 DashScope Java SDK 調用即時語音辨識(Qwen-ASR-Realtime)模型。
重要阿里雲百鍊為華北2(北京)、新加坡地區推出了業務空間專屬網域名稱,能夠為推理請求提供卓越的效能和更高的穩定性,建議遷移至新網域名稱:
- 華北2(北京)地區:從
dashscope.aliyuncs.com遷移至{WorkspaceId}.cn-beijing.maas.aliyuncs.com - 新加坡地區:從
dashscope-intl.aliyuncs.com遷移至{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com
{WorkspaceId}需要替換為真實的Workspace ID。現有網域名稱仍可正常使用。
前提條件
- 安裝SDK,確保DashScope SDK版本不低於2.22.5。
- 擷取API Key。
- 瞭解WebSocket API。
完整範例
說明範例程式碼讀取 your_audio_file.pcm(PCM16、16 kHz、單聲道)。如僅有 MP3/WAV 等格式,可使用 ffmpeg 轉換:
ffmpeg -i your_audio.mp3 -ar 16000 -ac 1 -f s16le your_audio_file.pcm
import com.alibaba.dashscope.audio.omni.*;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.google.gson.JsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.sound.sampled.LineUnavailableException;
import java.io.File;
import java.io.FileInputStream;
import java.util.Base64;
import java.util.Collections;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
public class Qwen3AsrRealtimeUsage {
private static final Logger log = LoggerFactory.getLogger(Qwen3AsrRealtimeUsage.class);
private static final int AUDIO_CHUNK_SIZE = 1024; // Audio chunk size in bytes
private static final int SLEEP_INTERVAL_MS = 30; // Sleep interval in milliseconds
public static void main(String[] args) throws InterruptedException, LineUnavailableException {
CountDownLatch finishLatch = new CountDownLatch(1);
OmniRealtimeParam param = OmniRealtimeParam.builder()
.model("qwen3-asr-flash-realtime")
// 以下為新加坡地區的配置,調用時請將"{WorkspaceId}"替換為真實的業務空間ID,各地區的配置不同。
.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();
OmniRealtimeConversation conversation = null;
final AtomicReference<OmniRealtimeConversation> conversationRef = new AtomicReference<>(null);
conversation = new OmniRealtimeConversation(param, new OmniRealtimeCallback() {
@Override
public void onOpen() {
System.out.println("connection opened");
}
@Override
public void onEvent(JsonObject message) {
String type = message.get("type").getAsString();
switch(type) {
case "session.created":
System.out.println("start session: " + message.get("session").getAsJsonObject().get("id").getAsString());
break;
case "conversation.item.input_audio_transcription.completed":
System.out.println("transcription: " + message.get("transcript").getAsString());
finishLatch.countDown();
break;
case "input_audio_buffer.speech_started":
System.out.println("======VAD Speech Start======");
break;
case "input_audio_buffer.speech_stopped":
System.out.println("======VAD Speech Stop======");
break;
case "conversation.item.input_audio_transcription.text":
System.out.println("transcription: " + message.get("text").getAsString() + message.get("stash").getAsString());
break;
default:
break;
}
}
@Override
public void onClose(int code, String reason) {
System.out.println("connection closed code: " + code + ", reason: " + reason);
}
});
conversationRef.set(conversation);
try {
conversation.connect();
} catch (NoApiKeyException e) {
throw new RuntimeException(e);
}
OmniRealtimeTranscriptionParam transcriptionParam = new OmniRealtimeTranscriptionParam();
transcriptionParam.setLanguage("zh");
transcriptionParam.setInputAudioFormat("pcm");
transcriptionParam.setInputSampleRate(16000);
OmniRealtimeConfig config = OmniRealtimeConfig.builder()
.modalities(Collections.singletonList(OmniRealtimeModality.TEXT))
.transcriptionConfig(transcriptionParam)
.build();
conversation.updateSession(config);
String filePath = "your_audio_file.pcm";
File audioFile = new File(filePath);
if (!audioFile.exists()) {
log.error("Audio file not found: {}", filePath);
return;
}
try (FileInputStream audioInputStream = new FileInputStream(audioFile)) {
byte[] audioBuffer = new byte[AUDIO_CHUNK_SIZE];
int bytesRead;
int totalBytesRead = 0;
log.info("Starting to send audio data from: {}", filePath);
// Read and send audio data in chunks
while ((bytesRead = audioInputStream.read(audioBuffer)) != -1) {
totalBytesRead += bytesRead;
byte[] chunk = new byte[bytesRead];
System.arraycopy(audioBuffer, 0, chunk, 0, bytesRead);
String audioB64 = Base64.getEncoder().encodeToString(chunk);
// Send audio chunk to conversation
conversation.appendAudio(audioB64);
// Add small delay to simulate real-time audio streaming
Thread.sleep(SLEEP_INTERVAL_MS);
}
log.info("Finished sending audio data. Total bytes sent: {}", totalBytesRead);
} catch (Exception e) {
log.error("Error sending audio from file: {}", filePath, e);
}
//send session.finish and wait for finish and close
conversation.endSession();
log.info("task finished");
System.exit(0);
}
}
Constants.baseHttpApiUrl = "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1";
請求參數
-
以下參數通過
OmniRealtimeParam的鏈式方法設定。點擊查看範例程式碼
OmniRealtimeParam param = OmniRealtimeParam.builder() .model("qwen3-asr-flash-realtime") // 以下為新加坡地區的配置,調用時請將"{WorkspaceId}"替換為真實的業務空間ID,各地區的配置不同。 .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();參數
類型
是否必須
說明
modelString是
指定要使用的模型名稱。
urlString是
語音辨識服務地址:
華北2(北京)地區:
wss://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api-ws/v1/realtime。調用時請將{WorkspaceId}替換為真實的Workspace ID。新加坡地區:
wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/realtime。調用時請將{WorkspaceId}替換為真實的業務空間ID。
apikeyString否
設定API Key。
-
以下參數通過
OmniRealtimeConfig的鏈式方法設定。點擊查看範例程式碼
OmniRealtimeTranscriptionParam transcriptionParam = new OmniRealtimeTranscriptionParam(); transcriptionParam.setLanguage("zh"); transcriptionParam.setInputSampleRate(16000); transcriptionParam.setInputAudioFormat("pcm"); OmniRealtimeConfig config = OmniRealtimeConfig.builder() .modalities(Collections.singletonList(OmniRealtimeModality.TEXT)) .enableTurnDetection( true) .turnDetectionType("server_vad") .turnDetectionThreshold(0.0f) .turnDetectionSilenceDurationMs(400) .transcriptionConfig(transcriptionParam) .build();參數
類型
是否必須
說明
modalitiesList<OmniRealtimeModality>是
模型輸出模態,固定為
[OmniRealtimeModality.TEXT]。enableTurnDetectionboolean否
是否開啟服務端語音活動檢測(VAD)。關閉後,需手動調用
commit()方法觸發識別。預設值:
true。取值範圍:
true:開啟false:關閉
turnDetectionTypeString否
服務端VAD類型,固定為
server_vad。turnDetectionThresholdfloat否
VAD檢測閾值。推薦將該值設為
0.0。預設值:
0.2。取值範圍:
[-1, 1]。較低的閾值會提高 VAD 的靈敏度,可能將背景雜音誤判為語音。較高的閾值則降低靈敏度,有助於在嘈雜環境中減少誤觸發。
turnDetectionSilenceDurationMsint否
VAD斷句檢測閾值(ms)。靜音持續時間長度超過該閾值將被認為是語句結束。推薦將該值設為
400。預設值:
800。取值範圍:
[200, 6000]。較低的值(如 300ms)可使模型更快響應,但可能導致在自然停頓處發生不合理的斷句。較高的值(如 1200ms)可更好地處理長句內的停頓,但會增加整體響應延遲。
transcriptionConfigOmniRealtimeTranscriptionParam否
語音辨識相關配置。
-
以下參數通過
OmniRealtimeTranscriptionParam的setter方法設定。點擊查看範例程式碼
OmniRealtimeTranscriptionParam transcriptionParam = new OmniRealtimeTranscriptionParam(); transcriptionParam.setLanguage("zh"); transcriptionParam.setInputSampleRate(16000); transcriptionParam.setInputAudioFormat("pcm");參數
類型
是否必須
說明
languageString否
音頻源語言。
zh:中文(普通話、四川話、閩南語、吳語)
yue:粵語
en:英文
ja:日語
de:德語
ko:韓語
ru:俄語
fr:法語
pt:葡萄牙語
ar:阿拉伯語
it:意大利語
es:西班牙語
hi:印地語
id:印尼語
th:泰語
tr:土耳其語
uk:烏克蘭語
vi:越南語
cs:捷克語
da:丹麥語
fil:菲律賓語
fi:芬蘭語
is:冰島語
ms:馬來語
no:挪威語
pl:波蘭語
sv:瑞典語
inputSampleRateint否
音頻採樣率(Hz)。支援
16000和8000。預設值:
16000。設定為
8000時,服務端會先升採樣到16000Hz再進行識別,可能引入微小延遲。建議僅在源音頻為8000Hz(如電話線路)時使用。inputAudioFormatString否
音頻格式。支援
pcm和opus。預設值:
pcm。
關鍵介面
OmniRealtimeConversation類
OmniRealtimeConversation通過import com.alibaba.dashscope.audio.omni.OmniRealtimeConversation;方法引入。
| 方法簽名 | 服務端響應事件(通過回調下發) | 說明 |
|---|---|---|
| 無 | 構造方法。 |
|
| 和服務端建立串連。 |
|
| 用於更新會話配置,建議在串連建立後首先調用該方法進行設定。若未調用該方法,系統將使用預設配置。只需關注請求參數中的涉及到的參數。 |
| 無 | 將Base64編碼後的音頻資料片段追加到雲端輸入音頻緩衝區。 |
|
| 提交之前通過append添加到雲端緩衝區的音視頻,如果輸入的音頻緩衝區為空白將產生錯誤。 禁用情境:請求參數 |
|
| 通知服務端結束會話,服務端收到會話結束通知後將完成最後的語音辨識。 調用時機:
|
| 無 | 終止任務,並關閉串連。 |
| 無 | 擷取當前任務的session_id。 |
| 無 | 擷取最近一次response的response_id。 |
回調介面(OmniRealtimeCallback)
服務端會通過回調的方式,將服務端響應事件和資料返回給用戶端。
繼承此類並實現相應方法以處理服務端事件。
通過import com.alibaba.dashscope.audio.omni.OmniRealtimeCallback;引入。
| 方法簽名 | 參數 | 說明 |
|---|---|---|
| 無 | WebSocket串連成功建立時觸發。 |
| message:服務端事件 | 收到服務端事件時觸發。 |
| code:狀態代碼 reason:WebSocket串連關閉時的日誌資訊 | WebSocket串連關閉時觸發。 |