Todos los productos
Search
Centro de documentos

Alibaba Cloud Model Studio:El SDK de Java de Fun-ASR-Realtime proporciona interfaces para el reconocimiento de voz síncrono y en streaming

Última actualización: Oct 20, 2026

Este tema describe los parámetros e interfaces del SDK de Java para el reconocimiento de voz en tiempo real de Fun-ASR-Realtime.

Requisitos previos

Inicio rápido

La clase Recognition proporciona interfaces tanto para llamadas síncronas como para llamadas de streaming bidireccionales. Elija el enfoque que mejor se adapte a sus necesidades:

  • Llamada síncrona: reconoce un archivo local y devuelve el resultado completo de una vez. Ideal para procesar audio pregrabado.
  • Llamada de transmisión bidireccional: reconoce un flujo de audio directamente y devuelve resultados en tiempo real. El flujo de audio puede provenir de un dispositivo externo, como un micrófono, o leerse desde un archivo local. Ideal para escenarios que requieren retroalimentación inmediata.

Llamada síncrona

Envíe una única tarea de reconocimiento de voz en tiempo real y obtenga el resultado del reconocimiento de forma síncrona pasando un archivo local. La llamada se bloquea hasta que se devuelve el resultado.

Instancie la clase Recognition y llame al método call para vincular los Parámetros de solicitud y el archivo a reconocer. El método realiza el reconocimiento y devuelve el resultado final.

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("fun-asr-realtime")
                        // The API Key differs between the Singapore and Beijing regions. Get an API Key: https://www.alibabacloud.com/help/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);
    }
}

Llamada de transmisión bidireccional: basada en callbacks

Envíe una única tarea de reconocimiento de voz en tiempo real y transmita los resultados del reconocimiento en tiempo real implementando una interfaz de callback.

  1. Iniciar reconocimiento de voz por transmisión

    Instancie la clase Recognition y llame al método call para vincular los Parámetros de solicitud y la Interfaz de callback (ResultCallback) e inicie el reconocimiento de voz por streaming.

  2. Transmitir el audio

    Llame al método sendAudioFrame de la clase Recognition en un bucle para enviar el flujo de audio binario al servidor en segmentos. Lea el audio de un archivo local o de un dispositivo como un micrófono.

    Mientras se envían los datos de audio, el servidor devuelve resultados de reconocimiento al cliente en tiempo real a través del método onEvent de la interfaz de callback (ResultCallback).

    Envíe aproximadamente 100 ms de audio por cuadro, manteniendo cada carga útil entre 1 KB y 16 KB.

  3. Finalizar el proceso

    Llame al método stop de la clase Recognition para finalizar el reconocimiento de voz.

    Este método bloquea el hilo actual hasta que se activa el callback onComplete o onError de la interfaz de callback (ResultCallback), momento en el cual se libera el hilo.

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("fun-asr-realtime")
                // The API Key differs between the Singapore and Beijing regions. Get an API Key: https://www.alibabacloud.com/help/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("fun-asr-realtime")
                // The API Key differs between the Singapore and Beijing regions. Get an API Key: https://www.alibabacloud.com/help/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());
    }
}

Llamada de transmisión bidireccional: basada en Flowable

Envíe una única tarea de reconocimiento de voz en tiempo real y transmita los resultados del reconocimiento en tiempo real implementando un flujo de trabajo (Flowable).

Flowable es una clase en RxJava para procesar flujos de datos reactivos. Para saber cómo usar Flowable, consulte Detalles de la API de Flowable.

Llame directamente al método streamCall de la clase Recognition para iniciar el reconocimiento.

El método streamCall devuelve una instancia de Flowable<RecognitionResult>. Utilice los métodos de la instancia Flowable, como blockingForEach o subscribe, para procesar los resultados del reconocimiento. Cada resultado está encapsulado en un RecognitionResult.

El método streamCall toma dos parámetros:

  • Instancia RecognitionParam (Parámetros de solicitud): utilícela para configurar el modelo, la frecuencia de muestreo, el formato de audio y otros parámetros necesarios para el reconocimiento de voz.
  • Instancia Flowable<ByteBuffer>: cree una instancia de tipo Flowable<ByteBuffer> e implemente la lógica de análisis del flujo de audio en ella.
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("fun-asr-realtime")
                // The API Key differs between the Singapore and Beijing regions. Get an API Key: https://www.alibabacloud.com/help/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);
    }
}

Llamadas de alta concurrencia

El SDK de Java de DashScope utiliza el agrupamiento de conexiones de OkHttp3 para reducir la sobrecarga de establecer conexiones repetidamente. Para más detalles, consulte Mejores prácticas de alta concurrencia.

Parámetros de solicitud

Utilice los métodos encadenados de RecognitionParam para configurar el modelo, la frecuencia de muestreo, el formato de audio y otros parámetros. Pase el objeto de parámetros configurado al método call/streamCall de la clase Recognition.

RecognitionParam param = RecognitionParam.builder()
  .model("fun-asr-realtime")
  .format("pcm")
  .sampleRate(16000)
  //.parameter("language_hints", new String[]{"zh"})
  .build();
ParámetroTipoObligatorioDescripción
modelStringSíEl nombre del modelo.
sampleRateIntegerSíLa tasa de muestreo, en Hz.

Valores válidos: Los modelos de 8 kHz solo admiten 8000 Hz; otros modelos admiten cualquier frecuencia de muestreo.

formatStringSíEl formato de audio.

Valores válidos:

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

Importanteopus/speex: Debe usar encapsulación Ogg.

wav: Debe usar codificación PCM.

amr: Solo se admite el tipo AMR-NB.

vocabularyIdStringNoEl ID de una lista de palabras calientes precompilada.

Genere este ID con antelación llamando a la API de creación de lista de palabras clave. Pase el ID durante el reconocimiento para usar las palabras clave de la lista.

Adecuado para escenarios donde el vocabulario es conocido y relativamente estable, y donde necesita reutilizar la misma lista de palabras en distintas solicitudes.

Para obtener detalles sobre el uso, consulte Palabras clave precompiladas.

max_sentence_silenceIntegerNoEl umbral de silencio del VAD para la segmentación, en ms. Cuando el silencio posterior a un segmento de voz supera este umbral, el sistema determina que la oración ha finalizado.

Valor predeterminado: 1300.

Valores válidos: [200, 6000].

Configure max_sentence_silence mediante el método parameter o el método parameters de la instancia RecognitionParam:

RecognitionParam param = RecognitionParam.builder()
 .model("fun-asr-realtime")
 .format("pcm")
 .sampleRate(16000)
 .parameter("max_sentence_silence", 800)
 .build();
RecognitionParam param = RecognitionParam.builder()
 .model("fun-asr-realtime")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("max_sentence_silence", 800))
 .build();
multi_threshold_mode_enabledbooleanNo

Si se debe habilitar el modo de umbral múltiple. Cuando está habilitado, esto evita que los segmentos VAD sean demasiado largos.

Valor predeterminado: false.

Configure multi_threshold_mode_enabled mediante el método parameter o el método parameters de la instancia RecognitionParam:

RecognitionParam param = RecognitionParam.builder()
 .model("fun-asr-realtime")
 .format("pcm")
 .sampleRate(16000)
 .parameter("multi_threshold_mode_enabled", true)
 .build();
RecognitionParam param = RecognitionParam.builder()
 .model("fun-asr-realtime")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("multi_threshold_mode_enabled", true))
 .build();
punctuation_prediction_enabledbooleanNoDefine si se agrega puntuación automáticamente a los resultados del reconocimiento:
  • true (predeterminado): sí. Este valor no se puede cambiar.

Configure punctuation_prediction_enabled mediante el método parameter o el método parameters de la instancia RecognitionParam:

RecognitionParam param = RecognitionParam.builder()
 .model("fun-asr-realtime")
 .format("pcm")
 .sampleRate(16000)
 .parameter("punctuation_prediction_enabled", false)
 .build();
RecognitionParam param = RecognitionParam.builder()
 .model("fun-asr-realtime")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("punctuation_prediction_enabled", false))
 .build();
heartbeatbooleanNoSi se habilitan los paquetes de latido.

Valor predeterminado: false.

  • true: Mantiene activa la conexión con el servidor incluso cuando se envía audio silencioso de forma continua.
  • false (predeterminado): Incluso cuando se envía audio silencioso de forma continua, la conexión expira y se cierra después de un período de tiempo.

El audio silencioso se refiere al contenido en un archivo de audio o flujo de datos que no contiene señal de sonido. Puede generar audio silencioso de varias maneras, como utilizando software de edición de audio como Audacity o Adobe Audition, o utilizando una herramienta de línea de comandos como FFmpeg.

NotaPara usar este campo, la versión del SDK debe ser 2.19.1 o posterior.

Configure heartbeat mediante el método parameter o el método parameters de la instancia RecognitionParam:

RecognitionParam param = RecognitionParam.builder()
 .model("fun-asr-realtime")
 .format("pcm")
 .sampleRate(16000)
 .parameter("heartbeat", true)
 .build();
RecognitionParam param = RecognitionParam.builder()
 .model("fun-asr-realtime")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("heartbeat", true))
 .build();
language_hintsString[]NoEl idioma del audio a reconocer. No hay valor predeterminado; si no se establece, el modelo detecta el idioma automáticamente.

Puede establecer 1 valor. Si establece más, solo el primer valor surte efecto.

Haga clic para ver los códigos de idioma admitidos

  • fun-asr-realtime:

    • zh: Chino
    • en: Inglés
    • ja: Japonés
    • ko: Coreano
    • vi: Vietnamita
    • th: Tailandés
    • id: Indonesio
    • ms: Malayo
    • tl: Filipino
    • hi: Hindi
    • ar: Árabe
    • fr: Francés
    • de: Alemán
    • es: Español
    • pt: Portugués
    • ru: Ruso
    • it: Italiano
    • nl: Neerlandés
    • sv: Sueco
    • da: Danés
    • fi: Finés
    • no: Noruego
    • el: Griego
    • pl: Polaco
    • cs: Checo
    • hu: Húngaro
    • ro: Rumano
    • bg: Búlgaro
    • hr: Croata
    • sk: Eslovaco
  • fun-asr-realtime-2026-02-28:

    • zh: Chino
    • en: Inglés
    • ja: Japonés
  • fun-asr-flash-8k-realtime, fun-asr-flash-8k-realtime-2026-01-28:

    • zh: Chino

Configure language_hints mediante el método parameter o el método parameters de la instancia RecognitionParam:

RecognitionParam param = RecognitionParam.builder()
 .model("fun-asr-realtime")
 .format("pcm")
 .sampleRate(16000)
 .parameter("language_hints", new String[]{"zh"})
 .build();
RecognitionParam param = RecognitionParam.builder()
 .model("fun-asr-realtime")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("language_hints", new String[]{"zh"}))
 .build();
speech_noise_thresholdfloatNoEl umbral para distinguir el habla del ruido, utilizado para ajustar la sensibilidad de la Detección de Actividad de Voz (VAD).

Valores válidos: [-1.0, 1.0].

Descripciones de valores:

  • Cuanto más cerca esté el valor de -1: El umbral de ruido disminuye, por lo que es más probable que el ruido se reconozca como habla, lo que puede causar que se transcriba más ruido.
  • Cuanto más cerca esté el valor de +1: El umbral de ruido aumenta, por lo que es más probable que el habla se juzgue erróneamente como ruido, lo que puede causar que se filtre parte del habla.

Este es un parámetro de configuración avanzada. Ajustarlo puede afectar significativamente los resultados del reconocimiento. Recomendaciones:

  • Pruebe y verifique exhaustivamente los resultados antes de ajustar.
  • Ajuste en incrementos pequeños según el entorno de audio real (se recomienda un paso de 0.1).

Configure speech_noise_threshold mediante el método parameter o el método parameters de la instancia RecognitionParam:

RecognitionParam param = RecognitionParam.builder()
 .model("fun-asr-realtime")
 .format("pcm")
 .sampleRate(16000)
 .parameter("speech_noise_threshold", -0.5)
 .build();
RecognitionParam param = RecognitionParam.builder()
 .model("fun-asr-realtime")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("speech_noise_threshold", -0.5))
 .build();
special_word_filterStringNoEspecifica las palabras sensibles que se deben procesar durante el reconocimiento de voz y permite configurar diferentes métodos de procesamiento para cada una. Para más detalles, consulte Filtrado de palabras sensibles.

Configure special_word_filter mediante el método parameter o el método parameters de la instancia 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("fun-asr-realtime")
 .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("fun-asr-realtime")
 .format("pcm")
 .sampleRate(16000)
 .parameters(Collections.singletonMap("special_word_filter", root.toString()))
 .build();
inputMap<String, Object>NoObjeto de entrada que pasa el contexto de la conversación. El contexto ayuda al reconocimiento y mejora la precisión de términos específicos. Para su uso, consulte Inicio rápido.

ImportanteSolo los modelos fun-asr-realtime admiten el parámetro de contexto.

El Map debe contener una clave context cuyo valor sea una matriz de mensajes de tipo List<Map<String, Object>>. Cada mensaje contiene los siguientes campos:

  • role (String, obligatorio): el rol del mensaje. user indica el resultado del reconocimiento del habla del usuario de rondas anteriores o una lista de palabras específica del dominio. assistant indica las respuestas del modelo de lenguaje grande de rondas anteriores.
  • content (List<Map>, obligatorio): la lista de contenido del mensaje. Cada elemento contiene type (String; establecido en input_text cuando el rol es user, y en text cuando el rol es assistant) y text (String, el contenido de texto).

ImportanteLímites: los mensajes de contexto de los tipos input_text y text están limitados a 5 cada uno; se conservan los 5 más recientes cuando se supera el límite. La longitud total del texto por ronda de contexto no puede exceder los 400 caracteres, y cualquier exceso se trunca desde el final.

ImportanteCuando pasa contexto, los mensajes en context deben seguir un orden específico: los mensajes de contexto deben organizarse por ronda de conversación, y dentro de cada ronda el mensaje user (tipo input_text) debe preceder al mensaje assistant correspondiente (tipo text).

NotaPara usar este campo, la versión del SDK debe ser 2.22.23 o posterior.

Configure input mediante el método input de la instancia 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("fun-asr-realtime")
       .format("pcm")
       .sampleRate(16000)
       .input(input)
       .build();
apiKeyStringNoSu clave API.

Interfaces clave

La clase Recognition

Importe Recognition con import com.alibaba.dashscope.audio.asr.recognition.Recognition;. Sus interfaces principales son las siguientes:

Interfaz/MétodoParámetroValor de retornoDescripción
public void call(RecognitionParam param, final ResultCallback<RecognitionResult> callback)
  • param: Parámetros de solicitud
  • callback: La interfaz de callback (ResultCallback)
NoneReconocimiento en tiempo real por streaming basado en callbacks. Este método no bloquea el hilo actual.
public String call(RecognitionParam param, File file)
  • param: Parámetros de solicitud
  • file: El archivo de audio a reconocer.
El resultado del reconocimiento.Reconocimiento no streaming de un archivo local. Este método bloquea el hilo actual hasta que se lee todo el archivo de audio. El archivo debe ser legible.
public Flowable<RecognitionResult> streamCall(RecognitionParam param, Flowable<ByteBuffer> audioFrame)
  • param: Parámetros de solicitud
  • audioFrame: Una instancia de Flowable<ByteBuffer>.
Flowable<RecognitionResult>Reconocimiento en tiempo real por streaming basado en Flowable.
public void sendAudioFrame(ByteBuffer audioFrame)
  • audioFrame: Un flujo de audio binario de tipo ByteBuffer.
NoneEnvía audio. Mantenga cada fragmento de audio enviado dentro de un tamaño razonable. Se recomienda que un fragmento contenga aproximadamente 100 ms de audio y tenga un tamaño de 1 KB a 16 KB.

Los resultados del reconocimiento se entregan a través del método onEvent de la interfaz de callback (ResultCallback).

public void stop()
NoneNoneDetiene el reconocimiento en tiempo real.

Este método bloquea el hilo actual hasta que se llama a onComplete o onError del callback ResultCallback.

boolean getDuplexApi().close(int code, String reason)
code: El código de cierre de WebSocket.

reason: El motivo del cierre.

Para obtener orientación sobre cómo configurar estos dos parámetros, consulte El protocolo WebSocket.

trueDespués de que finalice una tarea, cierre siempre la conexión WebSocket, haya ocurrido o no una excepción, para evitar fugas de conexiones. Para reutilizar conexiones y mejorar la eficiencia, consulte Mejores prácticas de alta concurrencia.
public String getLastRequestId()
NonerequestIdObtiene el requestId de la tarea actual. Disponible después de que se inicia una nueva tarea con call o streamingCall.

NotaEste método está disponible solo en la versión 2.18.0 del SDK y posteriores.

public long getFirstPackageDelay()
NoneLa latencia del primer paquete.Obtiene la latencia del primer paquete, es decir, el retraso desde el envío del primer paquete de audio hasta la recepción del primer resultado de reconocimiento. Úselo después de que se complete la tarea.

NotaEste método está disponible solo en la versión 2.18.0 del SDK y posteriores.

public long getLastPackageDelay()
NoneLa latencia del último paquete.Obtiene la latencia del último paquete, es decir, el tiempo transcurrido desde el envío del comando stop hasta la recepción del resultado final del reconocimiento. Úselo después de que se complete la tarea.

NotaEste método está disponible solo en la versión 2.18.0 del SDK y posteriores.

La interfaz de callback (ResultCallback)

Durante las llamadas de streaming bidireccionales, el servidor devuelve información clave del proceso y datos al cliente a través de callbacks. Implemente los métodos de callback para manejar la información o los datos devueltos por el servidor.

Implemente los métodos de callback extendiendo la clase abstracta ResultCallback. Cuando extienda esta clase, puede establecer el tipo genérico en RecognitionResult. RecognitionResult encapsula la estructura de datos devuelta por el servidor.

Dado que Java admite la reutilización de conexiones, no hay onClose ni onOpen.

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());
    }
};
Interfaz/MétodoParámetroValor de retornoDescripción
public void onEvent(RecognitionResult result)
result: Resultado de reconocimiento en tiempo real (RecognitionResult)NoneSe llama cuando el servidor envía una respuesta.
public void onComplete()
NoneNoneSe llama después de que se completa la tarea.
public void onError(Exception e)
e: La información de la excepción.NoneSe llama cuando ocurre una excepción.

Respuesta

Resultado de reconocimiento en tiempo real (RecognitionResult)

RecognitionResult representa el resultado de un único reconocimiento en tiempo real.

Interfaz/MétodoParámetroValor de retornoDescripción
public String getRequestId()
NonerequestIdObtiene el requestId.
public boolean isSentenceEnd()
NoneSi se ha formado una oración completa, es decir, si se detectó un límite de oración.Determina si la oración dada ha terminado.
public Sentence getSentence()
NoneInformación de la oración (Sentence)Obtiene la información de la oración, incluidas las marcas de tiempo y el texto.

Información de la oración (Sentence)

Interfaz/MétodoParámetroValor de retornoDescripción
public Long getBeginTime()
NoneLa hora de inicio de la oración, en ms.Devuelve la hora de inicio de la oración.
public Long getEndTime()
NoneLa hora de finalización de la oración, en ms.Devuelve la hora de finalización de la oración.
public String getText()
NoneEl texto reconocido.Devuelve el texto reconocido.
public List<Word> getWords()
NoneUna lista de objetos de Información de marcas de tiempo a nivel de palabra (Word).Devuelve información de marcas de tiempo a nivel de palabra.

Información de marcas de tiempo a nivel de palabra (Word)

Interfaz/MétodoParámetroValor de retornoDescripción
public long getBeginTime()
NoneEl tiempo de inicio de la palabra, en ms.Devuelve el tiempo de inicio de la palabra.
public long getEndTime()
NoneEl tiempo de finalización de la palabra, en ms.Devuelve el tiempo de finalización de la palabra.
public String getText()
NoneLa palabra.Devuelve la palabra reconocida.
public String getPunctuation()
NoneLa puntuación.Devuelve la puntuación.

Códigos de error

Si encuentra errores, consulte Códigos de error para solucionar problemas.

Si el problema persiste, únase a la comunidad de desarrolladores que aparece en el repositorio de muestras del SDK de voz para informar su problema y proporcionar el ID de solicitud para una investigación más detallada.

FAQ

Funcionalidades

P: ¿Cómo mantengo activa la conexión con el servidor durante largos períodos de silencio?

Establezca el parámetro de solicitud heartbeat en true y continúe enviando audio silencioso al servidor.

El audio silencioso es aquel que no contiene señal de sonido en el archivo o flujo de datos. Puede generar audio silencioso de varias maneras, por ejemplo, utilizando software de edición de audio como Audacity o Adobe Audition, o una herramienta de línea de comandos como FFmpeg.

P: ¿Cómo convierto el audio a un formato compatible?

Utilice la herramienta FFmpeg. Para más información sobre su uso, consulte el sitio web oficial de 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: ¿Cómo reconozco un archivo local (una grabación)?

Hay dos formas de reconocer un archivo local:

  • Pase la ruta del archivo local directamente: este enfoque devuelve el resultado completo del reconocimiento solo después de que finaliza el reconocimiento, por lo que no es adecuado para escenarios que necesitan retroalimentación inmediata.

    Consulte Llamada síncrona y pase la ruta del archivo al método call de la clase Recognition para reconocer la grabación directamente.

  • Convierta el archivo local en un flujo binario para el reconocimiento: este enfoque reconoce el archivo y transmite los resultados al mismo tiempo, lo cual es adecuado para escenarios que requieren retroalimentación inmediata.

    • Consulte Llamada de streaming bidireccional: basada en callbacks, y envíe el flujo binario al servidor para su reconocimiento mediante el método sendAudioFrame de la clase Recognition.
    • Consulte Llamada de streaming bidireccional: basada en Flowable, y envíe el flujo binario al servidor para su reconocimiento mediante el método streamCall de la clase Recognition.

Solución de problemas

P: ¿Por qué no se puede reconocer el habla (sin resultado de reconocimiento)?

  1. Verifique que el formato de audio (format) y la frecuencia de muestreo (sampleRate/sample_rate) en los parámetros de solicitud sean correctos y cumplan con las restricciones de parámetros. Los errores comunes incluyen:

    • El archivo de audio tiene extensión .wav pero en realidad está en formato MP3, mientras que el parámetro de solicitud format está configurado en mp3 (configuración de parámetro incorrecta).
    • La frecuencia de muestreo del audio es de 3600 Hz, pero el parámetro de solicitud sampleRate/sample_rate está configurado en 48000 (configuración de parámetro incorrecta).

    Utilice la herramienta ffprobe para obtener el contenedor, códec, frecuencia de muestreo, canales y otra información sobre el audio:

    ffprobe -v error -show_entries format=format_name -show_entries stream=codec_name,sample_rate,channels -of default=noprint_wrappers=1 input.xxx
    
  2. Verifique que el idioma configurado en language_hints coincida con el idioma real del audio.

    Por ejemplo, el audio está realmente en chino, pero language_hints está configurado como en (inglés).

  3. Si none de las verificaciones anteriores revela un problema, configure palabras clave personalizadas para mejorar el reconocimiento de términos específicos.