Appearance
time speech synthesis API reference-CosyVoice speech synthesis Python SDK
Use the DashScope Python SDK to integrate CosyVoice real-time speech synthesis into your application through non-streaming, one-way streaming, or bidirectional streaming modes. User guide: For model descriptions and selection recommendations, see Speech synthesis.
Service endpoint
The SDK uses the Beijing region endpoint by default. To switch to a different region, modify dashscope.base_websocket_api_url before initialization.
International
If you select the International deployment scope, model inference compute resources are dynamically scheduled worldwide, excluding the Chinese mainland. Static data is stored in your selected region. Supported region: Singapore.
wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference
Chinese mainland
If you select the Chinese mainland deployment scope, model inference compute resources are restricted to the Chinese mainland. Static data is stored in your selected region. Supported region: China (Beijing).
wss://dashscope.aliyuncs.com/api-ws/v1/inference
Switch to the Singapore region:
HELPCODEESCAPE-python
import dashscope
dashscope.base_websocket_api_url = 'wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference'SpeechSynthesizer
Package path : dashscope.audio.tts_v2.SpeechSynthesizer
Constructor
HELPCODEESCAPE-python
SpeechSynthesizer(
model: str,
voice: str,
format: AudioFormat = AudioFormat.MP3_22050HZ_MONO_256KBPS,
volume: int = 50,
speech_rate: float = 1.0,
pitch_rate: float = 1.0,
callback: ResultCallback = None)call() - non-streaming
Method signature:
HELPCODEESCAPE-python
def call(self, text: str) -> bytesParameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| text | str | Yes | The full text to synthesize. Maximum length: 20,000 characters. |
Return value : bytes containing the complete audio data.
Description: This blocking call returns the complete audio data at once. It is best suited for short text where real-time streaming is not required. Reinitialize the SpeechSynthesizer instance before each call.
streaming_call() - streaming
Method signature:
HELPCODEESCAPE-python
def streaming_call(self, text: str) -> NoneParameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| text | str | Yes | A text segment to synthesize. Call this method multiple times to append text. Maximum per call: 20,000 characters. Cumulative maximum: 200,000 characters. |
Description: This bidirectional streaming call accepts text in segments and delivers synthesized audio through callbacks in real time. It is ideal for integration with large language models where text is generated progressively. Call streaming_complete() after sending all text.
streaming_complete() - end streaming
Method signature:
HELPCODEESCAPE-python
def streaming_complete(self) -> NoneDescription: Notifies the server that all text has been sent. Blocks the current thread until the remaining text is synthesized and all audio data is returned. Failing to call this method may result in trailing text not being converted to speech.
get_last_request_id() - get request ID
Method signature:
HELPCODEESCAPE-python
def get_last_request_id(self) -> strReturn value : str containing the request ID of the most recent request. Use this for troubleshooting and tracing.
get_first_package_delay() - get first-packet latency
Method signature:
HELPCODEESCAPE-python
def get_first_package_delay(self) -> intReturn value : int representing the delay in milliseconds from sending text to receiving the first audio chunk. Call this after synthesis completes.
get_response() - get response message
Method signature:
HELPCODEESCAPE-python
def get_response(self) -> strReturn value : str containing the JSON-formatted response message from the most recent synthesis task, including request status and output information.
Constructor parameters
The following parameters are set through the SpeechSynthesizer constructor to control the model, voice, format, and audio characteristics. Parameter Type Required Description model str Yes The model name. voice str Yes **voice **string* *(required) The voice used for speech synthesis.
System voices: See Voice list
Cloned voices: Custom voices created through voice cloning
Custom voices: Custom voices created through voice design
format enum No Audio encoding format and sample rate. Default: AudioFormat.MP3_22050HZ_MONO_256KBPS.The AudioFormat enum is located in
dashscope.audio.tts_v2and supports MP3, WAV, PCM, and other formats. volume int No The volume level. Default value: 50. Valid values: [0, 100]. speech_rate float No The speech rate. Default value: 1.0. Valid values: [0.5, 2.0]. pitch_rate float No The pitch. Default value: 1.0. Valid values: [0.5, 2.0]. bit_rate int No The audio bit rate in kbps. When the audio format is opus, usebit_rateto adjust the bit rate. Default value: 32. Valid values: [6, 510].
**
**Note ** Set bit_rate through the additional_params parameter:
python
synthesizer = SpeechSynthesizer(
model="cosyvoice-v3-flash",
voice="longanyang",
additional_params={"bit_rate": 128000}
)word_timestamp_enabled bool No Specifies whether to enable word-level timestamps. Default value: false. Only available for cloned voices using the cosyvoice-v3-flash, cosyvoice-v3-plus, and cosyvoice-v2 models, as well as system voices marked as supported in Voice list.
**
**Note ** Set word_timestamp_enabled through the additional_params parameter:
python
synthesizer = SpeechSynthesizer(
model="cosyvoice-v3-flash",
voice="your_voice",
additional_params={"word_timestamp_enabled": True}
)seed 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]. language_hints list[str] No
**
**Important **
- 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 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
instruction str No Controls synthesis characteristics such as dialect, emotion, or speaking style. For usage details, see Instruction-based control. enable_aigc_tag bool 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 cosyvoice-v3-flash, cosyvoice-v3-plus, and cosyvoice-v2 support this feature.
**
**Note ** Set enable_aigc_tag, aigc_propagator, and aigc_propagate_id through the additional_params parameter:
python
synthesizer = SpeechSynthesizer(
model="cosyvoice-v3-flash",
voice="longanyang",
additional_params={
"enable_aigc_tag": True,
"aigc_propagator": "your_propagator",
"aigc_propagate_id": "your_propagate_id"
}
)aigc_propagator str 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 cosyvoice-v3-flash, cosyvoice-v3-plus, and cosyvoice-v2 support this feature. Set through the additional_params parameter. See the enable_aigc_tag example. aigc_propagate_id str 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 cosyvoice-v3-flash, cosyvoice-v3-plus, and cosyvoice-v2 support this feature. Set through the additional_params parameter. See the enable_aigc_tag example. hot_fix dict No Configures pronunciation corrections and text replacements applied before synthesis. Only cloned voices of cosyvoice-v3-flash support this feature. 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:
python
synthesizer = SpeechSynthesizer(
model="cosyvoice-v3-flash",
voice="your_voice", # Replace with your cosyvoice-v3-flash cloned voice
hot_fix={
"pronunciation": \[{"weather": "tian1 qi4"}\],
"replace": \[{"today": "gold day"}\]
}
)enable_markdown_filter bool No
**
**Important ** 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.
Default value: false. Valid values:
- true: Enable Markdown filtering
- false: Disable Markdown filtering
**
**Note ** Set enable_markdown_filter through the additional_params parameter:
python
synthesizer = SpeechSynthesizer(
model="cosyvoice-v3-flash",
voice="your_voice", # Replace with your cosyvoice-v3-flash cloned voice
additional_params={"enable_markdown_filter": True}
)callback ResultCallback No A callback instance for receiving synthesized audio and event notifications asynchronously. When set, call() runs in streaming mode and delivers audio through the on_data callback. When not set, call() runs in non-streaming mode and returns the complete audio as bytes.
ResultCallback
Package path : dashscope.audio.tts_v2.ResultCallback
on_open() - connection established
Method signature:
HELPCODEESCAPE-python
def on_open(self) -> NoneTriggered when: The WebSocket connection is successfully established. Use this callback to initialize audio output streams or open file resources.
on_event() - receive server response
Method signature:
HELPCODEESCAPE-python
def on_event(self, message: str) -> NoneParameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| message | str | Yes | A server response event in JSON format containing header (request information) and payload (output information). The payload.output field contains event type, original text, and other details. See output field in on_event messages . |
Triggered when : A server response is received. The message is a JSON string containing synthesis event output (event type, original text, sentence information). Parse with json.loads(message) and access payload.output for details.
on_complete() - synthesis complete
Method signature:
HELPCODEESCAPE-python
def on_complete(self) -> NoneTriggered when: All text has been synthesized and all audio data has been delivered through on_data. Use this callback to call get_first_package_delay() for performance metrics.
on_data() - receive audio data
Method signature:
HELPCODEESCAPE-python
def on_data(self, data: bytes) -> NoneParameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| data | bytes | Yes | A chunk of audio binary data in the format specified by the constructor's format parameter. |
Triggered when: An audio data chunk is received. This callback is invoked multiple times during synthesis. Use it to write data to a file or feed it to a playback device.
on_error() - error occurred
Method signature:
HELPCODEESCAPE-python
def on_error(self, message: str) -> NoneParameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| message | str | Yes | An error description containing the error code and detailed reason. |
Triggered when: An error occurs during synthesis. The connection closes automatically after this callback fires. Log the error for troubleshooting.
on_close() - connection closed
Method signature:
HELPCODEESCAPE-python
def on_close(self) -> NoneTriggered when: The WebSocket connection closes (whether normally or due to an error). Use this callback to release resources such as audio playback devices.
output field in on_event messages
The JSON message received by the on_event callback contains a payload.output field with synthesis event information. Use this field to track synthesis progress and retrieve per-sentence details. The output field structure is as follows:
| Field | Type | Description |
|---|---|---|
| type | str | Event type. Values: sentence-begin (sentence synthesis started), sentence-synthesis (sentence synthesis in progress), or sentence-end (sentence synthesis finished). |
| original_text | str | The original text of the current sentence. Returned in sentence-begin and sentence-end events. |
| sentence | dict | Sentence information. Contains index (sentence sequence number) and words (word list with timestamp information when word_timestamp_enabled is on). |
Message example:
HELPCODEESCAPE-json
{
"header": {
"task_id": "xxx",
"event": "result-generated",
"attributes": {}
},
"payload": {
"output": {
"type": "sentence-begin",
"original_text": "How is the weather today?",
"sentence": {
"index": 0,
"words": []
}
}
}
}Parsing example:
HELPCODEESCAPE-python
import json
def on_event(self, message):
data = json.loads(message)
output = data.get('payload', {}).get('output', {})
event_type = output.get('type', '')
original_text = output.get('original_text', '')
if event_type:
print(f'Event type: {event_type}, Original text: {original_text}')Code examples
The SDK supports the following synthesis modes:
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.
Non-streaming
The text sent in a single call must not exceed 20,000 characters. Exceeding this limit causes an error. Important
Reinitialize the SpeechSynthesizer instance before each call.
HELPCODEESCAPE-python
# coding=utf-8
import dashscope
from dashscope.audio.tts_v2 import *
import os
# The API Keys for Singapore and Beijing regions are different. Get API Key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# If environment variable is not configured, replace the following line with your Model Studio API Key: dashscope.api_key = "sk-xxx"
dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')
# The following is the Singapore region URL. To use a model in the Beijing region, replace the URL with: wss://dashscope.aliyuncs.com/api-ws/v1/inference
dashscope.base_websocket_api_url='wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference'
# Model
model = "cosyvoice-v3-flash"
# Voice
voice = "longanyang"
# Instantiate SpeechSynthesizer, passing request parameters such as model and voice in the constructor
synthesizer = SpeechSynthesizer(model=model, voice=voice)
# Send text for synthesis and get binary audio
audio = synthesizer.call("How is the weather today?")
# The first text submission requires establishing a WebSocket connection, so the first packet latency includes the connection setup time
print('[Metric] requestId: {}, first packet latency: {} ms'.format(
synthesizer.get_last_request_id(),
synthesizer.get_first_package_delay()))
# Save audio to local file
with open('output.mp3', 'wb') as f:
f.write(audio)One-way streaming
The text sent in a single call must not exceed 20,000 characters. Exceeding this limit causes an error. Important
Reinitialize the SpeechSynthesizer instance before each call.
HELPCODEESCAPE-python
# coding=utf-8
import os
import json
import dashscope
from dashscope.audio.tts_v2 import *
from datetime import datetime
def get_timestamp():
now = datetime.now()
formatted_timestamp = now.strftime("[%Y-%m-%d %H:%M:%S.%f]")
return formatted_timestamp
# The API Keys for Singapore and Beijing regions are different. Get API Key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# If environment variable is not configured, replace the following line with your Model Studio API Key: dashscope.api_key = "sk-xxx"
dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')
# The following is the Singapore region URL. To use a model in the Beijing region, replace the URL with: wss://dashscope.aliyuncs.com/api-ws/v1/inference
dashscope.base_websocket_api_url='wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference'
# Model
model = "cosyvoice-v3-flash"
# Voice
voice = "longanyang"
# Define callback interface
class Callback(ResultCallback):
_player = None
_stream = None
def on_open(self):
self.file = open("output.mp3", "wb")
print("Connection established: " + get_timestamp())
def on_complete(self):
print("Speech synthesis completed, all results received: " + get_timestamp())
# After the task completes (on_complete callback triggered), you can call get_first_package_delay to get the latency
# The first text submission requires establishing a WebSocket connection, so the first packet latency includes the connection setup time
print('[Metric] requestId: {}, first packet latency: {} ms'.format(
synthesizer.get_last_request_id(),
synthesizer.get_first_package_delay()))
def on_error(self, message: str):
print(f"Speech synthesis error: {message}")
def on_close(self):
print("Connection closed: " + get_timestamp())
self.file.close()
def on_event(self, message):
# Parse server-side events and get output information
data = json.loads(message)
output = data.get('payload', {}).get('output', {})
event_type = output.get('type', '')
original_text = output.get('original_text', '')
if event_type:
print(f"Event type: {event_type}, original text: {original_text}")
def on_data(self, data: bytes) -> None:
print(get_timestamp() + " Binary audio length: " + str(len(data)))
self.file.write(data)
callback = Callback()
# Instantiate SpeechSynthesizer, passing request parameters such as model and voice in the constructor
synthesizer = SpeechSynthesizer(
model=model,
voice=voice,
callback=callback,
)
# Send text for synthesis and get binary audio in real time via the on_data callback method
synthesizer.call("How is the weather today?")Bidirectional streaming
The text sent per call must not exceed 20,000 characters. The cumulative text must not exceed 200,000 characters.
During streaming input, call
streaming_callmultiple times to submit text segments in sequence. The server automatically performs sentence segmentation on received text:Complete sentences are synthesized immediately
Incomplete sentences are buffered until complete
When
streaming_completeis called, the server force-synthesizes all received but unprocessed text (including incomplete sentences).The interval between text segments must not exceed 23 seconds. Otherwise, a "request timeout after 23 seconds" exception is raised.
If there's no text to send, call
streaming_completepromptly to end the task. ImportantAlways call
streaming_complete. Failing to do so may cause trailing text to not be converted to speech.The server enforces a 23-second timeout. This value can't be modified on the client side.
HELPCODEESCAPE-python
# coding=utf-8
#
# pyaudio installation instructions:
# For macOS, run the following commands:
# brew install portaudio
# pip install pyaudio
# For Debian/Ubuntu, run the following commands:
# sudo apt-get install python-pyaudio python3-pyaudio
# or
# pip install pyaudio
# For CentOS, run the following commands:
# sudo yum install -y portaudio portaudio-devel && pip install pyaudio
# For Microsoft Windows, run the following command:
# python -m pip install pyaudio
import os
import time
import pyaudio
import json
import dashscope
from dashscope.api_entities.dashscope_response import SpeechSynthesisResponse
from dashscope.audio.tts_v2 import *
from datetime import datetime
def get_timestamp():
now = datetime.now()
formatted_timestamp = now.strftime("[%Y-%m-%d %H:%M:%S.%f]")
return formatted_timestamp
# The API Keys for Singapore and Beijing regions are different. Get API Key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# If environment variable is not configured, replace the following line with your Model Studio API Key: dashscope.api_key = "sk-xxx"
dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')
# The following is the Singapore region URL. To use a model in the Beijing region, replace the URL with: wss://dashscope.aliyuncs.com/api-ws/v1/inference
dashscope.base_websocket_api_url='wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference'
# Model
model = "cosyvoice-v3-flash"
# Voice
voice = "longanyang"
# Define callback interface
class Callback(ResultCallback):
_player = None
_stream = None
def on_open(self):
print("Connection established: " + get_timestamp())
self._player = pyaudio.PyAudio()
self._stream = self._player.open(
format=pyaudio.paInt16, channels=1, rate=22050, output=True
)
def on_complete(self):
print("Speech synthesis completed, all results received: " + get_timestamp())
def on_error(self, message: str):
print(f"Speech synthesis error: {message}")
def on_close(self):
print("Connection closed: " + get_timestamp())
# Stop the player
self._stream.stop_stream()
self._stream.close()
self._player.terminate()
def on_event(self, message):
# Parse server-side events and get output information
data = json.loads(message)
output = data.get('payload', {}).get('output', {})
event_type = output.get('type', '')
original_text = output.get('original_text', '')
if event_type:
print(f"Event type: {event_type}, original text: {original_text}")
def on_data(self, data: bytes) -> None:
print(get_timestamp() + " Binary audio length: " + str(len(data)))
self._stream.write(data)
callback = Callback()
test_text = [
"Streaming text-to-speech SDK,",
"converts input text",
"into binary audio data.",
"Compared with non-streaming speech synthesis,",
"streaming synthesis offers better real-time performance.",
"Users hear near-synchronous audio output while typing,",
"greatly improving interaction experience",
"and reducing wait time.",
"Ideal for large language model (LLM) integration,",
"where text is streamed for speech synthesis.",
]
# Instantiate SpeechSynthesizer, passing request parameters such as model and voice in the constructor
synthesizer = SpeechSynthesizer(
model=model,
voice=voice,
format=AudioFormat.PCM_22050HZ_MONO_16BIT,
callback=callback,
)
# Send text for streaming synthesis. Get binary audio in real time via the on_data callback method
for text in test_text:
synthesizer.streaming_call(text)
time.sleep(0.1)
# End streaming speech synthesis
synthesizer.streaming_complete()
# The first text submission requires establishing a WebSocket connection, so the first packet latency includes the connection setup time
print('[Metric] requestId: {}, first packet latency: {} ms'.format(
synthesizer.get_last_request_id(),
synthesizer.get_first_package_delay()))