Qwen-LiveTranslate Java SDK - API reference

Updated at:

Translate speech in real time using the DashScope Java SDK and the qwen3.5-livetranslate-flash-realtime model. The SDK connects over WebSocket, streams audio input, and returns translated text and synthesized speech.

Before you begin

  1. Install the SDK and make sure the DashScope SDK version is 2.22.5 or later.
  2. Get and configure an API key.
  3. Learn about Real-time speech/audio and video translation - Qwen.

ImportantAlibaba Cloud Model Studio has released workspace-specific domains for the China (Beijing) and Singapore regions. The new dedicated domains deliver superior performance and higher stability for inference requests. We recommend migrating to the new domains:

  • China (Beijing): from wss://dashscope.aliyuncs.com to wss://{WorkspaceId}.cn-beijing.maas.aliyuncs.com
  • Singapore: from wss://dashscope-intl.aliyuncs.com to wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com

{WorkspaceId} is your workspace ID, which can be found on the Workspace Details page in the Alibaba Cloud Model Studio console. The existing domain remains fully functional.

Request parameters

Key interfaces

OmniRealtimeConversation class

OmniRealtimeConversation is introduced via import com.alibaba.dashscope.audio.omni.OmniRealtimeConversation;.

Method signatureServer response events (delivered via callback)Description
public OmniRealtimeConversation(OmniRealtimeParam param, OmniRealtimeCallback callback)

None

Constructor.

public void connect() throws NoApiKeyException, InterruptedException

Server events

Session created

Server events

Session configuration updated

Establishes a connection with the server.

public void updateSession(OmniRealtimeConfig config)

Server events

Session configuration updated

Updates the session configuration. We recommend calling this method first after the connection is established. If this method is not called, the system uses the default configuration. Only the parameters involved in OmniRealtimeConfig need to be considered.

public void appendAudio(String audioBase64)

None

Appends Base64-encoded audio data chunks to the cloud input audio buffer. The server automatically detects speech start and end and triggers translation.

public void commit()

input_audio_buffer.committed

Input audio buffer committed

In Manual mode, commits the audio previously appended to the cloud buffer via the appendAudio method. The server automatically starts generating a translation response upon receipt. In VAD mode, this method does not need to be called; the server commits automatically.

public void clearAppendedAudio()

input_audio_buffer.cleared

Input audio buffer cleared

Clears the audio data in the current cloud buffer that has not been committed.

public void endSession() throws InterruptedException

session.finished

The server completes the speech translation and ends the session

Notifies the server to end the session. After receiving the session end notification, the server completes the final speech translation.

public void close(int code, String reason)

None

Terminates the task and closes the connection.

public String getSessionId()

None

Gets the session_id of the current task.

public String getResponseId()

None

Gets the response_id of the most recent response.

public long getFirstTextDelay()

None

Gets the first text delay of the most recent response (in milliseconds).

public long getFirstAudioDelay()

None

Gets the first audio delay of the most recent response (in milliseconds).

Callback interface (OmniRealtimeCallback)

The server returns server-side response events and data to the client through callbacks.

Extend this class and implement the corresponding methods to handle server events.

Introduced via import com.alibaba.dashscope.audio.omni.OmniRealtimeCallback;.

Method signatureParametersDescription
public void onOpen()

None

Triggered when the WebSocket connection is successfully established.

public abstract void onEvent(JsonObject message)

message: Server events

Triggered when a server event is received.

public abstract void onClose(int code, String reason)

code: status code

reason: log information when the WebSocket connection is closed

Triggered when the WebSocket connection is closed.

Complete example

The following example shows how to record audio from a microphone in real time and translate it.

Sample code for real-time microphone translation

import com.alibaba.dashscope.audio.omni.*;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.google.gson.JsonObject;

import javax.sound.sampled.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import com.alibaba.dashscope.utils.Constants;

/**
 * Microphone example for the real-time audio and video translation model
 */
public class Main {
    static {Constants.baseHttpApiUrl="https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1";}
    private static final int INPUT_CHUNK_SIZE = 3200;   // 100 ms of 16 kHz 16-bit mono audio
    private static final int OUTPUT_CHUNK_SIZE = 4800;  // 100 ms of 24 kHz 16-bit mono audio
    private static final AtomicBoolean running = new AtomicBoolean(true);
    private static SourceDataLine speaker;  // Speaker

    public static void main(String[] args) throws InterruptedException {
        String apiKey = System.getenv("DASHSCOPE_API_KEY");
        if (apiKey == null || apiKey.isEmpty()) {
            System.err.println("Set the DASHSCOPE_API_KEY environment variable");
            System.exit(1);
        }

        // Create connection parameters
        OmniRealtimeParam param = OmniRealtimeParam.builder()
                .model("qwen3.5-livetranslate-flash-realtime")
                .url("wss://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api-ws/v1/realtime")
                .apikey(apiKey)
                .build();

        // Create the callback handler
        OmniRealtimeCallback callback = new OmniRealtimeCallback() {
            @Override
            public void onOpen() {
                System.out.println("[Connection established]");
            }

            @Override
            public void onEvent(JsonObject message) {
                String type = message.get("type").getAsString();
                switch (type) {
                    case "input_audio_buffer.speech_started":
                        System.out.println("====== Speech input detected ======");
                        break;
                    case "input_audio_buffer.speech_stopped":
                        System.out.println("====== Speech input ended ======");
                        break;
                    case "conversation.item.input_audio_transcription.completed":
                        String originalText = message.get("transcript").getAsString();
                        System.out.println("[Original text] " + originalText);
                        break;
                    case "response.audio_transcript.done":
                        String translatedText = message.get("transcript").getAsString();
                        System.out.println("[Translation result] " + translatedText);
                        break;
                    case "response.audio.delta":
                        // Decode and play the translated audio
                        String audioB64 = message.get("delta").getAsString();
                        byte[] audioBytes = Base64.getDecoder().decode(audioB64);
                        if (speaker != null) {
                            speaker.write(audioBytes, 0, audioBytes.length);
                        }
                        break;
                    case "error":
                        JsonObject error = message.get("error").getAsJsonObject();
                        System.err.println("[Error] " + error.get("message").getAsString());
                        break;
                }
            }

            @Override
            public void onClose(int code, String reason) {
                System.out.println("[Connection closed] code: " + code + ", reason: " + reason);
            }
        };

        // Create the session
        OmniRealtimeConversation conversation = new OmniRealtimeConversation(param, callback);

        try {
            // Initialize the speaker (for playing the translated speech)
            AudioFormat speakerFormat = new AudioFormat(24000, 16, 1, true, false);
            DataLine.Info speakerInfo = new DataLine.Info(SourceDataLine.class, speakerFormat);
            speaker = (SourceDataLine) AudioSystem.getLine(speakerInfo);
            speaker.open(speakerFormat, OUTPUT_CHUNK_SIZE * 4);
            speaker.start();

            // Initialize the microphone (for capturing speech input)
            AudioFormat micFormat = new AudioFormat(16000, 16, 1, true, false);
            DataLine.Info micInfo = new DataLine.Info(TargetDataLine.class, micFormat);
            if (!AudioSystem.isLineSupported(micInfo)) {
                System.err.println("Microphone is not available");
                System.exit(1);
            }
            TargetDataLine microphone = (TargetDataLine) AudioSystem.getLine(micInfo);
            microphone.open(micFormat);
            microphone.start();

            // Connect to the server
            conversation.connect();

            // Configure translation parameters
            Map<String, Object> phrases = new HashMap<>();
            phrases.put("Inteligencia Artificial", "Artificial Intelligence");
            phrases.put("Aprendizaje Automático", "Machine Learning");

            OmniRealtimeConfig config = OmniRealtimeConfig.builder()
                    .modalities(Arrays.asList(OmniRealtimeModality.AUDIO, OmniRealtimeModality.TEXT))
                    .voice("Tina")
                    .inputAudioFormat(OmniRealtimeAudioFormat.PCM_16000HZ_MONO_16BIT)
                    .outputAudioFormat(OmniRealtimeAudioFormat.PCM_24000HZ_MONO_16BIT)
                    .InputAudioTranscription("qwen3-asr-flash-realtime")
                    .translationConfig(OmniRealtimeTranslationParam.builder()
                            .language("en")
                            .corpus(OmniRealtimeTranslationParam.Corpus.builder()
                                    .phrases(phrases)
                                    .build())
                            .build())
                    .build();

            conversation.updateSession(config);

            // Register the exit signal handler
            Runtime.getRuntime().addShutdownHook(new Thread(() -> {
                System.out.println("\n[Exiting...]");
                running.set(false);
                microphone.stop();
                microphone.close();
                speaker.stop();
                speaker.close();
                try {
                    conversation.endSession();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                conversation.close(1000, "User stopped");
            }));

            System.out.println("[Starting real-time translation] Speak into the microphone. Press Ctrl+C to exit");

            // Continuously capture microphone audio and send it
            byte[] buffer = new byte[INPUT_CHUNK_SIZE];
            while (running.get()) {
                int bytesRead = microphone.read(buffer, 0, buffer.length);
                if (bytesRead > 0) {
                    conversation.appendAudio(Base64.getEncoder().encodeToString(buffer));
                }
            }

        } catch (NoApiKeyException e) {
            System.err.println("API Key error: " + e.getMessage());
        } catch (Exception e) {
            System.err.println("An exception occurred: " + e.getMessage());
            e.printStackTrace();
        }
    }
}