Todos os produtos
Search
Central de documentação

Alibaba Cloud Model Studio:Qwen-Audio-3.0-ASR-Flash-Streaming/Fun-ASR-Realtime Java SDK provides interfaces for synchronous and streaming speech recognition

Última atualização: Sep 02, 2026

Este tópico descreve os parâmetros e as interfaces do Java SDK para reconhecimento de fala em tempo real com Qwen-Audio-3.0-ASR-Flash-Streaming/Fun-ASR-Realtime.

ImportanteO Alibaba Cloud Model Studio lançou domínios específicos por workspace para as regiões China (Beijing) e Singapore. Os novos domínios dedicados oferecem desempenho superior e maior estabilidade para solicitações de inferência. Recomendamos a migração para os novos domínios:

  • China (Beijing): de dashscope.aliyuncs.com para {WorkspaceId}.cn-beijing.maas.aliyuncs.com
  • Singapore: de dashscope-intl.aliyuncs.com para {WorkspaceId}.ap-southeast-1.maas.aliyuncs.com

Substitua {WorkspaceId} pelo seu Workspace ID real. Os domínios existentes permanecem totalmente funcionais.

Guia do usuário: Para uma introdução aos modelos e orientações sobre seleção, consulte Speech-to-text.

Pré-requisitos

O service está ativado e você Obtain an API key. Para evitar riscos de segurança causados por vazamento de código, Configure API key as an environment variable em vez de codificá-la diretamente no código-fonte.

Início rápido

A The Recognition class fornece interfaces para chamadas síncronas e de streaming bidirecional. Escolha a abordagem adequada às suas necessidades:

  • Chamada síncrona: reconhece um arquivo local e retorna o resultado completo de uma só vez. Ideal para processar áudio pré-gravado.
  • Chamada de streaming bidirecional: reconhece um fluxo de áudio diretamente e retorna resultados em tempo real. O fluxo pode vir de um dispositivo externo, como um microfone, ou ser lido de um arquivo local. Indicada para cenários que exigem feedback imediato.

Chamada síncrona

Envie uma única tarefa de reconhecimento de fala em tempo real e obtenha o resultado sincronamente passando um arquivo local. A chamada bloqueia a execução até o retorno do resultado.

Instancie The Recognition class e chame o método call para vincular os Request parameters e o arquivo a ser reconhecido. O método executa o reconhecimento e retorna o resultado final.

Clique para visualizar o exemplo completo

import com.alibaba.dashscope.audio.asr.recognition.Recognition;
import com.alibaba.dashscope.audio.asr.recognition.RecognitionParam;
import com.alibaba.dashscope.utils.Constants;

import java.io.File;

public class Main {
    public static void main(String[] args) {
        // The following is the configuration for the Singapore region. When calling, replace "{WorkspaceId}" with your real workspace ID. Configurations differ by region.
        Constants.baseWebsocketApiUrl = "wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference";
        // Create a Recognition instance
        Recognition recognizer = new Recognition();
        // Create RecognitionParam
        RecognitionParam param =
                RecognitionParam.builder()
                        .model("qwen-audio-3.0-asr-flash-streaming")
                        // The API Key differs between the Singapore and Beijing regions. Get an 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 Model Studio API Key: .apiKey("sk-xxx")
                        .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                        .format("wav")
                        .sampleRate(16000)
                        //.parameter("language_hints", new String[]{"zh"})
                        .build();

        try {
            System.out.println("Recognition result: " + recognizer.call(param, new File("{YOUR_AUDIO_FILE}")));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // Close the WebSocket connection after the task is complete
            recognizer.getDuplexApi().close(1000, "bye");
        }
        System.out.println(
                "[Metric] requestId: "
                        + recognizer.getLastRequestId()
                        + ", first package delay ms: "
                        + recognizer.getFirstPackageDelay()
                        + ", last package delay ms: "
                        + recognizer.getLastPackageDelay());
        System.exit(0);
    }
}

Chamada de streaming bidirecional: baseada em callback

Envie uma única tarefa de reconhecimento de fala em tempo real e transmita os resultados implementando uma interface de callback.

  1. Inicie o reconhecimento de fala em streaming

    Instancie The Recognition class e chame o método call para vincular os Request parameters e a The callback interface (ResultCallback) e iniciar o reconhecimento.

  2. Transmita o áudio

    Chame o método sendAudioFrame da The Recognition class em loop para enviar o fluxo de áudio binário ao servidor em segmentos. Leia o áudio de um arquivo local ou de um dispositivo, como um microfone.

    Enquanto os dados de áudio são enviados, o servidor retorna resultados de reconhecimento ao cliente em tempo real pelo método onEvent da The callback interface (ResultCallback).

    Envie cerca de 100 ms de áudio por quadro, mantendo cada payload entre 1 KB e 16 KB.

  3. Encerre o processo

    Chame o método stop da The Recognition class para encerrar o reconhecimento de fala.

    Esse método bloqueia a thread atual até que o callback onComplete ou onError da The callback interface (ResultCallback) seja acionado, liberando a thread.

Clique para visualizar o exemplo completo

import com.alibaba.dashscope.audio.asr.recognition.Recognition;
import com.alibaba.dashscope.audio.asr.recognition.RecognitionParam;
import com.alibaba.dashscope.audio.asr.recognition.RecognitionResult;
import com.alibaba.dashscope.common.ResultCallback;
import com.alibaba.dashscope.utils.Constants;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.TargetDataLine;

import java.nio.ByteBuffer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        // The following is the configuration for the Singapore region. When calling, replace "{WorkspaceId}" with your real workspace ID. Configurations differ by region.
        Constants.baseWebsocketApiUrl = "wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference";
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.submit(new RealtimeRecognitionTask());
        executorService.shutdown();
        executorService.awaitTermination(1, TimeUnit.MINUTES);
        System.exit(0);
    }
}

class RealtimeRecognitionTask implements Runnable {
    @Override
    public void run() {
        RecognitionParam param = RecognitionParam.builder()
                .model("qwen-audio-3.0-asr-flash-streaming")
                // The API Key differs between the Singapore and Beijing regions. Get an 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 Model Studio API Key: .apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .format("pcm")
                .sampleRate(16000)
                .build();
        Recognition recognizer = new Recognition();

        ResultCallback<RecognitionResult> callback = new ResultCallback<RecognitionResult>() {
            @Override
            public void onEvent(RecognitionResult result) {
                if (result.isSentenceEnd()) {
                    System.out.println("Final Result: " + result.getSentence().getText());
                } else {
                    System.out.println("Intermediate Result: " + result.getSentence().getText());
                }
            }

            @Override
            public void onComplete() {
                System.out.println("Recognition complete");
            }

            @Override
            public void onError(Exception e) {
                System.out.println("RecognitionCallback error: " + e.getMessage());
            }
        };
        try {
            recognizer.call(param, callback);
            // Create the audio format
            AudioFormat audioFormat = new AudioFormat(16000, 16, 1, true, false);
            // Match the default recording device based on the format
            TargetDataLine targetDataLine =
                    AudioSystem.getTargetDataLine(audioFormat);
            targetDataLine.open(audioFormat);
            // Start recording
            targetDataLine.start();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            long start = System.currentTimeMillis();
            // Record for 50s and perform real-time transcription
            while (System.currentTimeMillis() - start < 50000) {
                int read = targetDataLine.read(buffer.array(), 0, buffer.capacity());
                if (read > 0) {
                    buffer.limit(read);
                    // Send the recorded audio data to the streaming recognition service
                    recognizer.sendAudioFrame(buffer);
                    buffer = ByteBuffer.allocate(1024);
                    // The recording rate is limited; sleep for a short while to prevent excessive CPU usage
                    Thread.sleep(20);
                }
            }
            recognizer.stop();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // Close the WebSocket connection after the task is complete
            recognizer.getDuplexApi().close(1000, "bye");
        }

        System.out.println(
                "[Metric] requestId: "
                        + recognizer.getLastRequestId()
                        + ", first package delay ms: "
                        + recognizer.getFirstPackageDelay()
                        + ", last package delay ms: "
                        + recognizer.getLastPackageDelay());
    }
}
import com.alibaba.dashscope.api.GeneralApi;
import com.alibaba.dashscope.audio.asr.recognition.Recognition;
import com.alibaba.dashscope.audio.asr.recognition.RecognitionParam;
import com.alibaba.dashscope.audio.asr.recognition.RecognitionResult;
import com.alibaba.dashscope.base.HalfDuplexParamBase;
import com.alibaba.dashscope.common.GeneralListParam;
import com.alibaba.dashscope.common.ResultCallback;
import com.alibaba.dashscope.protocol.GeneralServiceOption;
import com.alibaba.dashscope.protocol.HttpMethod;
import com.alibaba.dashscope.protocol.Protocol;
import com.alibaba.dashscope.protocol.StreamingMode;
import com.alibaba.dashscope.utils.Constants;

import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

class TimeUtils {
    private static final DateTimeFormatter formatter =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");

    public static String getTimestamp() {
        return LocalDateTime.now().format(formatter);
    }
}

public class Main {
    public static void main(String[] args) throws InterruptedException {
        // The following is the configuration for the Singapore region. When calling, replace "{WorkspaceId}" with your real workspace ID. Configurations differ by region.
        Constants.baseWebsocketApiUrl = "wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference";
        // In real applications, this method only needs to be executed once at the very beginning of the program; there is no need to execute it multiple times.
        warmUp();

        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.submit(new RealtimeRecognitionTask(Paths.get(System.getProperty("user.dir"), "{YOUR_AUDIO_FILE}")));
        executorService.shutdown();

        // wait for all tasks to complete
        executorService.awaitTermination(1, TimeUnit.MINUTES);
        System.exit(0);
    }

    public static void warmUp() {
        try {
            // Lightweight GET request to establish connection
            GeneralServiceOption warmupOption = GeneralServiceOption.builder()
                    .protocol(Protocol.HTTP)
                    .httpMethod(HttpMethod.GET)
                    .streamingMode(StreamingMode.OUT)
                    .path("assistants")
                    .build();

            warmupOption.setBaseHttpUrl(Constants.baseHttpApiUrl);
            GeneralApi<HalfDuplexParamBase> api = new GeneralApi<>();
            api.get(GeneralListParam.builder().limit(1L).build(), warmupOption);
        } catch (Exception e) {
            // Reset flag to allow retry if pre-warming failed
        }
    }
}

class RealtimeRecognitionTask implements Runnable {
    private Path filepath;

    public RealtimeRecognitionTask(Path filepath) {
        this.filepath = filepath;
    }

    @Override
    public void run() {
        RecognitionParam param = RecognitionParam.builder()
                .model("qwen-audio-3.0-asr-flash-streaming")
                // The API Key differs between the Singapore and Beijing regions. Get an 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 Model Studio API Key: .apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .format("wav")
                .sampleRate(16000)
                .build();
        Recognition recognizer = new Recognition();

        String threadName = Thread.currentThread().getName();

        ResultCallback<RecognitionResult> callback = new ResultCallback<RecognitionResult>() {
            @Override
            public void onEvent(RecognitionResult message) {
                if (message.isSentenceEnd()) {

                    System.out.println(TimeUtils.getTimestamp()+" "+
                            "[process " + threadName + "] Final Result:" + message.getSentence().getText());
                } else {
                    System.out.println(TimeUtils.getTimestamp()+" "+
                            "[process " + threadName + "] Intermediate Result: " + message.getSentence().getText());
                }
            }

            @Override
            public void onComplete() {
                System.out.println(TimeUtils.getTimestamp()+" "+"[" + threadName + "] Recognition complete");
            }

            @Override
            public void onError(Exception e) {
                System.out.println(TimeUtils.getTimestamp()+" "+
                        "[" + threadName + "] RecognitionCallback error: " + e.getMessage());
            }
        };

        try {
            recognizer.call(param, callback);
            // Please replace the path with your audio file path
            System.out.println(TimeUtils.getTimestamp()+" "+"[" + threadName + "] Input file_path is: " + this.filepath);
            // Read file and send audio by chunks
            FileInputStream fis = new FileInputStream(this.filepath.toFile());
            byte[] allData = new byte[fis.available()];
            int ret = fis.read(allData);
            fis.close();

            int sendFrameLength = 3200;
            for (int i = 0; i * sendFrameLength < allData.length; i ++) {
                int start = i * sendFrameLength;
                int end = Math.min(start + sendFrameLength, allData.length);
                ByteBuffer byteBuffer = ByteBuffer.wrap(allData, start, end - start);
                recognizer.sendAudioFrame(byteBuffer);
                Thread.sleep(100);
            }

            System.out.println(TimeUtils.getTimestamp()+" "+LocalDateTime.now());
            recognizer.stop();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // Close the WebSocket connection after the task is complete
            recognizer.getDuplexApi().close(1000, "bye");
        }

        System.out.println(
                "["
                        + threadName
                        + "][Metric] requestId: "
                        + recognizer.getLastRequestId()
                        + ", first package delay ms: "
                        + recognizer.getFirstPackageDelay()
                        + ", last package delay ms: "
                        + recognizer.getLastPackageDelay());
    }
}

Chamada de streaming bidirecional: baseada em Flowable

Envie uma única tarefa de reconhecimento de fala em tempo real e transmita os resultados implementando um fluxo de trabalho (Flowable).

Flowable é um framework open-source para gerenciamento de fluxos de trabalho e processos de negócios, licenciado sob Apache 2.0. Para saber como usar o Flowable, consulte Detalhes da API Flowable.

Clique para visualizar o exemplo completo

Chame o método streamCall da The Recognition class diretamente para iniciar o reconhecimento.

O método streamCall retorna uma instância Flowable<RecognitionResult>. Use métodos da instância Flowable, como blockingForEach ou subscribe, para processar os resultados. Cada resultado vem encapsulado em um objeto RecognitionResult.

O método streamCall aceita dois parâmetros:

  • Instância RecognitionParam (Request parameters): use-a para definir modelo, taxa de amostragem, formato de áudio e outros parâmetros necessários ao reconhecimento.
  • Instância Flowable<ByteBuffer>: crie uma instância do tipo Flowable<ByteBuffer> e implemente nela a lógica de análise do fluxo de áudio.
import com.alibaba.dashscope.audio.asr.recognition.Recognition;
import com.alibaba.dashscope.audio.asr.recognition.RecognitionParam;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.Constants;
import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.TargetDataLine;
import java.nio.ByteBuffer;

public class Main {
    public static void main(String[] args) throws NoApiKeyException {
        // The following is the configuration for the Singapore region. When calling, replace "{WorkspaceId}" with your real workspace ID. Configurations differ by region.
        Constants.baseWebsocketApiUrl = "wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference";
        // Create a Flowable<ByteBuffer>
        Flowable<ByteBuffer> audioSource =
                Flowable.create(
                        emitter -> {
                            new Thread(
                                    () -> {
                                        try {
                                            // Create the audio format
                                            AudioFormat audioFormat = new AudioFormat(16000, 16, 1, true, false);
                                            // Match the default recording device based on the format
                                            TargetDataLine targetDataLine =
                                                    AudioSystem.getTargetDataLine(audioFormat);
                                            targetDataLine.open(audioFormat);
                                            // Start recording
                                            targetDataLine.start();
                                            ByteBuffer buffer = ByteBuffer.allocate(1024);
                                            long start = System.currentTimeMillis();
                                            // Record for 50s and perform real-time transcription
                                            while (System.currentTimeMillis() - start < 50000) {
                                                int read = targetDataLine.read(buffer.array(), 0, buffer.capacity());
                                                if (read > 0) {
                                                    buffer.limit(read);
                                                    // Send the recorded audio data to the streaming recognition service
                                                    emitter.onNext(buffer);
                                                    buffer = ByteBuffer.allocate(1024);
                                                    // The recording rate is limited; sleep for a short while to prevent excessive CPU usage
                                                    Thread.sleep(20);
                                                }
                                            }
                                            // Notify that transcription has ended
                                            emitter.onComplete();
                                        } catch (Exception e) {
                                            emitter.onError(e);
                                        }
                                    })
                                    .start();
                        },
                        BackpressureStrategy.BUFFER);

        // Create the Recognizer
        Recognition recognizer = new Recognition();
        // Create RecognitionParam and pass the Flowable<ByteBuffer> created above into the audioFrames parameter
        RecognitionParam param = RecognitionParam.builder()
                .model("qwen-audio-3.0-asr-flash-streaming")
                // The API Key differs between the Singapore and Beijing regions. Get an 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 Model Studio API Key: .apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .format("pcm")
                .sampleRate(16000)
                .build();

        // Streaming call interface
        recognizer
                .streamCall(param, audioSource)
                .blockingForEach(
                        result -> {
                            // Subscribe to the output result
                            if (result.isSentenceEnd()) {
                                System.out.println("Final Result: " + result.getSentence().getText());
                            } else {
                                System.out.println("Intermediate Result: " + result.getSentence().getText());
                            }
                        });
        // Close the WebSocket connection after the task is complete
        recognizer.getDuplexApi().close(1000, "bye");
        System.out.println(
                "[Metric] requestId: "
                        + recognizer.getLastRequestId()
                        + ", first package delay ms: "
                        + recognizer.getFirstPackageDelay()
                        + ", last package delay ms: "
                        + recognizer.getLastPackageDelay());
        System.exit(0);
    }
}

Chamadas de alta concorrência

O DashScope Java SDK utiliza o pool de conexões do OkHttp3 para reduzir a sobrecarga de estabelecimento repetido de conexões. Para mais detalhes, consulte Optimize Paraformer real-time speech recognition for high concurrency.

Parâmetros de solicitação

Use os métodos encadeados de RecognitionParam para configurar modelo, taxa de amostragem, formato de áudio e outros parâmetros. Passe o objeto configurado para o método call/streamCall da The Recognition class.

Clique para visualizar o exemplo

RecognitionParam param = RecognitionParam.builder()
  .model("qwen-audio-3.0-asr-flash-streaming")
  .format("pcm")
  .sampleRate(16000)
  //.parameter("language_hints", new String[]{"zh"})
  .build();
ParâmetroTipoObrigatórioDescrição

model

String

Sim

Nome do modelo. As séries Qwen-Audio-3.0-ASR-Flash-Streaming e Fun-ASR-Realtime são suportadas. Para mais detalhes, consulte Supported models and regions.

sampleRate

Integer

Sim

Taxa de amostragem, em Hz.

Valores válidos: modelos de 8 kHz suportam apenas 8000 Hz; demais modelos aceitam qualquer taxa.

format

String

Sim

Formato de áudio.

Valores válidos:

  • pcm
  • wav
  • mp3
  • opus
  • speex
  • aac
  • amr

Importanteopus/speex: Devem usar encapsulamento Ogg.

wav: Deve usar codificação PCM.

amr: Apenas o tipo AMR-NB é suportado.

vocabularyId

String

Não

ID de uma lista de palavras-chave pré-compilada.

Gere esse ID antecipadamente chamando a API de criação de lista de palavras-chave. Passe o ID durante o reconhecimento para usar as palavras-chave da lista.

Adequado para cenários com vocabulário conhecido e relativamente estável, nos quais é necessário reutilizar a mesma lista entre solicitações.

Para detalhes de uso, consulte Precompiled hotwords.

vocabulary

Map<String, Integer>

Não

Palavras-chave instantâneas.

Passadas como pares chave-valor, onde a chave é o texto da palavra-chave (string) e o valor é o peso (integer). Não é necessário criar uma lista antecipadamente. O peso varia de [1, 5] ou é definido como 50: valores em [1, 5] aumentam a probabilidade de o modelo gerar a palavra conforme o valor cresce; o valor 50 designa uma super palavra-chave, que melhora significativamente a recuperação, mas o número de super palavras-chave não pode exceder 50.

Adequado para otimização temporária de palavras-chave no nível de sessão.

Quando configurado junto com palavras-chave pré-compiladas, apenas as instantâneas têm efeito. Para detalhes de uso, consulte Instant hotwords.

ImportanteApenas qwen-audio-3.0-asr-flash-streaming suporta palavras-chave instantâneas.

ObservaçãoDefina vocabulary pelo método parameter ou parameters da instância RecognitionParam:

Map<String, Integer> vocab = new HashMap<>();
vocab.put("John Smith", 5);
vocab.put("Jane Doe", 5);

RecognitionParam param = RecognitionParam.builder()
        .model("qwen-audio-3.0-asr-flash-streaming")
        .format("pcm")
        .sampleRate(16000)
        .parameter("vocabulary", vocab)
        .build();
Map<String, Integer> vocab = new HashMap<>();
vocab.put("John Smith", 5);
vocab.put("Jane Doe", 5);

Map<String, Object> parameters = new HashMap<>();
parameters.put("vocabulary", vocab);

RecognitionParam param = RecognitionParam.builder()
        .model("qwen-audio-3.0-asr-flash-streaming")
        .format("pcm")
        .sampleRate(16000)
        .parameters(parameters)
        .build();

semantic_punctuation_enabled

boolean

Não

Ativa a segmentação semântica.

Valor padrão: false.

  • true: Ativa a segmentação semântica e desativa a segmentação VAD.
  • false (padrão): Ativa a segmentação VAD e desativa a segmentação semântica.

A segmentação semântica é mais precisa e adequada para transcrição de reuniões. Já a segmentação VAD (Voice Activity Detection) apresenta menor latência, sendo ideal para cenários interativos.

ObservaçãoDefina semantic_punctuation_enabled pelo método parameter ou parameters da instância RecognitionParam:

RecognitionParam param = RecognitionParam.builder()
 .model("qwen-audio-3.0-asr-flash-streaming")
 .format("pcm")
 .sampleRate(16000)
 .parameter("semantic_punctuation_enabled", true)
 .build();
RecognitionParam param = RecognitionParam.builder()
 .model("qwen-audio-3.0-asr-flash-streaming")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("semantic_punctuation_enabled", true))
 .build();

max_sentence_silence

Integer

Não

Limiar de silêncio VAD para segmentação, em ms. Se o silêncio após um segmento de fala superar esse limiar, o sistema considera a frase encerrada. Quando semantic_punctuation_enabled é true, este parâmetro deixa de ser critério para retornar sentence_end, mas valores muito baixos podem afetar o desempenho do reconhecimento.

Valor padrão: 1300.

Valores válidos: [200, 6000].

ObservaçãoDefina max_sentence_silence pelo método parameter ou parameters da instância RecognitionParam:

RecognitionParam param = RecognitionParam.builder()
 .model("qwen-audio-3.0-asr-flash-streaming")
 .format("pcm")
 .sampleRate(16000)
 .parameter("max_sentence_silence", 800)
 .build();
RecognitionParam param = RecognitionParam.builder()
 .model("qwen-audio-3.0-asr-flash-streaming")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("max_sentence_silence", 800))
 .build();

multi_threshold_mode_enabled

boolean

Não

ImportanteTem efeito apenas quando semantic_punctuation_enabled é false.

Ativa o modo de múltiplos limiares. Quando ativado, evita que segmentos VAD fiquem excessivamente longos.

Valor padrão: false.

ObservaçãoDefina multi_threshold_mode_enabled pelo método parameter ou parameters da instância RecognitionParam:

RecognitionParam param = RecognitionParam.builder()
 .model("qwen-audio-3.0-asr-flash-streaming")
 .format("pcm")
 .sampleRate(16000)
 .parameter("multi_threshold_mode_enabled", true)
 .build();
RecognitionParam param = RecognitionParam.builder()
 .model("qwen-audio-3.0-asr-flash-streaming")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("multi_threshold_mode_enabled", true))
 .build();

punctuation_prediction_enabled

boolean

Não

Define se a pontuação deve ser adicionada automaticamente aos resultados:

  • true (padrão): sim. Este valor não pode ser alterado.

ObservaçãoDefina punctuation_prediction_enabled pelo método parameter ou parameters da instância RecognitionParam:

RecognitionParam param = RecognitionParam.builder()
 .model("qwen-audio-3.0-asr-flash-streaming")
 .format("pcm")
 .sampleRate(16000)
 .parameter("punctuation_prediction_enabled", false)
 .build();
RecognitionParam param = RecognitionParam.builder()
 .model("qwen-audio-3.0-asr-flash-streaming")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("punctuation_prediction_enabled", false))
 .build();

heartbeat

boolean

Não

Ativa pacotes de heartbeat.

Valor padrão: false.

  • true: Mantém a conexão com o servidor ativa mesmo durante envio contínuo de áudio silencioso.
  • false (padrão): Mesmo com envio contínuo de áudio silencioso, a conexão expira e fecha após determinado período.

Áudio silencioso refere-se a conteúdo sem sinal sonoro em um arquivo ou fluxo de dados. É possível gerá-lo de várias formas, usando softwares de edição como Audacity ou Adobe Audition, ou ferramentas de linha de comando como FFmpeg.

ObservaçãoPara usar este campo, a versão do SDK deve ser 2.19.1 ou posterior.

Defina heartbeat pelo método parameter ou parameters da instância RecognitionParam:

RecognitionParam param = RecognitionParam.builder()
 .model("qwen-audio-3.0-asr-flash-streaming")
 .format("pcm")
 .sampleRate(16000)
 .parameter("heartbeat", true)
 .build();
RecognitionParam param = RecognitionParam.builder()
 .model("qwen-audio-3.0-asr-flash-streaming")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("heartbeat", true))
 .build();

language_hints

String[]

Não

Idioma do áudio a ser reconhecido. Não há valor padrão; se omitido, o modelo detecta o idioma automaticamente.

Para a série Qwen-Audio-3.0-ASR-Flash-Streaming, é possível definir até 4 valores; caso defina mais, apenas os 4 primeiros terão efeito. Para a série Fun-ASR-Realtime, apenas 1 valor é aceito; se houver vários, somente o primeiro será considerado.

Clique para visualizar os códigos de idioma suportados

  • qwen-audio-3.0-asr-flash-streaming, fun-asr-realtime, fun-asr-realtime-2025-11-07:

    • zh: Chinês
    • en: Inglês
    • ja: Japonês
    • ko: Coreano
    • vi: Vietnamita
    • th: Tailandês
    • id: Indonésio
    • ms: Malaio
    • tl: Filipino
    • hi: Hindi
    • ar: Árabe
    • fr: Francês
    • de: Alemão
    • es: Espanhol
    • pt: Português
    • ru: Russo
    • it: Italiano
    • nl: Holandês
    • sv: Sueco
    • da: Dinamarquês
    • fi: Finlandês
    • no: Norueguês
    • el: Grego
    • pl: Polonês
    • cs: Tcheco
    • hu: Húngaro
    • ro: Romeno
    • bg: Búlgaro
    • hr: Croata
    • sk: Eslovaco
  • fun-asr-realtime-2026-02-28:

    • zh: Chinês
    • en: Inglês
    • ja: Japonês
  • fun-asr-realtime-2025-09-15:

    • zh: Chinês
    • en: Inglês
  • fun-asr-flash-8k-realtime, fun-asr-flash-8k-realtime-2026-01-28:

    • zh: Chinês

ObservaçãoDefina language_hints pelo método parameter ou parameters da instância RecognitionParam:

RecognitionParam param = RecognitionParam.builder()
 .model("qwen-audio-3.0-asr-flash-streaming")
 .format("pcm")
 .sampleRate(16000)
 .parameter("language_hints", new String[]{"zh"})
 .build();
RecognitionParam param = RecognitionParam.builder()
 .model("qwen-audio-3.0-asr-flash-streaming")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("language_hints", new String[]{"zh"}))
 .build();

speech_noise_threshold

float

Não

Limiar para distinguir fala de ruído, usado para ajustar a sensibilidade da Detecção de Atividade de Voz (VAD).

Valores válidos: [-1,0, 1,0].

Descrições dos valores:

  • Quanto mais próximo de -1: O limiar de ruído diminui, aumentando a probabilidade de ruído ser reconhecido como fala, o que pode resultar em transcrição de mais ruído.
  • Quanto mais próximo de +1: O limiar de ruído aumenta, elevando a chance de fala ser confundida com ruído, o que pode filtrar parte da fala.

Trata-se de um parâmetro avançado. Ajustá-lo pode impactar significativamente os resultados. Recomendações:

  • Teste e valide minuciosamente os resultados antes de ajustar.
  • Faça ajustes incrementais conforme o ambiente de áudio real (recomenda-se passo de 0,1).

ObservaçãoDefina speech_noise_threshold pelo método parameter ou parameters da instância RecognitionParam:

RecognitionParam param = RecognitionParam.builder()
 .model("qwen-audio-3.0-asr-flash-streaming")
 .format("pcm")
 .sampleRate(16000)
 .parameter("speech_noise_threshold", -0.5)
 .build();
RecognitionParam param = RecognitionParam.builder()
 .model("qwen-audio-3.0-asr-flash-streaming")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("speech_noise_threshold", -0.5))
 .build();

special_word_filter

String

Não

Especifica palavras sensíveis a serem processadas durante o reconhecimento, permitindo definir métodos distintos para cada palavra. Para mais detalhes, consulte Sensitive word filtering.

ObservaçãoDefina special_word_filter pelo método parameter ou parameters da instância RecognitionParam:

// 1. Build the outermost object
JSONObject root = new JSONObject();
root.put("system_reserved_filter", true);

// 2. Build the "remove completely from results" configuration
JSONObject root1 = new JSONObject();
JSONArray array1 = new JSONArray();
array1.put("start");
array1.put("proceed");
root1.put("word_list", array1);

// 3. Build the "replace with equal-length *" configuration
JSONObject root2 = new JSONObject();
JSONArray array2 = new JSONArray();
array2.put("test");
root2.put("word_list", array2);

// 4. Assemble
root.put("filter_with_empty", root1);
root.put("filter_with_signed", root2);

RecognitionParam param = RecognitionParam.builder()
 .model("qwen-audio-3.0-asr-flash-streaming")
 .format("pcm")
 .sampleRate(16000)
 .parameter("special_word_filter", root.toString())
 .build();
// 1. Build the outermost object
JSONObject root = new JSONObject();
root.put("system_reserved_filter", true);

// 2. Build the "remove completely from results" configuration
JSONObject root1 = new JSONObject();
JSONArray array1 = new JSONArray();
array1.put("start");
array1.put("proceed");
root1.put("word_list", array1);

// 3. Build the "replace with equal-length *" configuration
JSONObject root2 = new JSONObject();
JSONArray array2 = new JSONArray();
array2.put("test");
root2.put("word_list", array2);

// 4. Assemble
root.put("filter_with_empty", root1);
root.put("filter_with_signed", root2);

RecognitionParam param = RecognitionParam.builder()
 .model("qwen-audio-3.0-asr-flash-streaming")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("special_word_filter", root.toString()))
 .build();

input

Map<String, Object>

Não

Objeto de entrada que fornece o contexto da conversa. O contexto auxilia no reconhecimento e melhora a precisão de termos específicos. Para uso, consulte Quick start.

ImportanteApenas os modelos qwen-audio-3.0-asr-flash-streaming, fun-asr-realtime e fun-asr-realtime-2025-11-07 suportam o parâmetro de contexto.

O Map deve conter a chave context, cujo valor é um array de mensagens do tipo List<Map<String, Object>>. Cada mensagem contém os seguintes campos:

  • role (String, obrigatório): função da mensagem. user indica resultado de reconhecimento de fala do usuário em rodadas anteriores ou lista de palavras específicas de domínio. assistant indica respostas do modelo de linguagem grande em rodadas anteriores.
  • content (List<Map>, obrigatório): lista de conteúdo da mensagem. Cada elemento contém type (String; defina como input_text quando role é user e como text quando role é assistant) e text (String, conteúdo textual).

ImportanteLimites: mensagens de contexto dos tipos input_text e text limitam-se a 5 cada; ao exceder, mantém-se as 5 mais recentes. O comprimento total do texto por rodada não pode ultrapassar 400 caracteres, truncando-se o excesso a partir do final.

ImportanteAo passar contexto, as mensagens em context devem seguir ordem específica: organize-as por rodada de conversa e, dentro de cada rodada, a mensagem user (tipo input_text) deve preceder a mensagem assistant correspondente (tipo text).

ObservaçãoPara usar este campo, a versão do SDK deve ser 2.22.23 ou posterior.

Defina input pelo método input da instância RecognitionParam:

// 1. Build the input struct
          Map<String, Object> userContent = new HashMap<>();
          userContent.put("type", "input_text");
          userContent.put("text", "Hello there");

          Map<String, Object> assistantContent = new HashMap<>();
          assistantContent.put("type", "text");
          assistantContent.put("text", "Hello, I am Qwen. How can I help you?");

          Map<String, Object> userMessage = new HashMap<>();
          userMessage.put("role", "user");
          userMessage.put("content", Arrays.asList(userContent));

          Map<String, Object> assistantMessage = new HashMap<>();
          assistantMessage.put("role", "assistant");
          assistantMessage.put("content", Arrays.asList(assistantContent));

          Map<String, Object> input = new HashMap<>();
          input.put("context", Arrays.asList(userMessage, assistantMessage));

          // 2. Pass it in through the input method
          RecognitionParam param = RecognitionParam.builder()
           .model("qwen-audio-3.0-asr-flash-streaming")
           .format("pcm")
           .sampleRate(16000)
           .input(input)
           .build();

apiKey

String

Não

Sua chave de API.

Interfaces principais

Classe Recognition

Importe Recognition com import com.alibaba.dashscope.audio.asr.recognition.Recognition;. Suas interfaces principais são:

Interface/MétodoParâmetroValor de retornoDescrição
public void call(RecognitionParam param, final ResultCallback<RecognitionResult> callback)

Nenhum

Reconhecimento em tempo real via streaming baseado em callback. Não bloqueia a thread atual.

public String call(RecognitionParam param, File file)

Resultado do reconhecimento.

Reconhecimento não streaming de arquivo local. Bloqueia a thread atual até concluir a leitura completa do arquivo, que deve ser legível.

public Flowable<RecognitionResult> streamCall(RecognitionParam param, Flowable<ByteBuffer> audioFrame)

Flowable<RecognitionResult>

Reconhecimento em tempo real via streaming baseado em Flowable.

public void sendAudioFrame(ByteBuffer audioFrame)
  • audioFrame: Fluxo de áudio binário do tipo ByteBuffer.

Nenhum

Envia áudio. Mantenha cada bloco enviado com tamanho razoável. Recomenda-se cerca de 100 ms de áudio por bloco, entre 1 KB e 16 KB.

Os resultados chegam pelo método onEvent da The callback interface (ResultCallback).

public void stop()

Nenhum

Nenhum

Interrompe o reconhecimento em tempo real.

Bloqueia a thread atual até que o callback ResultCallback invoque onComplete ou onError.

boolean getDuplexApi().close(int code, String reason)

code: Código de fechamento WebSocket.

reason: Motivo do fechamento.

Para orientações sobre esses parâmetros, consulte The WebSocket Protocol.

true

Sempre feche a conexão WebSocket ao término da tarefa, haja ou não exceção, para evitar vazamentos. Para reutilizar conexões visando eficiência, consulte Optimize Paraformer real-time speech recognition for high concurrency.

public String getLastRequestId()

Nenhum

requestId

Obtém o requestId da tarefa atual. Disponível após iniciar nova tarefa com call ou streamingCall.

ObservaçãoDisponível apenas no SDK versão 2.18.0 ou posterior.

public long getFirstPackageDelay()

Nenhum

Latência do primeiro pacote.

Obtém a latência do primeiro pacote, ou seja, o atraso entre o envio do primeiro pacote de áudio e o recebimento do primeiro resultado. Use após concluir a tarefa.

ObservaçãoDisponível apenas no SDK versão 2.18.0 ou posterior.

public long getLastPackageDelay()

Nenhum

Latência do último pacote.

Obtém a latência do último pacote, ou seja, o tempo entre o envio do comando stop e o recebimento do resultado final. Use após concluir a tarefa.

ObservaçãoDisponível apenas no SDK versão 2.18.0 ou posterior.

Interface de callback (ResultCallback)

Durante bidirectional streaming calls, o servidor retorna informações-chave e dados ao cliente via callbacks. Implemente os métodos de callback para tratar essas informações.

Estenda a classe abstrata ResultCallback para implementar os métodos. Ao estendê-la, defina o tipo genérico como RecognitionResult. RecognitionResult encapsula a estrutura de dados retornada pelo servidor.

Como o Java suporta reutilização de conexão, não há onClose nem onOpen.

Exemplo

ResultCallback<RecognitionResult> callback = new ResultCallback<RecognitionResult>() {
    @Override
    public void onEvent(RecognitionResult result) {
        System.out.println("RequestId: " + result.getRequestId());
        // Add your logic to process the speech recognition result here.
    }

    @Override
    public void onComplete() {
        System.out.println("Task complete");
    }

    @Override
    public void onError(Exception e) {
        System.out.println("Task failed: " + e.getMessage());
    }
};
Interface/MétodoParâmetroValor de retornoDescrição
public void onEvent(RecognitionResult result)

result: Real-time recognition result (RecognitionResult)

Nenhum

Invocado quando o servidor envia resposta.

public void onComplete()

Nenhum

Nenhum

Invocado após a conclusão da tarefa.

public void onError(Exception e)

e: Informações da exceção.

Nenhum

Invocado quando ocorre exceção.

Resposta

Resultado de reconhecimento em tempo real (RecognitionResult)

RecognitionResult representa o resultado de um único reconhecimento em tempo real.

Interface/MétodoParâmetroValor de retornoDescrição
public String getRequestId()

Nenhum

requestId

Obtém o requestId.

public boolean isSentenceEnd()

Nenhum

Indica se uma frase completa foi formada, ou seja, se houve detecção de limite de frase.

Determina se a frase terminou.

public Sentence getSentence()

Nenhum

Sentence information (Sentence)

Obtém informações da frase, incluindo timestamps e texto.

Informações da frase (Sentence)

Interface/MétodoParâmetroValor de retornoDescrição
public Long getBeginTime()

Nenhum

Tempo inicial da frase, em ms.

Retorna o tempo inicial da frase.

public Long getEndTime()

Nenhum

Tempo final da frase, em ms.

Retorna o tempo final da frase.

public String getText()

Nenhum

Texto reconhecido.

Retorna o texto reconhecido.

public List<Word> getWords()

Nenhum

Lista de objetos Word-level timestamp information (Word).

Retorna timestamps no nível de palavra.

Timestamps no nível de palavra (Word)

Interface/MétodoParâmetroValor de retornoDescrição
public long getBeginTime()

Nenhum

Tempo inicial da palavra, em ms.

Retorna o tempo inicial da palavra.

public long getEndTime()

Nenhum

Tempo final da palavra, em ms.

Retorna o tempo final da palavra.

public String getText()

Nenhum

Palavra.

Retorna a palavra reconhecida.

public String getPunctuation()

Nenhum

Pontuação.

Retorna a pontuação.

Códigos de erro

Em caso de erros, consulte Error codes para solução de problemas.

Se o problema persistir, junte-se à comunidade de desenvolvedores para relatá-lo e forneça o Request ID para investigação.

FAQ

Recursos

P: Como manter a conexão com o servidor ativa durante longos períodos de silêncio?

Defina o parâmetro heartbeat como true e continue enviando áudio silencioso ao servidor.

Áudio silencioso é aquele sem sinal sonoro no arquivo ou fluxo de dados. Gere-o de várias formas, por exemplo, com softwares de edição como Audacity ou Adobe Audition, ou ferramentas de linha de comando como FFmpeg.

P: Como converter áudio para um formato suportado?

Use a ferramenta FFmpeg. Para mais usos, consulte o site oficial do FFmpeg.

# Basic conversion command (universal template)
# -i, purpose: input file path, example values: audio.wav
# -c:a, purpose: audio encoder, example values: aac, libmp3lame, pcm_s16le
# -b:a, purpose: bitrate (audio quality control), example values: 192k, 320k
# -ar, purpose: sample rate, example values: 44100 (CD), 48000, 16000
# -ac, purpose: number of channels, example values: 1 (mono), 2 (stereo)
# -y, purpose: overwrite an existing file (no value needed)
ffmpeg -i input_audio.ext -c:a encoder_name -b:a bitrate -ar sample_rate -ac channels output.ext

# Example: WAV -> MP3 (preserve original quality)
ffmpeg -i input.wav -c:a libmp3lame -q:a 0 output.mp3
# Example: MP3 -> WAV (16-bit PCM standard format)
ffmpeg -i input.mp3 -c:a pcm_s16le -ar 44100 -ac 2 output.wav
# Example: M4A -> AAC (extract/convert Apple audio)
ffmpeg -i input.m4a -c:a copy output.aac  # Extract directly without re-encoding
ffmpeg -i input.m4a -c:a aac -b:a 256k output.aac  # Re-encode for higher quality
# Example: FLAC lossless -> Opus (high compression)
ffmpeg -i input.flac -c:a libopus -b:a 128k -vbr on output.opus

P: Como reconhecer um arquivo local (gravação)?

Há duas maneiras de reconhecer um arquivo local:

Solução de problemas

P: Por que a fala não é reconhecida (sem resultado)?

  1. Verifique se o formato de áudio (format) e a taxa de amostragem (sampleRate/sample_rate) nos parâmetros estão corretos e atendem às restrições. Erros comuns incluem:

    • Arquivo com extensão .wav, mas formato MP3, enquanto o parâmetro format está definido como mp3 (configuração incorreta).
    • Taxa de amostragem do áudio é 3600 Hz, mas o parâmetro sampleRate/sample_rate está definido como 48000 (configuração incorreta).

    Use a ferramenta ffprobe para obter informações sobre contêiner, codec, taxa de amostragem, canais e outros dados do áudio:

ffprobe -v error -show_entries format=format_name -show_entries stream=codec_name,sample_rate,channels -of default=noprint_wrappers=1 input.xxx
  1. Verifique se o idioma definido em language_hints corresponde ao idioma real do áudio.

    Por exemplo, áudio em chinês, mas language_hints definido como en (inglês).

  2. Se nenhuma verificação acima revelar o problema, configure palavras-chave personalizadas para melhorar o reconhecimento de termos específicos.