Skip to main content
Qwen-ASR-Realtime

Referensi API - Qwen-ASR-Realtime Java SDK

Gunakan DashScope Java SDK untuk memanggil Qwen-ASR-Realtime.

Prasyarat

Alibaba Cloud Model Studio telah merilis domain khusus ruang kerja untuk wilayah China (Beijing) dan Singapura. Domain khusus baru ini memberikan performa unggul dan stabilitas lebih tinggi untuk permintaan inferensi. Kami menyarankan Anda bermigrasi ke domain baru berikut:
  • China (Beijing): dari dashscope.aliyuncs.com ke {WorkspaceId}.cn-beijing.maas.aliyuncs.com
  • Singapura: dari dashscope-intl.aliyuncs.com ke {WorkspaceId}.ap-southeast-1.maas.aliyuncs.com
Ganti {WorkspaceId} dengan Workspace ID aktual Anda. Domain lama tetap berfungsi sepenuhnya.

Mode interaksi

Qwen-ASR-Realtime mendukung dua mode untuk menentukan kapan audio diproses:

Mode

enableTurnDetection

Cara kerja

Mode VAD (default)

true

Server mendeteksi batas-batas ucapan menggunakan voice activity detection (VAD) dan menentukan kapan buffer audio dikirim untuk dikenali.

Mode manual

false

Client mengontrol kapan audio dikirim dengan memanggil commit(). Ini memberi Anda full kontrol atas pemisahan segmen.

Untuk detail masing-masing mode, lihat Mode VAD dan Mode manual.

Contoh lengkap

Kode contoh membaca your_audio_file.pcm (PCM16, 16 kHz, mono). Jika Anda hanya memiliki format MP3, WAV, atau serupa, konversi dengan ffmpeg:
ffmpeg -i your_audio.mp3 -ar 16000 -ac 1 -f s16le your_audio_file.pcm
Java
import com.alibaba.dashscope.audio.omni.*;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.google.gson.JsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sound.sampled.LineUnavailableException;
import java.io.File;
import java.io.FileInputStream;
import java.util.Base64;
import java.util.Collections;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;

public class Qwen3AsrRealtimeUsage {
    private static final Logger log = LoggerFactory.getLogger(Qwen3AsrRealtimeUsage.class);
    private static final int AUDIO_CHUNK_SIZE = 1024; // Ukuran chunk audio dalam byte
    private static final int SLEEP_INTERVAL_MS = 30;  // Interval tidur dalam milidetik

    public static void main(String[] args) throws InterruptedException, LineUnavailableException {
        CountDownLatch finishLatch = new CountDownLatch(1);

        OmniRealtimeParam param = OmniRealtimeParam.builder()
                .model("qwen3-asr-flash-realtime")
                // Berikut adalah konfigurasi untuk wilayah Singapura. Saat memanggil, ganti "{WorkspaceId}" dengan ID ruang kerja Anda yang sebenarnya. Konfigurasi berbeda tiap wilayah.
                .url("wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/realtime")
                // Kunci API berbeda antara wilayah Singapura dan Beijing. Dapatkan Kunci API Anda: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
                // Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan Kunci API Alibaba Cloud Model Studio Anda: .apikey("sk-xxx")
                .apikey(System.getenv("DASHSCOPE_API_KEY"))
                .build();

        OmniRealtimeConversation conversation = null;
        final AtomicReference<OmniRealtimeConversation> conversationRef = new AtomicReference<>(null);
        conversation = new OmniRealtimeConversation(param, new OmniRealtimeCallback() {
            @Override
            public void onOpen() {
                System.out.println("connection opened");
            }
            @Override
            public void onEvent(JsonObject message) {
                String type = message.get("type").getAsString();
                switch(type) {
                    case "session.created":
                        System.out.println("start session: " + message.get("session").getAsJsonObject().get("id").getAsString());
                        break;
                    case "conversation.item.input_audio_transcription.completed":
                        System.out.println("transcription: " + message.get("transcript").getAsString());
                        finishLatch.countDown();
                        break;
                    case "input_audio_buffer.speech_started":
                        System.out.println("======VAD Speech Start======");
                        break;
                    case "input_audio_buffer.speech_stopped":
                        System.out.println("======VAD Speech Stop======");
                        break;
                    case "conversation.item.input_audio_transcription.text":
                        System.out.println("transcription: " + message.get("text").getAsString() + message.get("stash").getAsString());
                        break;
                    default:
                        break;
                }
            }
            @Override
            public void onClose(int code, String reason) {
                System.out.println("connection closed code: " + code + ", reason: " + reason);
            }
        });
        conversationRef.set(conversation);
        try {
            conversation.connect();
        } catch (NoApiKeyException e) {
            throw new RuntimeException(e);
        }

        OmniRealtimeTranscriptionParam transcriptionParam = new OmniRealtimeTranscriptionParam();
        transcriptionParam.setLanguage("zh");
        transcriptionParam.setInputAudioFormat("pcm");
        transcriptionParam.setInputSampleRate(16000);

        OmniRealtimeConfig config = OmniRealtimeConfig.builder()
                .modalities(Collections.singletonList(OmniRealtimeModality.TEXT))
                .transcriptionConfig(transcriptionParam)
                .build();
        conversation.updateSession(config);

        String filePath = "your_audio_file.pcm";
        File audioFile = new File(filePath);
        if (!audioFile.exists()) {
            log.error("Audio file not found: {}", filePath);
            return;
        }

        try (FileInputStream audioInputStream = new FileInputStream(audioFile)) {
            byte[] audioBuffer = new byte[AUDIO_CHUNK_SIZE];
            int bytesRead;
            int totalBytesRead = 0;

            log.info("Starting to send audio data from: {}", filePath);

            // Baca dan kirim data audio per chunk
            while ((bytesRead = audioInputStream.read(audioBuffer)) != -1) {
                totalBytesRead += bytesRead;
                String audioB64 = Base64.getEncoder().encodeToString(audioBuffer);
                // Kirim chunk audio ke percakapan
                conversation.appendAudio(audioB64);

                // Tambahkan jeda kecil untuk mensimulasikan streaming audio real-time
                Thread.sleep(SLEEP_INTERVAL_MS);
            }

            log.info("Finished sending audio data. Total bytes sent: {}", totalBytesRead);

        } catch (Exception e) {
            log.error("Error sending audio from file: {}", filePath, e);
        }

        //kirim session.finish dan tunggu selesai dan tutup
        conversation.endSession();
        log.info("task finished");

        System.exit(0);
    }
}
        Constants.baseHttpApiUrl = "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1";

Parameter permintaan

Parameter koneksi (OmniRealtimeParam)

Atur parameter ini dengan metode berantai dari kelas OmniRealtimeParam.
OmniRealtimeParam param = OmniRealtimeParam.builder()
        .model("qwen3-asr-flash-realtime")
        // Titik akhir untuk wilayah Singapura.
        // Konfigurasi berikut untuk wilayah Singapura. Ganti "{WorkspaceId}" dengan Workspace ID aktual Anda. Konfigurasi berbeda tergantung wilayah.
        .url("wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/realtime")
        // Kunci API untuk wilayah Singapura dan Beijing berbeda.
        // Untuk mendapatkan kunci API, lihat https://www.alibabacloud.com/help/en/model-studio/get-api-key
        // Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan .apikey("sk-xxx").
        .apikey(System.getenv("DASHSCOPE_API_KEY"))
        .build();

Parameter

Tipe

Wajib

Deskripsi

model

String

Ya

Model yang digunakan. Contoh: qwen3-asr-flash-realtime.

url

String

Ya

Titik akhir layanan. China (Beijing): wss://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api-ws/v1/realtime. Singapura: wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/realtime. Ganti {WorkspaceId} dengan Workspace ID aktual Anda. Ganti {WorkspaceId} dengan workspace ID aktual Anda.

apikey

String

Tidak

Kunci API.

Konfigurasi sesi (OmniRealtimeConfig)

Atur parameter ini dengan metode berantai dari kelas OmniRealtimeConfig.
OmniRealtimeTranscriptionParam transcriptionParam = new OmniRealtimeTranscriptionParam();
transcriptionParam.setLanguage("zh");
transcriptionParam.setInputSampleRate(16000);
transcriptionParam.setInputAudioFormat("pcm");

OmniRealtimeConfig config = OmniRealtimeConfig.builder()
        .modalities(Collections.singletonList(OmniRealtimeModality.TEXT))
        .enableTurnDetection(true)
        .turnDetectionType("server_vad")
        .turnDetectionThreshold(0.0f)
        .turnDetectionSilenceDurationMs(400)
        .transcriptionConfig(transcriptionParam)
        .build();

Parameter

Tipe

Wajib

Deskripsi

modalities

List<OmniRealtimeModality>

Ya

Modalitas output. Tetap diatur sebagai [OmniRealtimeModality.TEXT].

enableTurnDetection

boolean

Tidak

Mengaktifkan VAD sisi server. Jika dinonaktifkan, panggil commit() untuk memicu pengenalan secara manual. Default: true.

turnDetectionType

String

Tidak

Jenis VAD. Tetap diatur sebagai server_vad.

turnDetectionThreshold

float

Tidak

Ambang batas sensitivitas VAD. Nilai yang direkomendasikan: 0.0.

Default: 0.2. Rentang valid: [-1, 1].

Nilai lebih rendah meningkatkan sensitivitas (dapat terpicu oleh kebisingan latar belakang). Nilai lebih tinggi mengurangi sensitivitas dan membantu menghindari pemicuan salah di lingkungan berisik.

turnDetectionSilenceDurationMs

int

Tidak

Durasi diam dalam milidetik yang menandai akhir sebuah ujaran. Nilai yang direkomendasikan: 400.

Default: 800. Rentang valid: [200, 6000].

Durasi lebih pendek (misalnya 300 ms) mempercepat respons tetapi dapat memotong jeda alami. Durasi lebih panjang (misalnya 1200 ms) menangani jeda lebih baik tetapi meningkatkan latensi.

transcriptionConfig

OmniRealtimeTranscriptionParam

Tidak

Pengaturan pengenalan ucapan. Lihat Parameter transkripsi.

Parameter transkripsi (OmniRealtimeTranscriptionParam)

Atur parameter ini dengan metode setter dari kelas OmniRealtimeTranscriptionParam.
OmniRealtimeTranscriptionParam transcriptionParam = new OmniRealtimeTranscriptionParam();
transcriptionParam.setLanguage("zh");
transcriptionParam.setInputSampleRate(16000);
transcriptionParam.setInputAudioFormat("pcm");

Parameter

Tipe

Wajib

Deskripsi

language

String

Tidak

Bahasa sumber audio. Untuk daftar bahasa yang didukung, lihat Bahasa yang didukung.

inputSampleRate

int

Tidak

Laju pengambilan sampel audio dalam Hz. Nilai valid: 16000, 8000.

Default: 16000.

Mengatur 8000 menyebabkan upsampling sisi server ke 16.000 Hz, yang dapat menimbulkan latensi ringan. Gunakan hanya untuk audio asli 8.000 Hz (misalnya telepon).

inputAudioFormat

String

Tidak

Format encoding audio. Nilai valid: pcm, opus. Default: pcm.

corpusText

String

Tidak

Teks konteks untuk contextual biasing. Berikan teks latar belakang, kosakata entitas, atau materi referensi untuk meningkatkan akurasi pengenalan. Maksimum: 10.000 token.

Antarmuka utama

OmniRealtimeConversation

Impor: com.alibaba.dashscope.audio.omni.OmniRealtimeConversation Kelas ini mengelola siklus hidup WebSocket: menghubungkan ke server, mengirim audio, dan mengakhiri sesi.

Buat percakapan

OmniRealtimeConversation conversation =
        new OmniRealtimeConversation(param, callback);
Membuat instans percakapan baru dengan parameter koneksi dan penanganan callback yang ditentukan.

Hubungkan ke server

conversation.connect();
Membuka koneksi WebSocket. Server merespons dengan event session.created dan session.updated. Melemparkan: NoApiKeyException, InterruptedException.

Konfigurasi sesi

conversation.updateSession(config);
Memperbarui konfigurasi sesi setelah koneksi terbentuk. Server merespons dengan event session.updated. Jika tidak dipanggil, server menggunakan pengaturan default.

Kirim audio data

conversation.appendAudio(audioBase64);
Menambahkan segmen audio berformat Base64 ke buffer audio sisi server.
  • Mode VAD (enableTurnDetection=true): Server mendeteksi batas-batas ucapan dan menentukan kapan buffer diproses.
  • Mode manual (enableTurnDetection=false): Audio terakumulasi dalam buffer hingga Anda memanggil commit() untuk memicu pengenalan. Setiap event dapat berisi maksimal 15 MiB data audio.

Kirim buffer audio

conversation.commit();
Mengirimkan buffer audio yang telah dikumpulkan untuk dikenali. Server merespons dengan event input_audio_buffer.committed.
Metode ini hanya tersedia dalam mode manual (enableTurnDetection=false). Terjadi error jika buffer audio kosong.

Akhiri sesi

conversation.endSession();  // synchronous
// or
conversation.endSessionAsync();  // asynchronous
Memberi tahu server untuk menyelesaikan pemrosesan audio yang tersisa dan mengakhiri sesi. Server merespons dengan event session.finished. Kapan harus dipanggil:
  • Mode VAD: Setelah selesai mengirim audio.
  • Mode manual: Setelah memanggil commit().

Tutup koneksi

conversation.close();
Menghentikan tugas dan menutup koneksi WebSocket segera.

Dapatkan ID sesi dan ID respons

String sessionId = conversation.getSessionId();
String responseId = conversation.getResponseId();
  • getSessionId() mengembalikan ID sesi untuk tugas saat ini.
  • getResponseId() mengembalikan ID respons dari respons server terbaru.

OmniRealtimeCallback

Impor: com.alibaba.dashscope.audio.omni.OmniRealtimeCallback Wariskan kelas ini dan implementasikan metode callback untuk menangani event dari server.

Metode

Parameter

Dipicu saat

onOpen()

Tidak ada

Koneksi WebSocket berhasil dibuat.

onEvent(JsonObject message)

message: event server dalam format JSON. Jenis event umum: session.created, session.updated, input_audio_buffer.committed, conversation.item.input_audio_transcription.completed, session.finished.

Event server diterima. Uraikan field type untuk menentukan jenis event.

onClose(int code, String reason)

code: Kode status. reason: Alasan penutupan.

Koneksi WebSocket ditutup.

Pembuatan Gambar
  • FAQ
Video Generation
Model Dunia
Audio
  • Pembuatan audio
Realtime API
Penyematan Teks
TokenPlan
Model production