Skip to main content

实时语音识别(Qwen-ASR-Realtime)Java SDK-API参考

本文档介绍如何使用 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。现有域名仍可正常使用。

前提条件

  1. 安装SDK,确保DashScope SDK版本不低于2.22.5。
  2. 获取与配置 API Key。
  3. 了解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
Java
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")
                // 以下为华北2(北京)地域的配置,调用时请将"{WorkspaceId}"替换为真实的业务空间ID,各地域的配置不同。
                .url("wss://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api-ws/v1/realtime")
                // 新加坡和北京地域的API Key不同。获取API Key:https://help.aliyun.com/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);
    }
}

请求参数

  • 以下参数通过OmniRealtimeParam的链式方法设置。
    OmniRealtimeParam param = OmniRealtimeParam.builder()
                    .model("qwen3-asr-flash-realtime")
                    // 以下为华北2(北京)地域的配置,调用时请将"{WorkspaceId}"替换为真实的业务空间ID,各地域的配置不同。
                    .url("wss://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api-ws/v1/realtime")
                    // 新加坡和北京地域的API Key不同。获取API Key:https://help.aliyun.com/zh/model-studio/get-api-key
                    // 若没有配置环境变量,请用百炼API Key将下行替换为:.apikey("sk-xxx")
                    .apikey(System.getenv("DASHSCOPE_API_KEY"))
                    .build();
    

    参数

    类型

    是否必须

    说明

    model

    String

    是

    指定要使用的模型名称。

    url

    String

    是

    语音识别服务地址:

    • 华北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。

    apikey

    String

    否

    设置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();
    

    参数

    类型

    是否必须

    说明

    modalities

    List<OmniRealtimeModality>

    是

    模型输出模态,固定为[OmniRealtimeModality.TEXT]。

    enableTurnDetection

    boolean

    否

    是否开启服务端语音活动检测(VAD)。关闭后,需手动调用commit()方法触发识别。

    默认值:true。

    取值范围:

    • true:开启

    • false:关闭

    turnDetectionType

    String

    否

    服务端VAD类型,固定为 server_vad。

    turnDetectionThreshold

    float

    否

    VAD检测阈值。推荐将该值设为0.0。

    默认值:0.5。

    取值范围:[-1, 1]。

    较低的阈值会提高 VAD 的灵敏度,可能将背景噪音误判为语音。较高的阈值则降低灵敏度,有助于在嘈杂环境中减少误触发。

    turnDetectionSilenceDurationMs

    int

    否

    VAD断句检测阈值(ms)。静音持续时长超过该阈值将被认为是语句结束。推荐将该值设为400。

    默认值:800。

    取值范围:[200, 6000]。

    较低的值(如 300ms)可使模型更快响应,但可能导致在自然停顿处发生不合理的断句。较高的值(如 1200ms)可更好地处理长句内的停顿,但会增加整体响应延迟。

    transcriptionConfig

    OmniRealtimeTranscriptionParam

    否

    语音识别相关配置。

  • 以下参数通过OmniRealtimeTranscriptionParam的setter方法设置。
    OmniRealtimeTranscriptionParam transcriptionParam = new OmniRealtimeTranscriptionParam();
            transcriptionParam.setLanguage("zh");
            transcriptionParam.setInputSampleRate(16000);
            transcriptionParam.setInputAudioFormat("pcm");
    

    参数

    类型

    是否必须

    说明

    language

    String

    否

    音频源语言。

    • 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:瑞典语

    inputSampleRate

    int

    否

    音频采样率(Hz)。支持16000和8000。

    默认值:16000。

    设置为 8000 时,服务端会先升采样到16000Hz再进行识别,可能引入微小延迟。建议仅在源音频为8000Hz(如电话线路)时使用。

    inputAudioFormat

    String

    否

    音频格式。支持pcm和opus。

    默认值:pcm。

关键接口

OmniRealtimeConversation类

OmniRealtimeConversation通过import com.alibaba.dashscope.audio.omni.OmniRealtimeConversation;方法引入。
方法签名服务端响应事件(通过回调下发)说明
public OmniRealtimeConversation(OmniRealtimeParam param, OmniRealtimeCallback callback)
无构造方法。
public void connect() throws NoApiKeyException, InterruptedException
session.created
会话已创建
session.updated
会话配置已更新
和服务端创建连接。
public void updateSession(OmniRealtimeConfig config)
session.updated
会话配置已更新
用于更新会话配置,建议在连接建立后首先调用该方法进行设置。若未调用该方法,系统将使用默认配置。只需关注请求参数中的涉及到的参数。
public void appendAudio(String audioBase64)
无将Base64编码后的音频数据片段追加到云端输入音频缓冲区。
  • 请求参数enableTurnDetection设为true,音频缓冲区用于检测语音,服务端决定何时提交。
  • 请求参数enableTurnDetection设为false,客户端可以选择每个事件中放置多少音频量,最多放置 15 MiB。 例如,从客户端流式处理较小的数据块可以让 VAD 响应更迅速。
public void commit()
input_audio_buffer.committed
服务端收到提交的音频
提交之前通过append添加到云端缓冲区的音视频,如果输入的音频缓冲区为空将产生错误。禁用场景:请求参数enableTurnDetection设为true时。
public void endSession() throws InterruptedException
session.finished
服务端完成语音识别,结束会话
通知服务端结束会话,服务端收到会话结束通知后将完成最后的语音识别。调用时机:endSessionAsync 是 endSession 的异步版本,两者功能完全相同。
public void close()
无终止任务,并关闭连接。
public String getSessionId()
无获取当前任务的session_id。
public String getResponseId()
无获取最近一次response的response_id。

回调接口(OmniRealtimeCallback)

服务端会通过回调的方式,将服务端响应事件和数据返回给客户端。 继承此类并实现相应方法以处理服务端事件。 通过import com.alibaba.dashscope.audio.omni.OmniRealtimeCallback;引入。
方法签名参数说明
public void onOpen()
无WebSocket连接成功建立时触发。
public abstract void onEvent(JsonObject message)
message:服务端事件收到服务端事件时触发。
public abstract void onClose(int code, String reason)
code:状态码reason:WebSocket连接关闭时的日志信息WebSocket连接关闭时触发。
文本生成
图像生成
视频生成
世界模型
3D模型生成
音频
  • 音频生成
Realtime API
向量与排序
决策模型
TokenPlan
模型生产