All Products
Search
Document Center

Alibaba Cloud Model Studio:Qwen-Audio-ASR-Message Java SDK

Last Updated:Oct 11, 2026

Topik ini menjelaskan parameter dan antarmuka Java SDK untuk pengenalan ucapan real-time Qwen-Audio-ASR-Message.

Prasyarat

Layanan telah diaktifkan dan Dapatkan Kunci API. Untuk mencegah risiko keamanan akibat kebocoran kode, Konfigurasikan Kunci API sebagai Variabel lingkungan, bukan mengodekannya secara langsung dalam kode Anda.

Mulai cepat

Kelas Recognition menyediakan antarmuka untuk panggilan sinkron maupun panggilan streaming dua arah. Pilih pendekatan yang sesuai dengan kebutuhan Anda:

  • Panggilan sinkron: mengenali file lokal dan mengembalikan hasil lengkap sekaligus. Paling cocok untuk memproses audio yang telah direkam sebelumnya.
  • Panggilan streaming dua arah: mengenali aliran audio secara langsung dan mengembalikan hasil secara real time. Aliran audio dapat berasal dari perangkat eksternal seperti mikrofon atau dibaca dari file lokal. Paling cocok untuk skenario yang memerlukan umpan balik segera.

Panggilan sinkron

Kirim satu tugas pengenalan ucapan real-time dan dapatkan hasil pengenalan secara sinkron dengan memasukkan file lokal. Panggilan ini akan memblokir hingga hasil dikembalikan.

Buat instans Kelas Recognition, lalu panggil metode call untuk mengikat parameter permintaan dan file yang akan dikenali. Metode ini melakukan pengenalan dan mengembalikan hasil akhir.

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) {
        // Berikut adalah konfigurasi untuk wilayah Singapura. Saat memanggil, ganti "{WorkspaceId}" dengan Workspace ID Anda yang sebenarnya. Konfigurasi berbeda tiap wilayah.
        Constants.baseWebsocketApiUrl = "wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference";
        // Buat instans Recognition
        Recognition recognizer = new Recognition();
        // Buat RecognitionParam
        RecognitionParam param =
                RecognitionParam.builder()
                        .model("qwen-audio-3.1-asr-flash-message")
                        // Kunci API berbeda antara wilayah Singapura dan Beijing. Dapatkan Kunci API: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
                        // Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan Kunci API Studio Model Anda: .apiKey("sk-xxx")
                        .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                        .format("wav")
                        .sampleRate(16000)
                        .build();

        try {
            System.out.println("Hasil pengenalan: " + recognizer.call(param, new File("{YOUR_AUDIO_FILE}")));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // Tutup koneksi WebSocket setelah tugas selesai
            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);
    }
}

Panggilan streaming dua arah: berbasis callback

Kirim satu tugas pengenalan ucapan real-time dan alirkan hasil pengenalan real-time dengan mengimplementasikan antarmuka callback.

  1. Mulai pengenalan ucapan streaming

    Buat instans Kelas Recognition, lalu panggil metode call untuk mengikat parameter permintaan dan antarmuka callback (ResultCallback) serta mulai pengenalan ucapan streaming.

  2. Alirkan audio

    Panggil metode sendAudioFrame dari Kelas Recognition dalam loop untuk mengirim aliran audio biner ke server dalam segmen. Baca audio dari file lokal atau perangkat seperti mikrofon.

    Saat data audio dikirim, server mengembalikan hasil pengenalan ke klien secara real time melalui metode onEvent dari antarmuka callback (ResultCallback).

    Kirim sekitar 100 ms audio per frame, dengan ukuran muatan antara 1 KB hingga 16 KB.

  3. Akhiri proses

    Panggil metode stop dari Kelas Recognition untuk mengakhiri pengenalan ucapan.

    Metode ini memblokir thread saat ini hingga callback onComplete atau onError dari antarmuka callback (ResultCallback) dipicu, saat itu thread dilepas.

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 {
        // Berikut adalah konfigurasi untuk wilayah Singapura. Saat memanggil, ganti "{WorkspaceId}" dengan Workspace ID Anda yang sebenarnya. Konfigurasi berbeda tiap wilayah.
        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.1-asr-flash-message")
                // Kunci API berbeda antara wilayah Singapura dan Beijing. Dapatkan Kunci API: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
                // Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan Kunci API Studio Model Anda: .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("Hasil Akhir: " + result.getSentence().getText());
                } else {
                    System.out.println("Hasil Sementara: " + result.getSentence().getText());
                }
            }

            @Override
            public void onComplete() {
                System.out.println("Pengenalan selesai");
            }

            @Override
            public void onError(Exception e) {
                System.out.println("Kesalahan RecognitionCallback: " + e.getMessage());
            }
        };
        try {
            recognizer.call(param, callback);
            // Buat format audio
            AudioFormat audioFormat = new AudioFormat(16000, 16, 1, true, false);
            // Sesuaikan perangkat perekaman default berdasarkan format
            TargetDataLine targetDataLine =
                    AudioSystem.getTargetDataLine(audioFormat);
            targetDataLine.open(audioFormat);
            // Mulai merekam
            targetDataLine.start();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            long start = System.currentTimeMillis();
            // Rekam selama 50 detik dan lakukan transkripsi real-time
            while (System.currentTimeMillis() - start < 50000) {
                int read = targetDataLine.read(buffer.array(), 0, buffer.capacity());
                if (read > 0) {
                    buffer.limit(read);
                    // Kirim data audio yang direkam ke layanan pengenalan streaming
                    recognizer.sendAudioFrame(buffer);
                    buffer = ByteBuffer.allocate(1024);
                    // Laju perekaman dibatasi; tidur sejenak untuk mencegah penggunaan CPU berlebihan
                    Thread.sleep(20);
                }
            }
            recognizer.stop();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // Tutup koneksi WebSocket setelah tugas selesai
            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 {
        // Berikut adalah konfigurasi untuk wilayah Singapura. Saat memanggil, ganti "{WorkspaceId}" dengan Workspace ID Anda yang sebenarnya. Konfigurasi berbeda tiap wilayah.
        Constants.baseWebsocketApiUrl = "wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference";
        // Dalam aplikasi nyata, metode ini hanya perlu dijalankan sekali di awal program; tidak perlu dijalankan berulang kali.
        warmUp();

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

        // tunggu semua tugas selesai
        executorService.awaitTermination(1, TimeUnit.MINUTES);
        System.exit(0);
    }

    public static void warmUp() {
        try {
            // Permintaan GET ringan untuk membuat koneksi
            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) {
            // Atur ulang flag untuk memungkinkan percobaan ulang jika pemanasan gagal
        }
    }
}

class RealtimeRecognitionTask implements Runnable {
    private Path filepath;

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

    @Override
    public void run() {
        RecognitionParam param = RecognitionParam.builder()
                .model("qwen-audio-3.1-asr-flash-message")
                // Kunci API berbeda antara wilayah Singapura dan Beijing. Dapatkan Kunci API: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
                // Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan Kunci API Studio Model Anda: .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()+" "+
                            "[proses " + threadName + "] Hasil Akhir:" + message.getSentence().getText());
                } else {
                    System.out.println(TimeUtils.getTimestamp()+" "+
                            "[proses " + threadName + "] Hasil Sementara: " + message.getSentence().getText());
                }
            }

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

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

        try {
            recognizer.call(param, callback);
            // Ganti path dengan path file audio Anda
            System.out.println(TimeUtils.getTimestamp()+" "+"[" + threadName + "] Input file_path adalah: " + this.filepath);
            // Baca file dan kirim audio per chunk
            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 {
            // Tutup koneksi WebSocket setelah tugas selesai
            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());
    }
}

Panggilan streaming dua arah: berbasis Flowable

Kirim satu tugas pengenalan ucapan real-time dan alirkan hasil pengenalan real-time dengan mengimplementasikan alur kerja (Flowable).

Flowable adalah framework open-source untuk manajemen alur kerja dan proses bisnis, dirilis di bawah lisensi Apache 2.0. Untuk cara menggunakan Flowable, lihat Detail API Flowable.

Panggil metode streamCall dari Kelas Recognition secara langsung untuk memulai pengenalan.

Metode streamCall mengembalikan instans Flowable<RecognitionResult>. Gunakan metode instans Flowable, seperti blockingForEach atau subscribe, untuk memproses hasil pengenalan. Setiap hasil dibungkus dalam RecognitionResult.

Metode streamCall memiliki dua parameter:

  • Instans RecognitionParam (parameter permintaan): gunakan untuk mengatur model, laju sampel, format audio, dan parameter lain yang diperlukan untuk pengenalan ucapan.
  • Instans Flowable<ByteBuffer>: buat instans bertipe Flowable<ByteBuffer> dan implementasikan logika penguraian aliran audio di dalamnya.
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 {
        // Berikut adalah konfigurasi untuk wilayah Singapura. Saat memanggil, ganti "{WorkspaceId}" dengan Workspace ID Anda yang sebenarnya. Konfigurasi berbeda tiap wilayah.
        Constants.baseWebsocketApiUrl = "wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference";
        // Buat Flowable<ByteBuffer>
        Flowable<ByteBuffer> audioSource =
                Flowable.create(
                        emitter -> {
                            new Thread(
                                    () -> {
                                        try {
                                            // Buat format audio
                                            AudioFormat audioFormat = new AudioFormat(16000, 16, 1, true, false);
                                            // Sesuaikan perangkat perekaman default berdasarkan format
                                            TargetDataLine targetDataLine =
                                                    AudioSystem.getTargetDataLine(audioFormat);
                                            targetDataLine.open(audioFormat);
                                            // Mulai merekam
                                            targetDataLine.start();
                                            ByteBuffer buffer = ByteBuffer.allocate(1024);
                                            long start = System.currentTimeMillis();
                                            // Rekam selama 50 detik dan lakukan transkripsi real-time
                                            while (System.currentTimeMillis() - start < 50000) {
                                                int read = targetDataLine.read(buffer.array(), 0, buffer.capacity());
                                                if (read > 0) {
                                                    buffer.limit(read);
                                                    // Kirim data audio yang direkam ke layanan pengenalan streaming
                                                    emitter.onNext(buffer);
                                                    buffer = ByteBuffer.allocate(1024);
                                                    // Laju perekaman dibatasi; tidur sejenak untuk mencegah penggunaan CPU berlebihan
                                                    Thread.sleep(20);
                                                }
                                            }
                                            // Beri tahu bahwa transkripsi telah berakhir
                                            emitter.onComplete();
                                        } catch (Exception e) {
                                            emitter.onError(e);
                                        }
                                    })
                                    .start();
                        },
                        BackpressureStrategy.BUFFER);

        // Buat Recognizer
        Recognition recognizer = new Recognition();
        // Buat RecognitionParam dan masukkan Flowable<ByteBuffer> yang dibuat di atas ke parameter audioFrames
        RecognitionParam param = RecognitionParam.builder()
                .model("qwen-audio-3.1-asr-flash-message")
                // Kunci API berbeda antara wilayah Singapura dan Beijing. Dapatkan Kunci API: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
                // Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan Kunci API Studio Model Anda: .apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .format("pcm")
                .sampleRate(16000)
                .build();

        // Antarmuka panggilan streaming
        recognizer
                .streamCall(param, audioSource)
                .blockingForEach(
                        result -> {
                            // Langganan hasil output
                            if (result.isSentenceEnd()) {
                                System.out.println("Hasil Akhir: " + result.getSentence().getText());
                            } else {
                                System.out.println("Hasil Sementara: " + result.getSentence().getText());
                            }
                        });
        // Tutup koneksi WebSocket setelah tugas selesai
        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);
    }
}

Panggilan konkurensi tinggi

SDK Java DashScope menggunakan pooling koneksi OkHttp3 untuk mengurangi overhead pembentukan koneksi berulang. Untuk detailnya, lihat Praktik terbaik konkurensi tinggi.

Parameter permintaan

Gunakan metode berantai RecognitionParam untuk mengonfigurasi model, laju sampel, format audio, dan parameter lainnya. Masukkan objek parameter yang telah dikonfigurasi ke metode call/streamCall dari Kelas Recognition.

RecognitionParam param = RecognitionParam.builder()
  .model("qwen-audio-3.1-asr-flash-message")
  .format("pcm")
  .sampleRate(16000)
  .build();
ParameterTipeWajibDeskripsi
modelString

Ya

Nama model.
sampleRateInteger

Ya

Laju sampel dalam Hz. Hanya 16000 yang didukung.

formatString

Ya

Format audio.

Nilai valid:

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

Pentingopus/speex: Harus menggunakan enkapsulasi Ogg.

wav: Harus menggunakan encoding PCM.

amr: Hanya tipe AMR-NB yang didukung.

keep_dialectboolean

Tidak

Default: false, yang mentranskripsikan dialek menjadi bahasa Mandarin standar. Tetapkan ke true untuk mempertahankan ungkapan dialek. Tetapkan dengan .parameter("keep_dialect", value).

Parameter ini hanya berlaku pada hasil akhir (sentence_end=true) dan tidak didukung pada hasil sementara (sentence_end=false).

vad_modelString

Tidak

Model VAD: near_meeting_16k (jarak dekat) atau far_field_meeting_16k (jarak jauh, default). Tetapkan dengan .parameter("vad_model", value).

disfluency_removal_enabledboolean

Tidak

Menentukan apakah kata pengisi difilter dan teks keluaran dirapikan. Default: false. Tetapkan ke true untuk mengaktifkan. Tetapkan dengan .parameter("disfluency_removal_enabled", value).

intermediate_result_enabledboolean

Tidak

Menentukan apakah hasil streaming sementara dikembalikan. Default: false. Tetapkan ke true untuk menerimanya. Tetapkan dengan .parameter("intermediate_result_enabled", value).

vocabularyIdString

Tidak

ID daftar kata panas yang telah dikompilasi sebelumnya.

Hasilkan ID ini terlebih dahulu dengan memanggil API pembuatan daftar kata panas. Masukkan ID ini selama pengenalan untuk menggunakan kata-kata panas dalam daftar tersebut.

Cocok untuk skenario di mana kosakata diketahui dan relatif stabil, serta Anda perlu menggunakan kembali daftar kata yang sama di berbagai permintaan.

Untuk detail penggunaan, lihat Kata panas yang telah dikompilasi.

vocabulary

Map<String, Integer>

Tidak

Kata panas instan.

Diberikan sebagai pasangan kunci-nilai, di mana kunci adalah teks kata panas (string) dan nilai adalah bobot kata panas (integer). Tidak perlu membuat daftar kata panas terlebih dahulu. Bobot berkisar antara [1, 5] atau diatur ke 50: nilai dalam [1, 5] membuat model lebih cenderung mengeluarkan kata tersebut seiring peningkatan nilainya; nilai 50 menunjukkan kata panas super, yang sangat meningkatkan recall, tetapi jumlah kata panas super tidak boleh melebihi 50.

Cocok untuk optimasi kata panas sementara pada tingkat sesi.

Jika dikonfigurasi bersama kata panas yang telah dikompilasi, hanya kata panas instan yang berlaku. Untuk detail penggunaan, lihat Kata panas instan.

PentingHanya qwen-audio-3.1-asr-flash-message yang mendukung kata panas instan.

Atur vocabulary melalui metode parameter atau metode parameters dari instans 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.1-asr-flash-message")
        .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.1-asr-flash-message")
        .format("pcm")
        .sampleRate(16000)
        .parameters(parameters)
        .build();
language_hintsString[]

Tidak

Bahasa audio yang akan dikenali. Tidak ada nilai default; jika tidak diatur, model akan mendeteksi bahasa secara otomatis.

Anda dapat menetapkan hingga 4 nilai. Jika lebih, hanya 4 nilai pertama yang berlaku.

Klik untuk melihat kode bahasa yang didukung

  • zh: Chinese
  • en: English
  • ja: Japanese
  • ko: Korean
  • vi: Vietnamese
  • th: Thai
  • id: Indonesian
  • ms: Malay
  • tl: Filipino
  • hi: Hindi
  • ar: Arabic
  • fr: French
  • de: German
  • es: Spanish
  • pt: Portuguese
  • ru: Russian
  • it: Italian
  • nl: Dutch
  • sv: Swedish
  • da: Danish
  • fi: Finnish
  • no: Norwegian
  • el: Greek
  • pl: Polish
  • cs: Czech
  • hu: Hungarian
  • ro: Romanian
  • bg: Bulgarian
  • hr: Croatian
  • sk: Slovak

Atur parameter ini melalui .parameter("language_hints", new String[]{"zh"}) pada RecognitionParam.

Parameter ini hanya berlaku pada hasil akhir (sentence_end=true) dan tidak didukung pada hasil sementara (sentence_end=false).

max_sentence_silenceInteger

Tidak

Ambang keheningan VAD untuk segmentasi, dalam milidetik. Kalimat dianggap selesai jika keheningan setelah ucapan melebihi ambang ini. Default: 800. Rentang valid: [200, 6000].

heartbeatboolean

Tidak

Apakah paket heartbeat diaktifkan.

Nilai default: false.

  • true: Menjaga koneksi ke server tetap aktif meskipun audio diam dikirim terus-menerus.
  • false (default): Meskipun audio diam dikirim terus-menerus, koneksi akan timeout dan ditutup setelah periode waktu tertentu.

Audio diam mengacu pada konten dalam file atau aliran data yang tidak mengandung sinyal suara. Anda dapat menghasilkan audio diam dengan beberapa cara, seperti menggunakan perangkat lunak pengeditan audio seperti Audacity atau Adobe Audition, atau menggunakan alat command-line seperti FFmpeg.

CatatanUntuk menggunakan bidang ini, versi SDK harus 2.19.1 atau lebih baru.

Atur heartbeat melalui metode parameter atau metode parameters dari instans RecognitionParam:

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

Tidak

Ambang batas untuk membedakan ucapan dari kebisingan, digunakan untuk menyesuaikan sensitivitas Voice Activity Detection (VAD).

Nilai valid: [-1.0, 1.0].

Deskripsi nilai:

  • Semakin dekat nilai ke -1: Ambang batas kebisingan menurun, sehingga kebisingan lebih mungkin dikenali sebagai ucapan, yang dapat menyebabkan lebih banyak kebisingan ditranskripsikan.
  • Semakin dekat nilai ke +1: Ambang batas kebisingan meningkat, sehingga ucapan lebih mungkin salah dianggap sebagai kebisingan, yang dapat menyebabkan beberapa ucapan disaring.

Ini adalah parameter konfigurasi lanjutan. Penyesuaian dapat memengaruhi hasil pengenalan secara signifikan. Rekomendasi:

  • Uji dan verifikasi hasil secara menyeluruh sebelum menyesuaikan.
  • Atur dengan kenaikan kecil berdasarkan lingkungan audio aktual (langkah 0.1 direkomendasikan).

Atur speech_noise_threshold melalui metode parameter atau metode parameters dari instans RecognitionParam:

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

Map<String, Object>

Tidak

Objek input yang memasukkan konteks percakapan. Konteks membantu pengenalan dan meningkatkan akurasi pengenalan istilah khusus. Untuk penggunaan, lihat Mulai cepat.

PentingHanya model qwen-audio-3.1-asr-flash-message yang mendukung parameter konteks.

Map harus berisi kunci context yang nilainya adalah array pesan bertipe List<Map<String, Object>>. Setiap pesan berisi bidang berikut:

  • role (String, wajib): peran pesan. user menunjukkan hasil pengenalan ucapan pengguna dari putaran sebelumnya atau daftar kata khusus domain. assistant menunjukkan balasan model bahasa besar dari putaran sebelumnya.
  • content (List<Map>, wajib): daftar konten pesan. Setiap elemen berisi type (String; diatur ke input_text ketika role adalah user, dan text ketika role adalah assistant) dan text (String, konten teks).

PentingBatasan: pesan konteks bertipe input_text dan text masing-masing dibatasi hingga 5; 5 pesan terbaru dipertahankan ketika batas terlampaui. Panjang total teks per putaran konteks tidak boleh melebihi 400 karakter, dan kelebihannya dipotong dari akhir.

PentingKetika Anda memasukkan konteks, pesan dalam context harus mengikuti urutan tertentu: pesan konteks harus diatur berdasarkan putaran percakapan, dan dalam setiap putaran pesan user (input_text) harus mendahului pesan assistant (text) yang sesuai.

CatatanUntuk menggunakan bidang ini, versi SDK harus 2.22.23 atau lebih baru.

Atur input melalui metode input dari instans RecognitionParam:

// 1. Bangun struktur input
      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. Masukkan melalui metode input
      RecognitionParam param = RecognitionParam.builder()
       .model("qwen-audio-3.1-asr-flash-message")
       .format("pcm")
       .sampleRate(16000)
       .input(input)
       .build();
apiKeyString

Tidak

Kunci API Anda.

Antarmuka utama

Kelas Recognition

Impor Recognition dengan import com.alibaba.dashscope.audio.asr.recognition.Recognition;. Antarmuka utamanya sebagai berikut:

Antarmuka/MetodeParameterNilai kembaliDeskripsi
public void call(RecognitionParam param, final ResultCallback<RecognitionResult> callback)
  • param: Parameter permintaan
  • callback: Antarmuka callback (ResultCallback)

Tidak ada

Pengenalan real-time streaming berbasis callback. Metode ini tidak memblokir thread saat ini.

public String call(RecognitionParam param, File file)
  • param: Parameter permintaan
  • file: File audio yang akan dikenali.

Hasil pengenalan.

Pengenalan non-streaming file lokal. Metode ini memblokir thread saat ini hingga seluruh file audio dibaca. File harus dapat dibaca.

public Flowable<RecognitionResult> streamCall(RecognitionParam param, Flowable<ByteBuffer> audioFrame)
  • param: Parameter permintaan
  • audioFrame: Instans Flowable<ByteBuffer>.

Flowable<RecognitionResult>

Pengenalan real-time streaming berbasis Flowable.

public void sendAudioFrame(ByteBuffer audioFrame)
  • audioFrame: Aliran audio biner bertipe ByteBuffer.

Tidak ada

Mengirim audio. Pertahankan ukuran setiap chunk audio yang dikirim dalam batas wajar. Ukuran chunk yang direkomendasikan berisi sekitar 100 ms audio dan berukuran 1 KB hingga 16 KB.

Hasil pengenalan dikirim melalui metode onEvent dari Antarmuka callback (ResultCallback).

public void stop()

Tidak ada

Tidak ada

Menghentikan pengenalan real-time.

Metode ini memblokir thread saat ini hingga callback ResultCallback memanggil onComplete atau onError.

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

code: Kode penutupan WebSocket.

reason: Alasan penutupan.

Untuk panduan mengatur dua parameter ini, lihat Protokol WebSocket.

true

Setelah tugas berakhir, selalu tutup koneksi WebSocket, baik terjadi kesalahan maupun tidak, untuk menghindari kebocoran koneksi. Untuk menggunakan kembali koneksi demi efisiensi yang lebih baik, lihat Optimalkan pengenalan ucapan real-time Paraformer untuk konkurensi tinggi.

public String getLastRequestId()

Tidak ada

requestId

Mendapatkan requestId tugas saat ini. Tersedia setelah tugas baru dimulai dengan call atau streamingCall.

CatatanMetode ini tersedia hanya di versi SDK 2.18.0 dan lebih baru.

public long getFirstPackageDelay()

Tidak ada

Latensi paket pertama.

Mendapatkan latensi paket pertama, yaitu penundaan dari pengiriman paket audio pertama hingga menerima hasil pengenalan pertama. Gunakan setelah tugas selesai.

CatatanMetode ini tersedia hanya di versi SDK 2.18.0 dan lebih baru.

public long getLastPackageDelay()

Tidak ada

Latensi paket terakhir.

Mendapatkan latensi paket terakhir, yaitu waktu dari pengiriman perintah stop hingga menerima hasil pengenalan akhir. Gunakan setelah tugas selesai.

CatatanMetode ini tersedia hanya di versi SDK 2.18.0 dan lebih baru.

Antarmuka callback (ResultCallback)

Selama panggilan streaming dua arah, server mengembalikan informasi dan data proses penting ke klien melalui callback. Implementasikan metode callback untuk menangani informasi atau data yang dikembalikan oleh server.

Implementasikan metode callback dengan memperluas kelas abstrak ResultCallback. Saat memperluas kelas ini, Anda dapat mengatur tipe generik ke RecognitionResult. RecognitionResult membungkus struktur data yang dikembalikan oleh server.

Karena Java mendukung penggunaan kembali koneksi, tidak ada onClose atau onOpen.

ResultCallback<RecognitionResult> callback = new ResultCallback<RecognitionResult>() {
    @Override
    public void onEvent(RecognitionResult result) {
        System.out.println("RequestId: " + result.getRequestId());
        // Tambahkan logika Anda untuk memproses hasil pengenalan ucapan di sini.
    }

    @Override
    public void onComplete() {
        System.out.println("Tugas selesai");
    }

    @Override
    public void onError(Exception e) {
        System.out.println("Tugas gagal: " + e.getMessage());
    }
};
Antarmuka/MetodeParameterNilai kembaliDeskripsi
public void onEvent(RecognitionResult result)

result: Hasil pengenalan real-time (RecognitionResult)

Tidak ada

Dipanggil ketika server mengirim respons.

public void onComplete()

Tidak ada

Tidak ada

Dipanggil setelah tugas selesai.

public void onError(Exception e)

e: Informasi pengecualian.

Tidak ada

Dipanggil ketika terjadi pengecualian.

Respons

Hasil pengenalan real-time (RecognitionResult)

RecognitionResult merepresentasikan hasil dari satu pengenalan real-time.

Antarmuka/MetodeParameterNilai kembaliDeskripsi
public String getRequestId()

Tidak ada

requestId

Mendapatkan requestId.

public boolean isSentenceEnd()

Tidak ada

Apakah kalimat lengkap telah terbentuk, yaitu apakah batas kalimat terdeteksi.

Menentukan apakah kalimat yang diberikan telah berakhir.

public Sentence getSentence()

Tidak ada

Informasi kalimat (Sentence)

Mendapatkan informasi kalimat, termasuk timestamp dan teks.

Informasi kalimat (Sentence)

Antarmuka/MetodeParameterNilai kembaliDeskripsi
public Long getBeginTime()

Tidak ada

Waktu mulai kalimat, dalam ms.

Mengembalikan waktu mulai kalimat.

public Long getEndTime()

Tidak ada

Waktu akhir kalimat, dalam ms.

Mengembalikan waktu akhir kalimat.

public String getText()

Tidak ada

Teks yang dikenali.

Mengembalikan teks yang dikenali.

public List<Word> getWords()

Tidak ada

Daftar objek Informasi timestamp tingkat kata (Word).

Mengembalikan informasi timestamp tingkat kata.

Informasi timestamp tingkat kata (Word)

Antarmuka/MetodeParameterNilai kembaliDeskripsi
public long getBeginTime()

Tidak ada

Waktu mulai kata, dalam ms.

Mengembalikan waktu mulai kata.

public long getEndTime()

Tidak ada

Waktu akhir kata, dalam ms.

Mengembalikan waktu akhir kata.

public String getText()

Tidak ada

Kata.

Mengembalikan kata yang dikenali.

public String getPunctuation()

Tidak ada

Tanda baca.

Mengembalikan tanda baca.

Kode kesalahan

Jika Anda mengalami kesalahan, lihat Kode kesalahan untuk troubleshooting.

Jika masalah berlanjut, bergabunglah dengan komunitas developer untuk melaporkan masalah Anda dan berikan Request ID untuk investigasi lebih lanjut.

FAQ

Fitur

T: Bagaimana cara menjaga koneksi ke server tetap aktif selama periode diam yang panjang?

Atur parameter permintaan heartbeat ke true, dan terus kirim audio diam ke server.

Audio diam adalah audio yang tidak mengandung sinyal suara dalam file atau aliran data. Anda dapat menghasilkan audio diam dengan beberapa cara, misalnya dengan menggunakan perangkat lunak pengeditan audio seperti Audacity atau Adobe Audition, atau alat command-line seperti FFmpeg.

T: Bagaimana cara mengonversi audio ke format yang didukung?

Gunakan alat FFmpeg. Untuk penggunaan lebih lanjut, lihat situs resmi FFmpeg.

# Perintah konversi dasar (templat universal)
# -i, tujuan: path file input, contoh nilai: audio.wav
# -c:a, tujuan: penyandi audio, contoh nilai: aac, libmp3lame, pcm_s16le
# -b:a, tujuan: bitrate (kontrol kualitas audio), contoh nilai: 192k, 320k
# -ar, tujuan: laju sampel, contoh nilai: 44100 (CD), 48000, 16000
# -ac, tujuan: jumlah saluran, contoh nilai: 1 (mono), 2 (stereo)
# -y, tujuan: timpa file yang ada (tidak perlu nilai)
ffmpeg -i input_audio.ext -c:a encoder_name -b:a bitrate -ar sample_rate -ac channels output.ext

# Contoh: WAV -> MP3 (pertahankan kualitas asli)
ffmpeg -i input.wav -c:a libmp3lame -q:a 0 output.mp3
# Contoh: MP3 -> WAV (format standar PCM 16-bit)
ffmpeg -i input.mp3 -c:a pcm_s16le -ar 44100 -ac 2 output.wav
# Contoh: M4A -> AAC (ekstrak/konversi audio Apple)
ffmpeg -i input.m4a -c:a copy output.aac  # Ekstrak langsung tanpa re-encoding
ffmpeg -i input.m4a -c:a aac -b:a 256k output.aac  # Re-encode untuk kualitas lebih tinggi
# Contoh: FLAC lossless -> Opus (kompresi tinggi)
ffmpeg -i input.flac -c:a libopus -b:a 128k -vbr on output.opus

T: Bagaimana cara mengenali file lokal (rekaman)?

Ada dua cara untuk mengenali file lokal:

  • Masukkan path file lokal secara langsung: pendekatan ini hanya mengembalikan hasil pengenalan lengkap setelah pengenalan selesai, sehingga tidak cocok untuk skenario yang memerlukan umpan balik segera.

    Lihat Panggilan sinkron, dan masukkan path file ke metode call dari Kelas Recognition untuk mengenali rekaman secara langsung.

  • Konversi file lokal ke aliran biner untuk pengenalan: pendekatan ini mengenali file dan mengalirkan hasil secara bersamaan, yang cocok untuk skenario yang memerlukan umpan balik segera.

    • Lihat Panggilan streaming dua arah: berbasis callback, dan kirim aliran biner ke server untuk pengenalan melalui metode sendAudioFrame dari Kelas Recognition.
    • Lihat Panggilan streaming dua arah: berbasis Flowable, dan kirim aliran biner ke server untuk pengenalan melalui metode streamCall dari Kelas Recognition.

Troubleshooting

T: Mengapa ucapan tidak dapat dikenali (tidak ada hasil pengenalan)?

  1. Periksa bahwa format audio (format) dan laju sampel (sampleRate/sample_rate) dalam parameter permintaan benar dan memenuhi batasan parameter. Kesalahan umum meliputi:

    • File audio memiliki ekstensi .wav tetapi sebenarnya dalam format MP3, sedangkan parameter permintaan format diatur ke mp3 (pengaturan parameter salah).
    • Laju sampel audio adalah 3600 Hz, tetapi parameter permintaan sampleRate/sample_rate diatur ke 48000 (pengaturan parameter salah).

    Gunakan alat ffprobe untuk mendapatkan informasi tentang kontainer, kodek, laju sampel, saluran, dan lainnya tentang audio:

ffprobe -v error -show_entries format=format_name -show_entries stream=codec_name,sample_rate,channels -of default=noprint_wrappers=1 input.xxx
  1. Jika tidak ada masalah yang ditemukan dari pemeriksaan di atas, konfigurasikan kata panas khusus untuk meningkatkan pengenalan istilah tertentu.