Use o DashScope Java SDK para chamar o Qwen-ASR-Realtime.
Pré-requisitos
- DashScope SDK 2.22.5 ou posterior (Instalar o SDK)
- Obter uma chave de API
- Compreender o fluxo de interação entre cliente e servidor
ImportanteO Alibaba Cloud Model Studio lançou domínios específicos por workspace para as regiões China (Pequim) e Singapura. Os novos domínios dedicados oferecem desempenho superior e maior estabilidade para solicitações de inferência. Recomendamos migrar para os novos domínios:
- China (Pequim): de
dashscope.aliyuncs.compara{WorkspaceId}.cn-beijing.maas.aliyuncs.com - Singapura: de
dashscope-intl.aliyuncs.compara{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com
Substitua {WorkspaceId} pelo seu ID do Workspace real. Os domínios existentes permanecem totalmente funcionais.
Modos de interação
O Qwen-ASR-Realtime oferece dois modos para determinar quando processar o áudio:
Modo | enableTurnDetection | Funcionamento |
|---|---|---|
Modo VAD (padrão) |
| O servidor detecta os limites da fala usando detecção de atividade de voz (VAD) e decide quando enviar o buffer de áudio para reconhecimento. |
Modo manual |
| O cliente controla o envio do áudio chamando |
Para obter detalhes sobre cada modo, consulte Modo VAD e Modo manual.
Exemplo completo
ObservaçãoO código de exemplo lê o arquivo your_audio_file.pcm (PCM16, 16 kHz, mono). Caso você possua apenas arquivos em MP3, WAV ou formatos similares, converta-os usando o 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")
// The following is the configuration for the Singapore region. When calling, replace "{WorkspaceId}" with your actual workspace ID. Configurations differ by region.
.url("wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/realtime")
// The API Key differs between the Singapore and Beijing regions. Get your API Key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
// If you have not configured the environment variable, replace the following line with your Alibaba Cloud Model Studio 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";
Parâmetros da solicitação
Parâmetros de conexão (OmniRealtimeParam)
Defina esses parâmetros com os métodos encadeados da classe OmniRealtimeParam.
Clique em para visualizar o código de exemplo
OmniRealtimeParam param = OmniRealtimeParam.builder()
.model("qwen3-asr-flash-realtime")
// Endpoint for the Singapore region.
// The following configuration is for the Singapore region. Replace "{WorkspaceId}" with your actual workspace ID. The configuration varies by region.
.url("wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/realtime")
// The API keys for the Singapore and Beijing regions are different.
// To obtain an API key, see https://www.alibabacloud.com/help/en/model-studio/get-api-key
// If you have not configured an environment variable, replace the following line with .apikey("sk-xxx").
.apikey(System.getenv("DASHSCOPE_API_KEY"))
.build();
Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
|
| Sim | Modelo a ser usado. Exemplo: |
|
| Sim | Endpoint do serviço. China (Pequim): |
|
| Não | Chave de API. |
Configuração da sessão (OmniRealtimeConfig)
Defina esses parâmetros com os métodos encadeados da classe OmniRealtimeConfig.
Clique em para visualizar o código de exemplo
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();
Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
|
| Sim | Modalidade de saída. Valor fixo: |
|
| Não | Ativa o VAD no lado do servidor. Quando desativado, chame |
|
| Não | Tipo de VAD. Valor fixo: |
|
| Não | Limiar de sensibilidade do VAD. Valor recomendado: Padrão: Valores menores aumentam a sensibilidade (podem gerar acionamentos por ruído de fundo). Valores maiores reduzem a sensibilidade e ajudam a evitar acionamentos falsos em ambientes ruidosos. |
|
| Não | Duração do silêncio em milissegundos que marca o fim de uma expressão. Valor recomendado: Padrão: Durações mais curtas (por exemplo, 300 ms) aceleram as respostas, mas podem dividir pausas naturais. Durações mais longas (por exemplo, 1200 ms) lidam melhor com pausas, mas aumentam a latência. |
|
| Não | Configurações de reconhecimento de fala. Consulte Parâmetros de transcrição. |
Parâmetros de transcrição (OmniRealtimeTranscriptionParam)
Defina esses parâmetros com os métodos setter da classe OmniRealtimeTranscriptionParam.
Clique em para visualizar o código de exemplo
OmniRealtimeTranscriptionParam transcriptionParam = new OmniRealtimeTranscriptionParam();
transcriptionParam.setLanguage("zh");
transcriptionParam.setInputSampleRate(16000);
transcriptionParam.setInputAudioFormat("pcm");
Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
|
| Não | Idioma da source de áudio. Para idiomas compatíveis, consulte Idiomas suportados. |
|
| Não | Taxa de amostragem de áudio em Hz. Valores válidos: Padrão: Definir como |
|
| Não | Formato de codificação de áudio. Valores válidos: |
|
| Não | Texto de contexto para viés contextual. Forneça texto de base, vocabulários de entidades ou material de referência para melhorar a precisão do reconhecimento. Máximo: 10.000 tokens. |
Interfaces principais
OmniRealtimeConversation
Importação: com.alibaba.dashscope.audio.omni.OmniRealtimeConversation
Esta classe gerencia o ciclo de vida do WebSocket: conexão ao servidor, envio de áudio e encerramento da sessão.
Crie uma conversa
OmniRealtimeConversation conversation =
new OmniRealtimeConversation(param, callback);
Cria uma nova instância de conversa com os parâmetros de conexão e o manipulador de callback especificados.
Conectar-se ao servidor
conversation.connect();
Abre uma conexão WebSocket. O servidor responde com os eventos session.created e session.updated.
Gera exceção: NoApiKeyException, InterruptedException.
Configure a sessão
conversation.updateSession(config);
Atualiza a configuração da sessão após estabelecer a conexão. O servidor responde com um evento session.updated. Se não for chamado, o servidor usa as configurações padrão.
Enviar dados de áudio
conversation.appendAudio(audioBase64);
Adiciona um segmento de áudio codificado em Base64 ao buffer de áudio no lado do servidor.
- Modo VAD (
enableTurnDetection=true): O servidor detecta os limites da fala e decide quando processar o buffer. - Modo manual (
enableTurnDetection=false): O áudio se acumula no buffer até você chamarcommit()para acionar o reconhecimento. Cada evento pode conter até 15 MiB de dados de áudio.
Confirmar o buffer de áudio
conversation.commit();
Envia o áudio armazenado em buffer para reconhecimento. O servidor responde com um evento input_audio_buffer.committed.
Este método está disponível apenas no modo manual (
enableTurnDetection=false). Ocorre um erro se o buffer de áudio estiver vazio.
Encerrar a sessão
conversation.endSession(); // synchronous
// or
conversation.endSessionAsync(); // asynchronous
Notifica o servidor para concluir o processamento de qualquer áudio restante e encerrar a sessão. O servidor responde com um evento session.finished.
Quando chamar:
- Modo VAD: Após terminar de enviar áudio.
- Modo manual: Após chamar
commit().
Cancele uma resposta
conversation.cancelResponse();
Cancela a resposta em andamento. Se não houver resposta para cancelar, o servidor retornará um erro.
Fechar a conexão
conversation.close();
Interrompe a tarefa e fecha a conexão WebSocket imediatamente.
Obter IDs de sessão e resposta
String sessionId = conversation.getSessionId();
String responseId = conversation.getResponseId();
getSessionId()retorna o ID da sessão da tarefa atual.getResponseId()retorna o ID da resposta mais recente do servidor.
OmniRealtimeCallback
Importação: com.alibaba.dashscope.audio.omni.OmniRealtimeCallback
Herde esta classe e implemente os métodos de callback para lidar com eventos do servidor.
Método | Parâmetros | Acionado quando |
|---|---|---|
| Nenhum | A conexão WebSocket é estabelecida. |
|
| Um evento do servidor é recebido. Analise o campo |
|
| A conexão WebSocket é fechada. |