Tous les produits
Search
Centre de documentation

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

Dernière mise à jour :Sep 07, 2026

Cette rubrique détaille les paramètres et les interfaces du SDK Java pour la reconnaissance vocale en temps réel Qwen-Audio-3.0-ASR-Flash-Streaming/Fun-ASR-Realtime.

ImportantAlibaba Cloud Model Studio a publié des domaines spécifiques aux espaces de travail pour les régions Chine (Pékin) et Singapour. Ces nouveaux domaines dédiés offrent des performances supérieures et une stabilité accrue pour les requêtes d'inférence. Nous vous recommandons de migrer vers ces nouveaux domaines :

  • Chine (Pékin) : passez de dashscope.aliyuncs.com à {WorkspaceId}.cn-beijing.maas.aliyuncs.com
  • Singapour : passez de dashscope-intl.aliyuncs.com à {WorkspaceId}.ap-southeast-1.maas.aliyuncs.com

Remplacez {WorkspaceId} par votre véritable ID d'espace de travail. Les domaines existants restent pleinement fonctionnels.

Guide d'utilisation : Pour une présentation des modèles et des conseils sur leur sélection, consultez la rubrique Reconnaissance vocale.

Prérequis

Le service est activé et vous avez obtenu une clé API. Afin de prévenir les risques de sécurité liés aux fuites de code, nous vous conseillons de configurer la clé API comme variable d'environnement plutôt que de l'intégrer en dur dans votre code.

Démarrage rapide

La classe Recognition fournit des interfaces pour les appels synchrones et les appels en streaming bidirectionnel. Choisissez l'approche adaptée à vos besoins :

  • Appel synchrone : reconnaît un fichier local et retourne le résultat complet en une seule fois. Cette méthode convient particulièrement au traitement d'enregistrements audio préexistants.
  • Appel en streaming bidirectionnel : reconnaît directement un flux audio et retourne les résultats en temps réel. Le flux audio peut provenir d'un périphérique externe, tel qu'un microphone, ou être lu depuis un fichier local. Recommandé pour les scénarios nécessitant un retour immédiat.

Appel synchrone

Soumettez une tâche unique de reconnaissance vocale en temps réel et obtenez le résultat de manière synchrone en transmettant un fichier local. L'appel bloque l'exécution jusqu'à ce que le résultat soit retourné.

Instanciez la classe Recognition, puis appelez la méthode call pour lier les paramètres de requête et le fichier à reconnaître. La méthode effectue la reconnaissance et retourne le résultat final.

Cliquez pour afficher l'exemple complet

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);
    }
}

Appel en streaming bidirectionnel : basé sur les callbacks

Soumettez une tâche unique de reconnaissance vocale en temps réel et recevez les résultats en continu grâce à l'implémentation d'une interface de callback.

  1. Lancez la reconnaissance vocale en streaming

    Instanciez la classe Recognition, puis appelez la méthode call pour lier les paramètres de requête et l'interface de callback (ResultCallback), afin de démarrer la reconnaissance vocale en streaming.

  2. Transmettez le flux audio

    Appelez la méthode sendAudioFrame de la classe Recognition dans une boucle pour envoyer le flux audio binaire au serveur par segments. Lisez l'audio depuis un fichier local ou un périphérique tel qu'un microphone.

    Pendant l'envoi des données audio, le serveur retourne les résultats de reconnaissance au client en temps réel via la méthode onEvent de l'interface de callback (ResultCallback).

    Envoyez environ 100 ms d'audio par trame, en maintenant chaque charge utile entre 1 Ko et 16 Ko.

  3. Terminez le processus

    Appelez la méthode stop de la classe Recognition pour arrêter la reconnaissance vocale.

    Cette méthode bloque le thread actuel jusqu'à ce que le callback onComplete ou onError de l'interface de callback (ResultCallback) soit déclenché, moment auquel le thread est libéré.

Cliquez pour afficher l'exemple complet

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());
    }
}

Appel en streaming bidirectionnel : basé sur Flowable

Soumettez une tâche unique de reconnaissance vocale en temps réel et recevez les résultats en continu grâce à l'implémentation d'un workflow (Flowable).

Flowable est un framework open source de gestion des workflows et des processus métier, publié sous licence Apache 2.0. Pour savoir comment utiliser Flowable, consultez les détails de l'API Flowable.

Cliquez pour afficher l'exemple complet

Appelez directement la méthode streamCall de la classe Recognition pour lancer la reconnaissance.

La méthode streamCall retourne une instance Flowable<RecognitionResult>. Utilisez les méthodes de l'instance Flowable, telles que blockingForEach ou subscribe, pour traiter les résultats de reconnaissance. Chaque résultat est encapsulé dans un objet RecognitionResult.

La méthode streamCall prend deux paramètres :

  • Une instance RecognitionParam (paramètres de requête) : permet de définir le modèle, la fréquence d'échantillonnage, le format audio et d'autres paramètres nécessaires à la reconnaissance vocale.
  • Une instance Flowable<ByteBuffer> : créez une instance de type Flowable<ByteBuffer> et implémentez-y la logique d'analyse du flux audio.
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);
    }
}

Appels à haute concurrence

Le SDK Java DashScope utilise le pool de connexions d'OkHttp3 pour réduire la surcharge liée à l'établissement répété de connexions. Pour plus de détails, consultez la rubrique Optimiser la reconnaissance vocale en temps réel Paraformer pour une concurrence élevée.

Paramètres de requête

Utilisez les méthodes chaînées de RecognitionParam pour configurer le modèle, la fréquence d'échantillonnage, le format audio et d'autres paramètres. Transmettez l'objet de paramètres configuré à la méthode call/streamCall de la classe Recognition.

Cliquez pour afficher l'exemple

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

model

String

Oui

Nom du modèle. Les séries de modèles Qwen-Audio-3.0-ASR-Flash-Streaming et Fun-ASR-Realtime sont prises en charge. Pour plus de détails, consultez Modèles et régions pris en charge.

sampleRate

Integer

Oui

Fréquence d'échantillonnage, en Hz.

Valeurs valides : les modèles 8 kHz ne prennent en charge que 8000 Hz ; les autres modèles acceptent n'importe quelle fréquence d'échantillonnage.

format

String

Oui

Format audio.

Valeurs valides :

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

Importantopus/speex : doit utiliser l'encapsulation Ogg.

wav : doit utiliser l'encodage PCM.

amr : seul le type AMR-NB est pris en charge.

vocabularyId

String

Non

ID d'une liste de mots clés précompilée.

Générez cet ID au préalable en appelant l'API de création de liste de mots clés. Transmettez l'ID lors de la reconnaissance pour utiliser les mots clés de la liste.

Convient aux scénarios où le vocabulaire est connu et relativement stable, et où vous devez réutiliser la même liste de mots entre les requêtes.

Pour plus de détails sur l'utilisation, consultez Mots clés précompilés.

vocabulary

Map<String, Integer>

Non

Mots clés instantanés.

Transmis sous forme de paires clé-valeur, où la clé est le texte du mot clé (string) et la valeur est le poids du mot clé (integer). Aucune liste de mots clés ne doit être créée au préalable. Le poids varie de [1, 5] ou est fixé à 50 : une valeur dans [1, 5] augmente la probabilité que le modèle produise le mot à mesure que la valeur croît ; une valeur de 50 désigne un super mot clé, ce qui améliore considérablement le rappel, mais le nombre de super mots clés ne peut pas dépasser 50.

Convient à l'optimisation temporaire des mots clés au niveau de la session.

Lorsqu'ils sont configurés conjointement avec des mots clés précompilés, seuls les mots clés instantanés prennent effet. Pour plus de détails sur l'utilisation, consultez Mots clés instantanés.

ImportantSeul qwen-audio-3.0-asr-flash-streaming prend en charge les mots clés instantanés.

RemarqueDéfinissez vocabulary via la méthode parameter ou la méthode parameters de l'instance 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

Non

Indique s'il faut activer la segmentation sémantique.

Valeur par défaut : false.

  • true : active la segmentation sémantique et désactive la segmentation VAD.
  • false (par défaut) : active la segmentation VAD et désactive la segmentation sémantique.

La segmentation sémantique est plus précise et mieux adaptée aux scénarios de transcription de réunions. La segmentation VAD (Voice Activity Detection) offre une latence plus faible et convient mieux aux scénarios interactifs.

RemarqueDéfinissez semantic_punctuation_enabled via la méthode parameter ou la méthode parameters de l'instance 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

Non

Seuil de silence VAD pour la segmentation, en ms. Lorsque le silence suivant un segment de parole dépasse ce seuil, le système considère que la phrase est terminée. Lorsque semantic_punctuation_enabled est défini sur true, ce paramètre n'est pas utilisé comme critère pour retourner sentence_end, mais une valeur trop basse peut affecter les performances de reconnaissance.

Valeur par défaut : 1300.

Valeurs valides : [200, 6000].

RemarqueDéfinissez max_sentence_silence via la méthode parameter ou la méthode parameters de l'instance 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

Non

ImportantPrend effet uniquement lorsque semantic_punctuation_enabled est false.

Indique s'il faut activer le mode multi-seuil. Lorsqu'il est activé, ce mode empêche les segments VAD de devenir trop longs.

Valeur par défaut : false.

RemarqueDéfinissez multi_threshold_mode_enabled via la méthode parameter ou la méthode parameters de l'instance 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

Non

Définit s'il faut ajouter automatiquement la ponctuation aux résultats de reconnaissance :

  • true (par défaut) : oui. Cette valeur ne peut pas être modifiée.

RemarqueDéfinissez punctuation_prediction_enabled via la méthode parameter ou la méthode parameters de l'instance 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

Non

Indique s'il faut activer les paquets de heartbeat.

Valeur par défaut : false.

  • true : maintient la connexion au serveur active même lorsque de l'audio silencieux est envoyé en continu.
  • false (par défaut) : la connexion est interrompue pour cause de timeout après 60 secondes, même si de l'audio silencieux est envoyé en continu.

L'audio silencieux désigne le contenu d'un fichier audio ou d'un flux de données ne contenant aucun signal sonore. Vous pouvez générer de l'audio silencieux de plusieurs façons, par exemple en utilisant un logiciel d'édition audio comme Audacity ou Adobe Audition, ou un outil en ligne de commande comme FFmpeg.

RemarquePour utiliser ce champ, la version du SDK doit être 2.19.1 ou ultérieure.

Définissez heartbeat via la méthode parameter ou la méthode parameters de l'instance 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[]

Non

Langue de l'audio à reconnaître. Il n'y a pas de valeur par défaut ; si ce paramètre n'est pas défini, le modèle détecte automatiquement la langue.

Pour la série de modèles Qwen-Audio-3.0-ASR-Flash-Streaming, vous pouvez définir jusqu'à 4 valeurs ; si vous en définissez plus de 4, seules les 4 premières prennent effet. Pour la série de modèles Fun-ASR-Realtime, vous ne pouvez définir qu'une seule valeur ; si vous en définissez plusieurs, seule la première prend effet.

Cliquez pour afficher les codes de langue pris en charge

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

    • zh : chinois
    • en : anglais
    • ja : japonais
    • ko : coréen
    • vi : vietnamien
    • th : thaï
    • id : indonésien
    • ms : malais
    • tl : filipino
    • hi : hindi
    • ar : arabe
    • fr : français
    • de : allemand
    • es : espagnol
    • pt : portugais
    • ru : russe
    • it : italien
    • nl : néerlandais
    • sv : suédois
    • da : danois
    • fi : finnois
    • no : norvégien
    • el : grec
    • pl : polonais
    • cs : tchèque
    • hu : hongrois
    • ro : roumain
    • bg : bulgare
    • hr : croate
    • sk : slovaque
  • fun-asr-realtime-2026-02-28 :

    • zh : chinois
    • en : anglais
    • ja : japonais
  • fun-asr-realtime-2025-09-15 :

    • zh : chinois
    • en : anglais
  • fun-asr-flash-8k-realtime, fun-asr-flash-8k-realtime-2026-01-28 :

    • zh : chinois

RemarqueDéfinissez language_hints via la méthode parameter ou la méthode parameters de l'instance 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

Non

Seuil de distinction entre la parole et le bruit, utilisé pour ajuster la sensibilité de la détection d'activité vocale (VAD).

Valeurs valides : [-1.0, 1.0].

Description des valeurs :

  • Plus la valeur se rapproche de -1 : le seuil de bruit diminue, donc le bruit est plus susceptible d'être reconnu comme de la parole, ce qui peut entraîner la transcription de davantage de bruit.
  • Plus la valeur se rapproche de +1 : le seuil de bruit augmente, donc la parole est plus susceptible d'être jugée à tort comme du bruit, ce qui peut filtrer une partie de la parole.

Il s'agit d'un paramètre de configuration avancé. Son ajustement peut affecter considérablement les résultats de reconnaissance. Recommandations :

  • Testez et vérifiez minutieusement les résultats avant tout ajustement.
  • Ajustez par petits incréments en fonction de l'environnement audio réel (un pas de 0,1 est recommandé).

RemarqueDéfinissez speech_noise_threshold via la méthode parameter ou la méthode parameters de l'instance 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

Non

Spécifie les mots sensibles à traiter lors de la reconnaissance vocale et permet de définir différentes méthodes de traitement pour différents mots sensibles. Pour plus de détails, consultez Filtrage des mots sensibles.

RemarqueDéfinissez special_word_filter via la méthode parameter ou la méthode parameters de l'instance 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>

Non

Objet d'entrée qui transmet le contexte de conversation. Le contexte aide à la reconnaissance et améliore la précision de reconnaissance des termes spécifiques. Pour l'utilisation, consultez Démarrage rapide.

ImportantSeuls les modèles qwen-audio-3.0-asr-flash-streaming, fun-asr-realtime et fun-asr-realtime-2025-11-07 prennent en charge le paramètre de contexte.

La Map doit contenir une clé context dont la valeur est un tableau de messages de type List<Map<String, Object>>. Chaque message contient les champs suivants :

  • role (String, obligatoire) : rôle du message. user indique le résultat de reconnaissance de la parole de l'utilisateur des tours précédents ou une liste de mots spécifiques au domaine. assistant indique les réponses du grand modèle linguistique des tours précédents.
  • content (List<Map>, obligatoire) : liste du contenu du message. Chaque élément contient type (String ; défini sur input_text lorsque le rôle est user, et text lorsque le rôle est assistant) et text (String, le contenu textuel).

ImportantLimites : les messages de contexte de type input_text et text sont limités à 5 chacun ; les 5 plus récents sont conservés lorsque la limite est dépassée. La longueur totale du texte par tour de contexte ne peut pas dépasser 400 caractères, et tout excédent est tronqué à partir de la fin.

ImportantLorsque vous transmettez un contexte, les messages dans context doivent suivre un ordre spécifique : les messages de contexte doivent être organisés par tour de conversation, et dans chaque tour, le message user (type input_text) doit précéder le message assistant correspondant (type text).

RemarquePour utiliser ce champ, la version du SDK doit être 2.22.23 ou ultérieure.

Définissez input via la méthode input de l'instance 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

Non

Votre clé API.

Interfaces clés

La classe Recognition

Importez Recognition avec import com.alibaba.dashscope.audio.asr.recognition.Recognition;. Ses interfaces clés sont les suivantes :

Interface/MéthodeParamètreValeur de retourDescription
public void call(RecognitionParam param, final ResultCallback<RecognitionResult> callback)

Aucune

Reconnaissance en temps réel en streaming basée sur les callbacks. Cette méthode ne bloque pas le thread actuel.

public String call(RecognitionParam param, File file)

Résultat de la reconnaissance.

Reconnaissance non streaming d'un fichier local. Cette méthode bloque le thread actuel jusqu'à ce que l'intégralité du fichier audio soit lue. Le fichier doit être lisible.

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

Flowable<RecognitionResult>

Reconnaissance en temps réel en streaming basée sur Flowable.

public void sendAudioFrame(ByteBuffer audioFrame)
  • audioFrame : flux audio binaire de type ByteBuffer.

Aucune

Envoie l'audio. Maintenez chaque segment audio poussé à une taille raisonnable. Un segment recommandé contient environ 100 ms d'audio et a une taille comprise entre 1 Ko et 16 Ko.

Les résultats de reconnaissance sont fournis via la méthode onEvent de l'interface de callback (ResultCallback).

public void stop()

Aucun

Aucune

Arrête la reconnaissance en temps réel.

Cette méthode bloque le thread actuel jusqu'à ce que le callback ResultCallback appelle onComplete ou onError.

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

code : code de fermeture WebSocket.

reason : raison de la fermeture.

Pour des conseils sur la définition de ces deux paramètres, consultez Le protocole WebSocket.

true

Après la fin d'une tâche, fermez toujours la connexion WebSocket, qu'une exception se soit produite ou non, afin d'éviter les fuites de connexion. Pour réutiliser les connexions afin d'améliorer l'efficacité, consultez Optimiser la reconnaissance vocale en temps réel Paraformer pour une concurrence élevée.

public String getLastRequestId()

Aucun

requestId

Obtient le requestId de la tâche actuelle. Disponible après le démarrage d'une nouvelle tâche avec call ou streamingCall.

RemarqueCette méthode n'est disponible que dans la version 2.18.0 et ultérieure du SDK.

public long getFirstPackageDelay()

Aucun

Latence du premier paquet.

Obtient la latence du premier paquet, c'est-à-dire le délai entre l'envoi du premier paquet audio et la réception du premier résultat de reconnaissance. À utiliser une fois la tâche terminée.

RemarqueCette méthode n'est disponible que dans la version 2.18.0 et ultérieure du SDK.

public long getLastPackageDelay()

Aucun

Latence du dernier paquet.

Obtient la latence du dernier paquet, c'est-à-dire le temps écoulé entre l'envoi de la commande stop et la réception du résultat final de reconnaissance. À utiliser une fois la tâche terminée.

RemarqueCette méthode n'est disponible que dans la version 2.18.0 et ultérieure du SDK.

L'interface de callback (ResultCallback)

Lors des appels en streaming bidirectionnel, le serveur retourne des informations clés sur le processus et des données au client via des callbacks. Implémentez les méthodes de callback pour traiter les informations ou les données retournées par le serveur.

Implémentez les méthodes de callback en étendant la classe abstraite ResultCallback. Lorsque vous étendez cette classe, vous pouvez définir le type générique sur RecognitionResult. RecognitionResult encapsule la structure de données retournée par le serveur.

Étant donné que Java prend en charge la réutilisation des connexions, il n'y a pas de onClose ni de onOpen.

Exemple

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éthodeParamètreValeur de retourDescription
public void onEvent(RecognitionResult result)

result : Résultat de reconnaissance en temps réel (RecognitionResult)

Aucune

Appelé lorsque le serveur envoie une réponse.

public void onComplete()

Aucun

Aucune

Appelé après la fin de la tâche.

public void onError(Exception e)

e : informations sur l'exception.

Aucune

Appelé lorsqu'une exception se produit.

Réponse

Résultat de reconnaissance en temps réel (RecognitionResult)

RecognitionResult représente le résultat d'une seule reconnaissance en temps réel.

Interface/MéthodeParamètreValeur de retourDescription
public String getRequestId()

Aucun

requestId

Obtient le requestId.

public boolean isSentenceEnd()

Aucun

Indique si une phrase complète a été formée, c'est-à-dire si une limite de phrase a été détectée.

Détermine si la phrase donnée est terminée.

public Sentence getSentence()

Aucun

Informations sur la phrase (Sentence)

Obtient les informations sur la phrase, y compris les horodatages et le texte.

Informations sur la phrase (Sentence)

Interface/MéthodeParamètreValeur de retourDescription
public Long getBeginTime()

Aucun

Heure de début de la phrase, en ms.

Retourne l'heure de début de la phrase.

public Long getEndTime()

Aucun

Heure de fin de la phrase, en ms.

Retourne l'heure de fin de la phrase.

public String getText()

Aucun

Texte reconnu.

Retourne le texte reconnu.

public List<Word> getWords()

Aucun

Une liste d'objets Informations d'horodatage au niveau du mot (Word).

Retourne les informations d'horodatage au niveau du mot.

Informations d'horodatage au niveau du mot (Word)

Interface/MéthodeParamètreValeur de retourDescription
public long getBeginTime()

Aucun

Heure de début du mot, en ms.

Retourne l'heure de début du mot.

public long getEndTime()

Aucun

Heure de fin du mot, en ms.

Retourne l'heure de fin du mot.

public String getText()

Aucun

Le mot.

Retourne le mot reconnu.

public String getPunctuation()

Aucun

La ponctuation.

Retourne la ponctuation.

Codes d'erreur

Si vous rencontrez des erreurs, consultez la rubrique Codes d'erreur pour le dépannage.

Si le problème persiste, rejoignez la communauté des développeurs pour signaler votre problème et fournir l'ID de requête pour une enquête plus approfondie.

FAQ

Fonctionnalités

Q : Comment maintenir la connexion au serveur active pendant de longues périodes de silence ?

Définissez le paramètre de requête heartbeat sur true et continuez à envoyer de l'audio silencieux au serveur.

L'audio silencieux est un audio qui ne contient aucun signal sonore dans le fichier ou le flux de données. Vous pouvez générer de l'audio silencieux de plusieurs façons, par exemple en utilisant un logiciel d'édition audio tel qu'Audacity ou Adobe Audition, ou un outil en ligne de commande tel que FFmpeg.

Q : Comment convertir l'audio dans un format pris en charge ?

Utilisez l'outil FFmpeg. Pour plus d'informations sur l'utilisation, consultez le site officiel 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

Q : Comment reconnaître un fichier local (un enregistrement) ?

Il existe deux façons de reconnaître un fichier local :

  • Transmettre directement le chemin du fichier local : cette approche ne retourne le résultat complet de la reconnaissance qu'une fois celle-ci terminée, elle ne convient donc pas aux scénarios nécessitant un retour immédiat.

    Consultez la section Appel synchrone, et transmettez le chemin du fichier à la méthode call de la classe Recognition pour reconnaître directement l'enregistrement.

  • Convertir le fichier local en flux binaire pour la reconnaissance : cette approche reconnaît le fichier et diffuse les résultats simultanément, ce qui convient aux scénarios nécessitant un retour immédiat.

Dépannage

Q : Pourquoi la parole n'est-elle pas reconnue (aucun résultat de reconnaissance) ?

  1. Vérifiez que le format audio (format) et la fréquence d'échantillonnage (sampleRate/sample_rate) dans les paramètres de requête sont corrects et respectent les contraintes des paramètres. Les erreurs courantes incluent :

    • Le fichier audio a une extension .wav mais est en réalité au format MP3, tandis que le paramètre de requête format est défini sur mp3 (paramétrage incorrect).
    • La fréquence d'échantillonnage audio est de 3600 Hz, mais le paramètre de requête sampleRate/sample_rate est défini sur 48000 (paramétrage incorrect).

    Utilisez l'outil ffprobe pour obtenir des informations sur le conteneur, le codec, la fréquence d'échantillonnage, les canaux et d'autres détails de l'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. Vérifiez que la langue définie dans language_hints correspond à la langue réelle de l'audio.

    Par exemple, l'audio est en réalité en chinois, mais language_hints est défini sur en (anglais).

  3. Si aucune des vérifications ci-dessus ne révèle de problème, configurez des mots clés personnalisés pour améliorer la reconnaissance de termes spécifiques.