QwenCloudBRASIL
Tradução de apoio para consulta. Código e identificadores técnicos preservados. Consultar referência original ↗

Qwen-Audio-3.x-ASR-Flash-Streaming/Fun-ASR-Realtime SDK Java

SDK Java ASR em tempo real para Qwen-Audio-3.x-ASR-Flash-Streaming/Fun-ASR-Realtime

Guia do usuário: Para obter uma introdução aos modelos e orientação sobre a seleção de modelos, consulte Fala para texto.

Início rápido

A classe de reconhecimento fornece interfaces para chamadas síncronas e chamadas de streaming bidirecionais. Escolha a abordagem que atenda às suas necessidades:

Chamada síncrona

Envie uma única tarefa de reconhecimento de fala em tempo real e obtenha o resultado do reconhecimento de forma síncrona, passando um arquivo local. A chamada é bloqueada até que o resultado seja retornado.

Instancie a classe de reconhecimento e ligue para o call método para vincular [parâmetros de solicitação] (#request-parameters) e o arquivo a ser reconhecido. O método realiza o reconhecimento e retorna o resultado final.

Clique para ver 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) {
    // Create a Recognition instance
    Recognition recognizer = new Recognition();
    // Create RecognitionParam
    RecognitionParam param =
        RecognitionParam.builder()
            .model("qwen-audio-3.1-asr-flash-streaming")
            // If you have not configured the environment variable, replace the following line with your 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 retorno de chamada

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

Comece a transmitir reconhecimento.

Instancie a [classe de reconhecimento](#recognition-class) e ligue para o `call` método para vincular [parâmetros de solicitação] (#request-parameters) e a [interface de retorno de chamada (ResultCallback)](#callback-interface-resultcallback) e inicie o streaming do reconhecimento de fala.

Stream the audio

Ligue para o `sendAudioFrame` método da [classe de reconhecimento](#recognition-class) em um 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 estão sendo enviados, o servidor retorna os resultados do reconhecimento ao cliente em tempo real através do `onEvent` método da [interface de retorno de chamada (ResultCallback)](#callback-interface-resultcallback).

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

End the process

Ligue para o `stop` método da [classe de reconhecimento](#recognition-class) para encerrar o reconhecimento de fala.

Este método bloqueia o thread atual até que o `onComplete` ou `onError` retorno de chamada da [interface de retorno de chamada (ResultCallback)](#callback-interface-resultcallback) é acionado e, nesse ponto, o thread é liberado.

Clique para ver o exemplo completo.

Recognize speech from a microphone

  ```java
  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 {
      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")
          // If you have not configured the environment variable, replace the following line with your 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());
    }
  }
  ```

Recognize a local audio file

  ```java
  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 {
      // 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.1-asr-flash-streaming")
          // If you have not configured the environment variable, replace the following line with your 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 do reconhecimento em tempo real implementando um fluxo de trabalho (Flowable).

Flowable é uma estrutura de código aberto para fluxo de trabalho e gerenciamento de processos de negócios, lançada sob a licença Apache 2.0. Para saber como usar o Flowable, consulte Detalhes da API do Flowable.

Clique para ver o exemplo completo.

Ligue para o streamCall método da classe de reconhecimento diretamente para iniciar o reconhecimento.

O streamCall método retorna um Flowable<RecognitionResult> instância. Utilize métodos do Flowable exemplo, como blockingForEach ou subscribe, para processar os resultados do reconhecimento. Cada resultado é envolvido em um RecognitionResult.

O streamCall método leva dois parâmetros:

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 {
    // 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")
        // If you have not configured the environment variable, replace the following line with your 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 simultaneidade

O DashScope Java SDK usa o pool de conexões do OkHttp3 para reduzir a sobrecarga de estabelecer conexões repetidamente. Para obter detalhes, consulte Otimizar o reconhecimento de fala em tempo real do Paraformer para alta simultaneidade.

Parâmetros de solicitação

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

Clique para ver 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âmetro Tipo Obrigatório Descrição
modelo Corda Sim O nome do modelo. O Qwen-Audio-3.x-ASR-Flash-Streaming e Fun-ASR-Realtime séries de modelos são suportadas. Para obter detalhes, consulte Modelos suportados.
taxa de amostra Inteiro Sim A taxa de amostragem, em Hz. Valores válidos: modelos de 8 kHz suportam apenas 8.000 Hz; outros modelos suportam qualquer taxa de amostragem.
formato Corda Sim O formato de áudio. Valores válidos: pcm, wav, mp3, opus, speex, aac, amr.
opus/speex: Deve usar encapsulamento Ogg. wav: Deve usar codificação PCM. amr: Somente o tipo AMR-NB é suportado.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |

| manter_dialeto | booleano | Não | Apoiado por qwen-audio-3.1-asr-flash-streaming apenas. O padrão é false, que transcreve dialetos para o chinês padrão. Definir como true para preservar expressões dialetais. Definir com .parameter("keep_dialect", value). Consulte referência da API para obter detalhes. | | vad_modelo | Corda | Não | Apoiado por qwen-audio-3.1-asr-flash-streaming apenas. Definir como near_meeting_16k (campo próximo) ou far_field_meeting_16k (campo distante, padrão). Definir com .parameter("vad_model", value). Consulte referência da API para obter detalhes. | | vocabulárioId | Corda | Não | O ID de uma lista de hot word pré-compilada. Gere esse ID antecipadamente chamando a API de criação de lista de palavras quentes. Passe o ID durante o reconhecimento para usar as palavras quentes da lista. Adequado para cenários onde o vocabulário é conhecido e relativamente estável, e onde é necessário reutilizar a mesma lista de palavras em solicitações. Para obter detalhes de uso, consulte Hotwords pré-compiladas. | | vocabulário | Mapa
| Não | Palavras quentes instantâneas. Passados como pares de valores-chave, onde a chave é o texto da palavra quente (string) e o valor é o peso da palavra quente (integer). Nenhuma lista de palavras quentes precisa ser criada com antecedência. O peso varia de [1, 5] ou é definido como 50: um valor em [1, 5] aumenta a probabilidade de o modelo gerar a palavra à medida que o valor aumenta; um valor de 50 designa uma palavra superquente, o que melhora muito a recuperação, mas o número de palavras superquentes não pode exceder 50. Adequado para otimização de palavra quente temporária em nível de sessão. Quando hotwords instantâneas e pré-compiladas são configuradas juntas, o sistema mescla os dois conjuntos. Se o conjunto mesclado contiver mais de 2.000 hotwords, o sistema selecionará aleatoriamente 2.000 para usar. Para obter detalhes de uso, consulte Hotwords instantâneas. Somente qwen-audio-3.1-asr-flash-streaming e qwen-audio-3.0-asr-flash-streaming suporta palavras quentes instantâneas. | | semântica_pontuação_habilitada | booleano | Não | Seja para ativar a segmentação semântica. Valor padrão: falso. true: ativa a segmentação semântica e desativa a segmentação VAD. false (padrão): habilita a segmentação VAD e desabilita a segmentação semântica. A segmentação semântica é mais precisa e mais adequada para atender cenários de transcrição. A segmentação VAD (Voice Activity Detection) tem menor latência e é mais adequada para cenários interativos. | | max_frase_silêncio | Inteiro | Não | O limite de silêncio do VAD para segmentação, em ms. Quando o silêncio após um segmento de fala ultrapassa esse limite, o sistema determina que a frase terminou. Quando semantic_punctuation_enabled estiver definido como verdadeiro, este parâmetro não será usado como critério para retornar sentence_end, mas defini-lo muito baixo pode afetar o desempenho do reconhecimento. Valor padrão: 1300. Valores válidos: [200, 6000]. | | multi_limite_modo_enabled | booleano | Não | Só entra em vigor quando semantic_punctuation_enabled é falso. Se deve ativar o modo multi-limite. Quando ativado, evita que os segmentos VAD se tornem muito longos. Valor padrão: falso. | | pontuação_predição_habilitado | booleano | Não | Define se a pontuação será adicionada automaticamente aos resultados do reconhecimento: true (padrão): sim. Este valor não pode ser alterado. | | batimento cardíaco | booleano | Não | Se deve ativar pacotes de pulsação. Valor padrão: falso. true: mantém a conexão com o servidor ativa mesmo quando o áudio silencioso é enviado continuamente. false (padrão): Mesmo quando o áudio silencioso é enviado continuamente, a conexão atinge o tempo limite e fecha após um período de tempo. Áudio silencioso refere-se ao conteúdo de um arquivo de áudio ou fluxo de dados que não contém sinal sonoro. Você pode gerar áudio silencioso de várias maneiras, como usando software de edição de áudio como Audacity ou Adobe Audition, ou usando uma ferramenta de linha de comando como FFmpeg. Para usar este campo, a versão do SDK deve ser 2.19.1 ou posterior. | | idioma_dicas | Cadeia[] | Não | O idioma do áudio a ser reconhecido. Não há valor padrão; se não for definido, o modelo detectará o idioma automaticamente. Para o Qwen-Audio-3.x-ASR-Flash-Streaming série de modelos, você pode definir até 4 valores; se você definir mais de 4, apenas os 4 primeiros terão efeito. Para o Fun-ASR-Realtime série de modelos, você pode definir apenas 1 valor; se você definir vários valores, apenas o primeiro terá efeito.<ul><li>qwen-audio-3.1-asr-flash-streaming, qwen-audio-3.0-asr-flash-streaming, fun-asr-realtime: zh, en, ja, ko, vi, th, id, ms, tl, oi, ar, fr, de, es, pt, ru, it, nl, sv, da, fi, não, el, pl, cs, hu, ro, bg, hr, sk</li></ul> | | fala_ruído_limiar | flutuar | Não | O limite 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]. Quanto mais próximo o valor estiver de -1: o limite de ruído diminui, então é mais provável que o ruído seja reconhecido como fala, o que pode fazer com que mais ruído seja transcrito. Quanto mais próximo o valor estiver de +1: O limite de ruído aumenta, então é mais provável que a fala seja mal avaliada como ruído, o que pode fazer com que parte da fala seja filtrada. Este é um parâmetro de configuração avançado. Ajustá-lo pode afetar significativamente os resultados do reconhecimento. Recomendações: Teste e verifique minuciosamente os resultados antes de ajustar. Ajuste em pequenos incrementos com base no ambiente de áudio real (recomenda-se um passo de 0,1). | | especial_palavra_filtro | Corda | Não | Especifica as palavras sensíveis a serem processadas durante o reconhecimento de fala e suporta a configuração de diferentes métodos de processamento para diferentes palavras sensíveis. Para obter detalhes, consulte Filtragem de palavras sensíveis. | | entrada | Mapa
| Não | Objeto de entrada que passa no contexto da conversa. O contexto ajuda no reconhecimento e melhora a precisão do reconhecimento dos termos adequados. Para uso, consulte Início rápido. Apenas o qwen-audio-3.1-asr-flash-streaming, qwen-audio-3.0-asr-flash-streaming, fun-asr-realtime modelos suportam o parâmetro de contexto. O Mapa deve conter um context chave cujo valor é uma matriz de mensagens do tipo List<Map<String, Object>>. Cada mensagem contém os seguintes campos: role (String, obrigatório): a função da mensagem. user indica o resultado do reconhecimento da fala do usuário em rodadas anteriores ou uma lista de palavras específicas do domínio. assistant indica as respostas do modelo de linguagem grande das rodadas anteriores. content (Lista
, obrigatório): a lista de conteúdo da mensagem. Cada elemento contém type (Sequência; definido como input_text quando a função é usuário, e text quando a função é assistente) e text (String, o conteúdo do texto). Limites: mensagens de contexto do input_text e text os tipos são limitados a 5 cada; os 5 mais recentes são mantidos quando o limite é excedido. O comprimento total do texto por rodada de contexto não pode exceder 400 caracteres e qualquer excesso é truncado no final.

Quando você passa no contexto, as mensagens em context devem seguir uma ordem específica: as mensagens de contexto devem ser organizadas por rodada de conversa, e dentro de cada rodada o user mensagem (input_text tipo) deve preceder o correspondente assistant mensagem (text tipo).

Para usar este campo, a versão do SDK deve ser 2.22.23 ou posterior. | | APIKey | Corda | Não | Sua chave de API. |

Definir vocabulary através do parameter método ou o parameters método do RecognitionParam exemplo:

Set through parameter

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

Defina os parâmetros.

  ```java
  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.1-asr-flash-streaming")
          .format("pcm")
          .sampleRate(16000)
          .parameters(parameters)
          .build();
  ```

Definir input através do input método do RecognitionParam exemplo:

// 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.1-asr-flash-streaming")
 .format("pcm")
 .sampleRate(16000)
 .input(input)
 .build();

Definir special_word_filter através do parameter método ou o parameters método do RecognitionParam exemplo:

Set through parameter

  ```java
  // 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.1-asr-flash-streaming")
   .format("pcm")
   .sampleRate(16000)
   .parameter("special_word_filter", root.toString())
   .build();
  ```

Defina os parâmetros.

  ```java
  // 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.1-asr-flash-streaming")
   .format("pcm")
   .sampleRate(16000)
   .parameters(Collections.singletonMap("special_word_filter", root.toString()))
   .build();
  ```

Para parâmetros que não estão no RecognitionParam construtor diretamente (como semantic_punctuation_enabled, heartbeat, max_sentence_silence, multi_threshold_mode_enabled, punctuation_prediction_enabled, speech_noise_thresholde language_hints), use o parameter ou parameters método:

Set through parameter

  ```java
  RecognitionParam param = RecognitionParam.builder()
   .model("qwen-audio-3.1-asr-flash-streaming")
   .format("pcm")
   .sampleRate(16000)
   .parameter("semantic_punctuation_enabled", true)
   .build();
  ```

Defina os parâmetros.

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

Interfaces principais

Aula de reconhecimento

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

Interface/Método Parâmetro Valor de retorno Descrição
public void call(RecognitionParam param, final ResultCallback<RecognitionResult> callback) param: Solicitar parâmetros
callback: A interface de retorno de chamada (ResultCallback) Nenhum Reconhecimento em tempo real de streaming baseado em retorno de chamada. Este método não bloqueia o thread atual.
public String call(RecognitionParam param, File file) param: Solicitar parâmetros
file: O arquivo de áudio a ser reconhecido. O resultado do reconhecimento. Reconhecimento sem streaming de um arquivo local. Este método bloqueia o thread atual até que todo o arquivo de áudio seja lido. O arquivo deve ser legível.
public Flowable<RecognitionResult> streamCall(RecognitionParam param, Flowable<ByteBuffer> audioFrame) param: Solicitar parâmetros
audioFrame: A Flowable<ByteBuffer> instância. Flowable<RecognitionResult> Reconhecimento em tempo real de streaming baseado em fluxo.
public void sendAudioFrame(ByteBuffer audioFrame) audioFrame: Um fluxo de áudio binário do tipo ByteBuffer. Nenhum Envia áudio. Mantenha cada pedaço de áudio enviado dentro de um tamanho razoável. Um bloco recomendado contém cerca de 100 ms de áudio e tem de 1 KB a 16 KB de tamanho. Os resultados do reconhecimento são entregues através do método onEvent da interface de retorno de chamada (ResultCallback).
public void stop() Nenhum Nenhum Interrompe o reconhecimento em tempo real. Este método bloqueia o thread atual até que o ResultCallback retorno de chamada onComplete ou onError é chamado.
public void updateContext(Map<String, Object> payloadInput) payloadInput: A Map<String, Object> contendo o payload.input objeto de um continue-task evento, incluindo o context campo. Não adicione um extra payload ou input invólucro. Nenhum Atualiza o contexto da conversa enquanto uma tarefa de reconhecimento está em execução, para auxiliar no reconhecimento do áudio subsequente. Quando ligar: depois de iniciar o reconhecimento de streaming com call e antes de ligar stop. Para modelos suportados e restrições de parâmetros, consulte continue-task.
Este método está disponível apenas no SDK versão 2.23.0 e posterior.
boolean getDuplexApi().close(int code, String reason) code: o código de fechamento do WebSocket.
reason: O motivo do fechamento.
Para obter orientação sobre como definir esses dois parâmetros, consulte O protocolo WebSocket. true Após o término de uma tarefa, sempre feche a conexão WebSocket, independentemente de ter ocorrido uma exceção ou não, para evitar vazamentos de conexão. Para reutilizar conexões para obter melhor eficiência, consulte Gerenciamento de alta simultaneidade.
public String getLastRequestId() Nenhum ID da solicitação Obtém o requestId da tarefa atual. Disponível após o início de uma nova tarefa com call ou streamingCall.
Este método está disponível apenas no SDK versão 2.18.0 e posterior.
                                                                                                                                                                                                                                                   |

| public long getFirstPackageDelay() | Nenhum | A 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 de reconhecimento. Use-o após a conclusão da tarefa. Este método está disponível apenas no SDK versão 2.18.0 e posterior. | | public long getLastPackageDelay() | Nenhum | A latência do último pacote. | Obtém a latência do último pacote, ou seja, o tempo desde o envio do stop comando para receber o resultado final do reconhecimento. Use-o após a conclusão da tarefa. Este método está disponível apenas no SDK versão 2.18.0 e posterior. |

Interface de retorno de chamada (ResultCallback)

Durante chamadas de streaming bidirecionais, o servidor retorna informações e dados importantes do processo ao cliente por meio de retornos de chamada. Implemente os métodos de retorno de chamada para tratar as informações ou dados retornados pelo servidor.

Implemente os métodos de retorno de chamada estendendo a classe abstrata ResultCallback. Ao estender esta classe, você pode definir o tipo genérico como RecognitionResult. RecognitionResult envolve a estrutura de dados retornada pelo servidor.

Como o Java suporta a reutilização de conexões, não há onClose ou 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étodo Parâmetro Valor de retorno Descrição
public void onEvent(RecognitionResult result) result: Resultado do reconhecimento em tempo real (RecognitionResult) Nenhum Chamado quando o servidor envia uma resposta.
public void onComplete() Nenhum Nenhum Chamado após a conclusão da tarefa.
public void onError(Exception e) e: as informações de exceção. Nenhum Chamado quando ocorre uma exceção.

Resposta

Resultado de reconhecimento em tempo real (RecognitionResult)

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

Interface/Método Parâmetro Valor de retorno Descrição
public String getRequestId() Nenhum ID da solicitação Obtém o requestId.
public boolean isSentenceEnd() Nenhum Se uma frase completa foi formada, ou seja, se foi detectado um limite de frase. Determina se a frase dada terminou.
public Sentence getSentence() Nenhum Informações da frase (frase) Obtém as informações da frase, incluindo carimbos de data/hora e texto.

Informações da frase (frase)

Interface/Método Parâmetro Valor de retorno Descrição
public Long getBeginTime() Nenhum A hora de início da frase, no ms. Retorna a hora de início da frase.
public Long getEndTime() Nenhum O tempo de término da frase, no ms. Retorna a hora de término da frase.
public String getText() Nenhum O texto reconhecido. Retorna o texto reconhecido.
public List<Word> getWords() Nenhum Uma lista de informações de carimbo de data/hora em nível de palavra (Word) objetos. Retorna informações de carimbo de data/hora em nível de palavra.

Informações de carimbo de data/hora em nível de palavra (Word)

Interface/Método Parâmetro Valor de retorno Descrição
public long getBeginTime() Nenhum A palavra hora de início, em ms. Retorna a hora de início da palavra.
public long getEndTime() Nenhum A palavra hora final, no ms. Retorna a hora de término da palavra.
public String getText() Nenhum A palavra. Retorna a palavra reconhecida.
public String getPunctuation() Nenhum A pontuação. Retorna a pontuação.

Códigos de erro

Se você encontrar erros, consulte Códigos de erro para solução de problemas.

Se o problema persistir, junte-se à comunidade de desenvolvedores para relatar seu problema e fornecer o ID da solicitação para investigação adicional.

Perguntas frequentes

Recursos

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

Defina o parâmetro de solicitação heartbeat como verdadeiro e continue enviando áudio silencioso para o servidor.

Áudio silencioso é áudio que não contém sinal sonoro no arquivo ou fluxo de dados. Você pode gerar áudio silencioso de diversas maneiras, por exemplo, usando software de edição de áudio como Audacity ou Adobe Audition, ou uma ferramenta de linha de comando como FFmpeg.

P: Como faço para converter áudio para um formato compatível?

Use a ferramenta FFmpeg. Para mais uso, 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 reconheço um arquivo local (uma gravação)?

Existem duas maneiras de reconhecer um arquivo local:

Solução de problemas

P: Por que a fala não pode ser reconhecida (sem resultado de reconhecimento)?

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

    • O arquivo de áudio tem extensão .wav, mas na verdade está no formato MP3, enquanto o parâmetro de solicitação format está definido como mp3 (configuração de parâmetro incorreta).
    • A taxa de amostragem de áudio é 3600 Hz, mas o parâmetro de solicitação sampleRate/sample_rate está definido como 48000 (configuração de parâmetro incorreta).

    Use o ffprobe ferramenta para obter o contêiner, codec, taxa de amostragem, canais e outras informações sobre o á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 language_hints corresponde ao idioma real do áudio.

    Por exemplo, o áudio está em chinês, mas language_hints está definido para en (Inglês).

  2. Se nenhuma das verificações acima revelar um problema, configure hotwords personalizados para melhorar o reconhecimento de termos específicos.