跳转到主要内容
Qwen-ASR-Realtime

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

本文档介绍如何使用 DashScope Java SDK 调用实时语音识别(Qwen-ASR-Realtime)模型。

前提条件

  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")
                .url("wss://maas.qianwenaiapi.com/api-ws/v1/realtime")
                // 若没有配置环境变量,请用千问AI平台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")
                .url("wss://maas.qianwenaiapi.com/api-ws/v1/realtime")
                // 若没有配置环境变量,请用千问AI平台API Key将下行替换为:.apikey("sk-xxx")
                .apikey(System.getenv("DASHSCOPE_API_KEY"))
                .build();
参数类型是否必须说明
modelString是指定要使用的模型名称。
urlString是语音识别服务地址,固定为 wss://maas.qianwenaiapi.com/api-ws/v1/realtime。
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&lt;OmniRealtimeModality&gt;是模型输出模态,固定为[OmniRealtimeModality.TEXT]。
enableTurnDetectionboolean否是否开启服务端语音活动检测(VAD)。关闭后,需手动调用commit()方法触发识别。
默认值:true。
取值范围:
  • true:开启
  • false:关闭
turnDetectionTypeString否服务端VAD类型,固定为 server_vad。
turnDetectionThresholdfloat否VAD检测阈值。推荐将该值设为0.0。
默认值:0.5。
取值范围:[-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;方法引入。
方法签名服务端响应事件(通过回调下发)说明
示例 1 请参见表格下方无构造方法。
示例 2 请参见表格下方session.created > 会话已创建 session.updated > 会话配置已更新和服务端创建连接。
示例 3 请参见表格下方session.updated > 会话配置已更新用于更新会话配置,建议在连接建立后首先调用该方法进行设置。若未调用该方法,系统将使用默认配置。只需关注请求参数中的涉及到的参数。
示例 4 请参见表格下方无将Base64编码后的音频数据片段追加到云端输入音频缓冲区。
  • 请求参数enableTurnDetection设为true,音频缓冲区用于检测语音,服务端决定何时提交。
  • 请求参数enableTurnDetection设为false,客户端可以选择每个事件中放置多少音频量,最多放置 15 MiB。 例如,从客户端流式处理较小的数据块可以让 VAD 响应更迅速。
示例 5 请参见表格下方input_audio_buffer.committed > 服务端收到提交的音频提交之前通过append添加到云端缓冲区的音视频,如果输入的音频缓冲区为空将产生错误。 禁用场景:请求参数enableTurnDetection设为true时。
示例 6 请参见表格下方session.finished > 服务端完成语音识别,结束会话通知服务端结束会话,服务端收到会话结束通知后将完成最后的语音识别。 调用时机: endSessionAsync 是 endSession 的异步版本,两者功能完全相同。
示例 7 请参见表格下方无终止任务,并关闭连接。
示例 8 请参见表格下方无获取当前任务的session_id。
示例 9 请参见表格下方无获取最近一次response的response_id。
示例 1(方法签名):
public OmniRealtimeConversation(OmniRealtimeParam param, OmniRealtimeCallback callback)
示例 2(方法签名):
public void connect() throws NoApiKeyException, InterruptedException
示例 3(方法签名):
public void updateSession(OmniRealtimeConfig config)
示例 4(方法签名):
public void appendAudio(String audioBase64)
示例 5(方法签名):
public void commit()
示例 6(方法签名):
public void endSession() throws InterruptedException
示例 7(方法签名):
public void close()
示例 8(方法签名):
public String getSessionId()
示例 9(方法签名):
public String getResponseId()

回调接口(OmniRealtimeCallback)

服务端会通过回调的方式,将服务端响应事件和数据返回给客户端。 继承此类并实现相应方法以处理服务端事件。 通过import com.alibaba.dashscope.audio.omni.OmniRealtimeCallback;引入。
方法签名参数说明
示例 1 请参见表格下方无WebSocket连接成功建立时触发。
示例 2 请参见表格下方message:服务端事件收到服务端事件时触发。
示例 3 请参见表格下方code:状态码 reason:WebSocket连接关闭时的日志信息WebSocket连接关闭时触发。
示例 1(方法签名):
public void onOpen()
示例 2(方法签名):
public abstract void onEvent(JsonObject message)
示例 3(方法签名):
public abstract void onClose(int code, String reason)