By default, the SDK connects to the Beijing region endpoint. To use a different region, set Constants.baseWebsocketApiUrl before initializing the SDK.
Singapore
China (Beijing)
wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inferenceReplace {WorkspaceId} with your actual workspace ID.
wss://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api-ws/v1/inferenceReplace {WorkspaceId} with your actual workspace ID.
Switch to the Singapore region:
Copy
import com.alibaba.dashscope.utils.Constants;// Set this before any SDK initializationConstants.baseWebsocketApiUrl = "wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference";
Alibaba 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 dashscope.aliyuncs.com to {WorkspaceId}.cn-beijing.maas.aliyuncs.com
Singapore: from dashscope-intl.aliyuncs.com to {WorkspaceId}.ap-southeast-1.maas.aliyuncs.com
Replace {WorkspaceId} with your actual Workspace ID. The existing domains remain fully functional.
Text to synthesize. Maximum length: 20,000 characters.
Return value: ByteBuffer or null. For non-streaming calls, returns the complete audio data. For unidirectional streaming calls, this method returns null; audio is delivered through the callback.
Description: Cancels the current bidirectional streaming speech synthesis task. After calling this method, the SDK immediately ends the current task. You can start a new synthesis task on the same connection without reinitializing the SpeechSynthesizer instance.
Version requirement: This feature requires Java SDK 2.22.26 or later.
Model limitations:
China (Beijing): All Qwen-Audio-TTS models support this feature. CosyVoice models require v2 or later.
Singapore: All Qwen-Audio-TTS models support this feature. CosyVoice models do not support this feature.
Cloned voices: Custom voices created through voice cloning
Custom voices: Custom voices created through voice design
format(SpeechSynthesisAudioFormat)
enum
No
Audio encoding format and sample rate.Default: SpeechSynthesisAudioFormat.MP3_22050HZ_MONO_256KBPS.SpeechSynthesisAudioFormat package: com.alibaba.dashscope.audio.ttsv2.SpeechSynthesisAudioFormat.
volume(int)
int
No
The volume level.Default value: 50.Valid values: [0, 100].
speechRate(float)
float
No
The speech rate.Default value: 1.0.Valid values: [0.5, 2.0].
pitchRate(float)
float
No
The pitch.Default value: 1.0.Valid values: [0.5, 2.0].
enableWordTimestamp(boolean)
boolean
No
Specifies whether to enable word-level timestamps.Default value: false.Available only in streaming output mode. Supported voices: cloned voices of qwen-audio-3.0-tts-plus, qwen-audio-3.0-tts-flash, cosyvoice-v3.5-plus, cosyvoice-v3.5-flash, cosyvoice-v3-flash, cosyvoice-v3-plus, and cosyvoice-v2, and system voices marked as supported in Qwen-Audio-TTS voice list, CosyVoice Voice list. Cloned voices of other models do not support this feature.
seed(int)
int
No
A random seed for controlling variation in the synthesis output. When the model version, text, voice, and other parameters are unchanged, using the same seed produces identical results.Default value: 0.Valid values: [0, 65535].For SDK versions earlier than 2.21.7, set seed through additional parameters.
languageHints(List<String>)
List<String>
No
This parameter is an array, but the current version only processes the first element. Pass a single value.
This parameter specifies the target language for speech synthesis. It's unrelated to the language of the audio sample used in voice cloning. To set the source language for a cloning task, see the voice cloning API reference.
Specifies the target language for speech synthesis to improve output quality.When digit pronunciation, abbreviation expansion, symbol reading, or minority-language synthesis doesn't meet expectations, use this parameter. For example:
Unexpected digit pronunciation: "hello, this is 110" is read as "hello, this is one zero" instead of the expected Chinese pronunciation
Inaccurate symbol pronunciation: "@" is read as the Chinese equivalent instead of "at"
Poor minor language synthesis quality with unnatural results
Valid values:
zh: Chinese
en: English
fr: French
de: German
ja: Japanese
ko: Korean
ru: Russian
pt: Portuguese
th: Thai
id: Indonesian
vi: Vietnamese
es: Spanish
it: Italian
ms: Malaysian
fil: Filipino
ar: Arabic
instruction(String)
String
No
Controls synthesis characteristics such as dialect, emotion, or speaking style.For usage details, see Instruction control.
hotFix(ParamHotFix)
ParamHotFix
No
Configures pronunciation corrections and text replacements applied before synthesis.This feature isn't supported by qwen-audio-3.0-tts-plus, qwen-audio-3.0-tts-flash, or cosyvoice-v2.Parameters:
pronunciation: Custom pronunciation. Specifies pinyin annotations for words to correct inaccurate default pronunciations.
replace: Text replacement. Replaces specified words with target text before synthesis. The replaced text is used as the actual synthesis input.
Example:
Copy
List<ParamHotFix.PronunciationItem> pronunciationItems = new ArrayList<>();pronunciationItems.add(new ParamHotFix.PronunciationItem("weather", "tian1 qi4"));List<ParamHotFix.ReplaceItem> replaceItems = new ArrayList<>();replaceItems.add(new ParamHotFix.ReplaceItem("today", "gold day"));ParamHotFix paramHotFix = new ParamHotFix();paramHotFix.setPronunciation(pronunciationItems);paramHotFix.setReplace(replaceItems);SpeechSynthesisParam param = SpeechSynthesisParam.builder() .model("qwen-audio-3.0-tts-flash") // Model .voice("longanhuan_v3.6") // Voice .hotFix(paramHotFix) .build();
The audio bit rate in kbps. When the audio format is mp3 or opus, use bit_rate to adjust the bit rate.
Default value: 32.
Valid values: [6, 510].
enable_aigc_tag
boolean
No
Specifies whether to embed an AIGC watermark in the generated audio. When set to true, the watermark is embedded in audio files of supported formats (wav/mp3/opus).
Default value: false.
Only qwen-audio-3.0-tts-plus, qwen-audio-3.0-tts-flash, cosyvoice-v3-flash, cosyvoice-v3-plus, and cosyvoice-v2 support this feature.
aigc_propagator
String
No
Sets the ContentPropagator field in the AIGC watermark, identifying the content propagator. Takes effect only when enable_aigc_tag is true.
Default value: Alibaba Cloud UID.
Only qwen-audio-3.0-tts-plus, qwen-audio-3.0-tts-flash, cosyvoice-v3-flash, cosyvoice-v3-plus, and cosyvoice-v2 support this feature.
aigc_propagate_id
String
No
Sets the PropagateID field in the AIGC watermark, uniquely identifying a specific propagation action. Takes effect only when enable_aigc_tag is true.
Default value: The request ID of the current speech synthesis request.
Only qwen-audio-3.0-tts-plus, qwen-audio-3.0-tts-flash, cosyvoice-v3-flash, cosyvoice-v3-plus, and cosyvoice-v2 support this feature.
enable_markdown_filter
boolean
No
Only cloned voices of cosyvoice-v3-flash support this feature.
Specifies whether to enable Markdown filtering. When enabled, the system automatically strips Markdown markup symbols from the input text before synthesis, preventing them from being read aloud.
Triggered when a synthesis event is received. Contains the audio frame, timestamp information, and output information (event type, original text, etc.).
Return value: com.google.gson.JsonObject, the output information of the synthesis event, containing event type and text content. Requires SDK version >= 2.22.0.
getOutput() returns a JsonObject that encapsulates synthesis event output information. Retrieve it in the onEvent callback or the Flowable stream. It contains the following fields:
Field
Type
Description
type
String
Event type. Possible values: sentence-begin (sentence start; returns the text to be synthesized), sentence-synthesis (audio synthesis in progress; returns an audio data chunk), sentence-end (sentence end; returns text content and word-level timestamps).
original_text
String
Original text of the current sentence. Returned in sentence-begin and sentence-end events.
sentence
JsonObject
Sentence information, containing the sentence index (index) and word-level timestamps (words). The sentence-end event includes full word-level timestamp information.
Non-streaming: A blocking call that sends the complete text at once and returns the full audio directly. Best suited for short-text speech synthesis.
Unidirectional streaming: A non-blocking call that sends the complete text at once and delivers audio data (potentially in chunks) through a callback function. Best suited for short-text scenarios that require low latency.
Bidirectional streaming: A non-blocking call that sends text in multiple segments and delivers incrementally synthesized audio through a callback function in real time. Best suited for long-text scenarios that require low latency.
The text length per request must not exceed 20,000 characters.
Reinitialize the SpeechSynthesizer instance before each call to the call method.
Copy
import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesisParam;import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesizer;import com.alibaba.dashscope.utils.Constants;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.nio.ByteBuffer;public class Main { // Model private static String model = "qwen-audio-3.0-tts-flash"; // Voice private static String voice = "longanhuan_v3.6"; public static void streamAudioDataToSpeaker() { // Request parameters SpeechSynthesisParam param = SpeechSynthesisParam.builder() // The API Keys for the Singapore and Beijing regions are different. Get an API Key: https://www.alibabacloud.com/help/en/model-studio/get-api-key // If the environment variable is not configured, replace the following line with your Model Studio API Key: .apiKey("sk-xxx") .apiKey(System.getenv("DASHSCOPE_API_KEY")) .model(model) // Model .voice(voice) // Voice .build(); // Synchronous mode: disable callback (second parameter is null) SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, null); ByteBuffer audio = null; try { // Block until audio is returned audio = synthesizer.call("What's the weather like today?"); } catch (Exception e) { throw new RuntimeException(e); } finally { // Close the WebSocket connection after the task is completed synthesizer.getDuplexApi().close(1000, "bye"); } if (audio != null) { // Save the audio data to a local file "output.mp3" File file = new File("output.mp3"); // The first text transmission requires establishing a WebSocket connection, so the first packet latency includes the connection setup time System.out.println( "[Metric] requestId: " + synthesizer.getLastRequestId() + ", first packet latency (ms): " + synthesizer.getFirstPackageDelay()); try (FileOutputStream fos = new FileOutputStream(file)) { fos.write(audio.array()); } catch (IOException e) { throw new RuntimeException(e); } } } public static void main(String[] args) { // The following configuration is for the Singapore region. Replace "{WorkspaceId}" with your actual workspace ID. The configuration varies by region. Constants.baseWebsocketApiUrl = "wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference"; streamAudioDataToSpeaker(); System.exit(0); }}
The text length per request must not exceed 20,000 characters.
Reinitialize the SpeechSynthesizer instance before each call to the call method.
Copy
import com.alibaba.dashscope.audio.tts.SpeechSynthesisResult;import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesisParam;import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesizer;import com.alibaba.dashscope.common.ResultCallback;import com.alibaba.dashscope.utils.Constants;import java.time.LocalDateTime;import java.time.format.DateTimeFormatter;import java.util.concurrent.CountDownLatch;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 { // Model private static String model = "qwen-audio-3.0-tts-flash"; // Voice private static String voice = "longanhuan_v3.6"; public static void streamAudioDataToSpeaker() { CountDownLatch latch = new CountDownLatch(1); // Implement the ResultCallback interface ResultCallback<SpeechSynthesisResult> callback = new ResultCallback<SpeechSynthesisResult>() { @Override public void onEvent(SpeechSynthesisResult result) { if (result.getAudioFrame() != null) { // Implement the logic to save audio data locally here System.out.println(TimeUtils.getTimestamp() + " Audio received"); } // Get output information, including event type and original text if (result.getOutput() != null && result.getOutput().has("type")) { System.out.println("Event type: " + result.getOutput().get("type").getAsString() + ", Original text: " + (result.getOutput().has("original_text") ? result.getOutput().get("original_text").getAsString() : "")); } } @Override public void onComplete() { System.out.println(TimeUtils.getTimestamp() + " Complete received, speech synthesis finished"); latch.countDown(); } @Override public void onError(Exception e) { System.out.println("Exception occurred: " + e.toString()); latch.countDown(); } }; // Request parameters SpeechSynthesisParam param = SpeechSynthesisParam.builder() // The API Keys for the Singapore and Beijing regions are different. Get an API Key: https://www.alibabacloud.com/help/en/model-studio/get-api-key // If the environment variable is not configured, replace the following line with your Model Studio API Key: .apiKey("sk-xxx") .apiKey(System.getenv("DASHSCOPE_API_KEY")) .model(model) // Model .voice(voice) // Voice .build(); // Passing "callback" as the second parameter enables asynchronous mode SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, callback); // Non-blocking call that returns null immediately (actual results are delivered asynchronously via the callback interface). Binary audio is received in real time through the onEvent method of the callback interface try { synthesizer.call("What's the weather like today?"); // Wait for synthesis to complete latch.await(); // Wait for playback thread to finish playing } catch (Exception e) { throw new RuntimeException(e); } finally { // Close the WebSocket connection after the task is completed synthesizer.getDuplexApi().close(1000, "bye"); } // The first text transmission requires establishing a WebSocket connection, so the first packet latency includes the connection setup time System.out.println( "[Metric] requestId: " + synthesizer.getLastRequestId() + ", first packet latency (ms): " + synthesizer.getFirstPackageDelay()); } public static void main(String[] args) { // The following configuration is for the Singapore region. Replace "{WorkspaceId}" with your actual workspace ID. The configuration varies by region. Constants.baseWebsocketApiUrl = "wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference"; streamAudioDataToSpeaker(); System.exit(0); }}
The text length per individual call must not exceed 20,000 characters, and the cumulative text length across all calls must not exceed 200,000 characters.
During streaming input, call streamingCall multiple times to submit text segments in order. The server automatically splits received text into sentences:
Complete sentences are synthesized immediately.
Incomplete sentences are buffered until they form a complete sentence.
When streamingComplete is called, the server force-synthesizes all received but unprocessed text segments, including incomplete sentences.
The interval between consecutive text segments must not exceed 23 seconds; exceeding this limit triggers a "request timeout after 23 seconds" exception.If no text is pending, call streamingComplete promptly to end the task.
Always call the streamingComplete method. Otherwise, trailing text segments may not be converted to speech.
The server enforces a 23-second timeout that cannot be changed on the client side.
Copy
import com.alibaba.dashscope.audio.tts.SpeechSynthesisResult;import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesisAudioFormat;import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesisParam;import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesizer;import com.alibaba.dashscope.common.ResultCallback;import com.alibaba.dashscope.utils.Constants;import java.time.LocalDateTime;import java.time.format.DateTimeFormatter;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 { private static String[] textArray = {"Streaming text-to-speech SDK, ", "can convert input text ", "into audio binary data. ", "Compared to non-streaming speech synthesis, ", "streaming synthesis offers better real-time performance. ", "While users input text, ", "they can hear nearly synchronous audio output, ", "greatly enhancing the interactive experience ", "and reducing user wait time. ", "It is suitable for calling large-scale ", "language models (LLMs) to ", "perform speech synthesis ", "with streaming text input."}; private static String model = "qwen-audio-3.0-tts-flash"; // Model private static String voice = "longanhuan_v3.6"; // Voice public static void streamAudioDataToSpeaker() { // Configure the callback function ResultCallback<SpeechSynthesisResult> callback = new ResultCallback<SpeechSynthesisResult>() { @Override public void onEvent(SpeechSynthesisResult result) { // System.out.println("Message received: " + result); if (result.getAudioFrame() != null) { // Implement the logic to process audio data here System.out.println(TimeUtils.getTimestamp() + " Audio received"); } } @Override public void onComplete() { System.out.println(TimeUtils.getTimestamp() + " Complete received, speech synthesis finished"); } @Override public void onError(Exception e) { System.out.println("Exception occurred: " + e.toString()); } }; // Request parameters SpeechSynthesisParam param = SpeechSynthesisParam.builder() // The API Keys for the Singapore and Beijing regions are different. Get an API Key: https://www.alibabacloud.com/help/en/model-studio/get-api-key // If the environment variable is not configured, replace the following line with your Model Studio API Key: .apiKey("sk-xxx") .apiKey(System.getenv("DASHSCOPE_API_KEY")) .model(model) .voice(voice) .format(SpeechSynthesisAudioFormat .PCM_22050HZ_MONO_16BIT) // Use PCM or MP3 for streaming synthesis .build(); SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, callback); // The call method with Callback will not block the current thread try { for (String text : textArray) { // Send text fragments and receive binary audio in real time through the onEvent method of the callback interface synthesizer.streamingCall(text); } // Wait for streaming speech synthesis to finish synthesizer.streamingComplete(); } catch (Exception e) { throw new RuntimeException(e); } finally { // Close the WebSocket connection after the task is completed synthesizer.getDuplexApi().close(1000, "bye"); } // The first text transmission requires establishing a WebSocket connection, so the first packet latency includes the connection setup time System.out.println( "[Metric] requestId: " + synthesizer.getLastRequestId() + ", first packet latency (ms): " + synthesizer.getFirstPackageDelay()); } public static void main(String[] args) { // The following configuration is for the Singapore region. Replace "{WorkspaceId}" with your actual workspace ID. The configuration varies by region. Constants.baseWebsocketApiUrl = "wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference"; streamAudioDataToSpeaker(); System.exit(0); }}
Flowable is an RxJava type representing a reactive stream that supports backpressure. For more information, see RxJava Flowable documentation.Before using Flowable, make sure the RxJava library is integrated and you understand the basics of reactive programming.The text length per individual call must not exceed 20,000 characters, and the cumulative text length across all calls must not exceed 200,000 characters.
Unidirectional streaming calls
Bidirectional streaming calls
The following example shows how to use the blockingForEach interface of a Flowable object to retrieve each streamed SpeechSynthesisResult object in a blocking manner.
Copy
import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesisParam;import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesizer;import com.alibaba.dashscope.exception.NoApiKeyException;import com.alibaba.dashscope.utils.Constants;import java.time.LocalDateTime;import java.time.format.DateTimeFormatter;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 { private static String model = "qwen-audio-3.0-tts-flash"; // Model private static String voice = "longanhuan_v3.6"; // Voice public static void streamAudioDataToSpeaker() throws NoApiKeyException { // Request parameters SpeechSynthesisParam param = SpeechSynthesisParam.builder() // The API Keys for the Singapore and Beijing regions are different. Get an API Key: https://www.alibabacloud.com/help/en/model-studio/get-api-key // If the environment variable is not configured, replace the following line with your Model Studio API Key: .apiKey("sk-xxx") .apiKey(System.getenv("DASHSCOPE_API_KEY")) .model(model) // Model .voice(voice) // Voice .build(); SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, null); synthesizer.callAsFlowable("What's the weather like today?").blockingForEach(result -> { if (result.getAudioFrame() != null) { // Implement the logic to process audio data here System.out.println(TimeUtils.getTimestamp() + " Audio received"); } // Get output information, including event type and original text if (result.getOutput() != null && result.getOutput().has("type")) { System.out.println("Event type: " + result.getOutput().get("type").getAsString() + ", Original text: " + (result.getOutput().has("original_text") ? result.getOutput().get("original_text").getAsString() : "")); } }); // Close the WebSocket connection after the task is completed synthesizer.getDuplexApi().close(1000, "bye"); // The first text transmission requires establishing a WebSocket connection, so the first packet latency includes the connection setup time System.out.println( "[Metric] requestId: " + synthesizer.getLastRequestId() + ", first packet latency (ms): " + synthesizer.getFirstPackageDelay()); } public static void main(String[] args) throws NoApiKeyException { // The following configuration is for the Singapore region. Replace "{WorkspaceId}" with your actual workspace ID. The configuration varies by region. Constants.baseWebsocketApiUrl = "wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference"; streamAudioDataToSpeaker(); System.exit(0); }}
The following example shows how to use a Flowable object as an input parameter for text streaming, and use the blockingForEach interface of the returned Flowable object to retrieve each streamed SpeechSynthesisResult object in a blocking manner.
Copy
import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesisParam;import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesizer;import com.alibaba.dashscope.exception.NoApiKeyException;import com.alibaba.dashscope.utils.Constants;import io.reactivex.BackpressureStrategy;import io.reactivex.Flowable;import java.time.LocalDateTime;import java.time.format.DateTimeFormatter;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 { private static String[] textArray = {"Streaming text-to-speech SDK, ", "can convert input text ", "into audio binary data. ", "Compared to non-streaming speech synthesis, ", "streaming synthesis offers better real-time performance. ", "While users input text, ", "they can hear nearly synchronous audio output, ", "greatly enhancing the interactive experience ", "and reducing user wait time. ", "It is suitable for calling large-scale ", "language models (LLMs) to ", "perform speech synthesis ", "with streaming text input."}; private static String model = "qwen-audio-3.0-tts-flash"; private static String voice = "longanhuan_v3.6"; public static void streamAudioDataToSpeaker() throws NoApiKeyException { // Simulate streaming input Flowable<String> textSource = Flowable.create(emitter -> { new Thread(() -> { for (int i = 0; i < textArray.length; i++) { emitter.onNext(textArray[i]); try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } } emitter.onComplete(); }).start(); }, BackpressureStrategy.BUFFER); // Request parameters SpeechSynthesisParam param = SpeechSynthesisParam.builder() // The API Keys for the Singapore and Beijing regions are different. Get an API Key: https://www.alibabacloud.com/help/en/model-studio/get-api-key // If the environment variable is not configured, replace the following line with your Model Studio API Key: .apiKey("sk-xxx") .apiKey(System.getenv("DASHSCOPE_API_KEY")) .model(model) // Model .voice(voice) // Voice .build(); SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, null); synthesizer.streamingCallAsFlowable(textSource).blockingForEach(result -> { if (result.getAudioFrame() != null) { // Implement the logic to play audio here System.out.println( TimeUtils.getTimestamp() + " Binary audio size: " + result.getAudioFrame().capacity()); } // Get output information, including event type and original text if (result.getOutput() != null && result.getOutput().has("type")) { System.out.println("Event type: " + result.getOutput().get("type").getAsString() + ", Original text: " + (result.getOutput().has("original_text") ? result.getOutput().get("original_text").getAsString() : "")); } }); synthesizer.getDuplexApi().close(1000, "bye"); // The first text transmission requires establishing a WebSocket connection, so the first packet latency includes the connection setup time System.out.println( "[Metric] requestId: " + synthesizer.getLastRequestId() + ", first packet latency (ms): " + synthesizer.getFirstPackageDelay()); } public static void main(String[] args) throws NoApiKeyException { // The following configuration is for the Singapore region. Replace "{WorkspaceId}" with your actual workspace ID. The configuration varies by region. Constants.baseWebsocketApiUrl = "wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference"; streamAudioDataToSpeaker(); System.exit(0); }}
The DashScope Java SDK uses OkHttp3 connection pooling to reduce the overhead of repeatedly establishing connections. For more information, see High-concurrency best practices.