Use the Qwen-Audio-TTS/CosyVoice non-real-time speech synthesis Python SDK to generate audio from text in non-streaming or streaming mode.
User guide: See Non-real-time speech synthesis.
The features described in this document are available only in the China (Beijing) region.
Alibaba Cloud Model Studio has released a workspace-specific domain for the China (Beijing) region. The new dedicated domain delivers superior performance and higher stability for inference requests. We recommend migrating from dashscope.aliyuncs.com to {WorkspaceId}.cn-beijing.maas.aliyuncs.com.
Replace {WorkspaceId} with your actual Workspace ID. The existing domain remains fully functional.
Prerequisites
-
Obtain an API key completed, and API key configured as an environment variable.
-
DashScope Python SDK 1.25.17 or later installed. Install the latest version.
HttpSpeechSynthesizer class
Package path: dashscope.audio.http_tts.http_speech_synthesizer.HttpSpeechSynthesizer
Description: HTTP-based speech synthesis. Use the stream parameter to switch between non-streaming and streaming modes.
call() — speech synthesis
Method signature:
@classmethod
def call(cls, model: str, text: str, voice: str,
format: str = "wav", sample_rate: int = 24000,
volume: int = 50, rate: float = 1.0, pitch: float = 1.0,
bit_rate: int = 32, enable_ssml: bool = False,
word_timestamp_enabled: bool = False,
seed: int = 0, language_hints: list = None,
instruction: str = None,
enable_aigc_tag: bool = False,
aigc_propagator: str = None,
aigc_propagate_id: str = None,
hot_fix: dict = None,
enable_markdown_filter: bool = False,
stream: bool = False,
api_key: str = None, **kwargs)
Parameters:
|
Parameter |
Type |
Required |
Description |
|
model |
str |
Yes |
The speech synthesis model. Valid values:
|
|
text |
str |
Yes |
The text to synthesize. Supports SSML and LaTeX input. Replace the text content with the corresponding format.
|
|
voice |
str |
Yes |
The voice for synthesis. Valid values:
|
|
format |
str |
No |
The audio format. Default value: mp3. Valid values:
|
|
sample_rate |
int |
No |
The audio sample rate in Hz. Valid values: 8000, 16000, 22050 (default), 24000, 44100, 48000. |
|
volume |
int |
No |
The volume level. Default value: 50. Valid values: [0, 100]. |
|
rate |
float |
No |
The speech rate. Default value: 1.0. Valid values: [0.5, 2.0]. |
|
pitch |
float |
No |
The pitch. Default value: 1.0. Valid values: [0.5, 2.0]. |
|
bit_rate |
int |
No |
The audio bitrate in kbps. Default value: 32. Valid values: [6, 510]. Important This parameter is supported only when |
|
enable_ssml |
bool |
No |
Specifies whether to enable SSML. Set this to |
|
word_timestamp_enabled |
bool |
No |
Specifies whether to enable word-level timestamps. Default: False.
Available only in streaming output mode. Supported voices: cloned voices of 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. qwen-audio-3.0-tts-plus, qwen-audio-3.0-tts-flash, and cloned voices of other models do not support this feature. |
|
seed |
int |
No |
The random seed for synthesis. Different seeds produce different outputs. With identical model version, text, voice, and other parameters, the same seed reproduces the same output. Default value: 0. Valid values: [0, 65535]. |
|
language_hints |
list |
No |
Important
Specifies the target language for speech synthesis to improve output quality. Use this parameter when numbers, abbreviations, or symbols are not pronounced as expected, or when synthesis quality for secondary languages is poor. Examples:
Valid values:
|
|
instruction |
str |
No |
An instruction that controls the synthesis behavior, such as dialect, emotion, or role. For usage details, see Non-real-time speech synthesis. |
|
enable_aigc_tag |
bool |
No |
Specifies whether to embed an AIGC watermark in the generated audio. When set to True, a watermark is embedded in audio files of supported formats (wav/mp3/opus). Default: 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 |
str |
No |
Sets the Default: 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 |
str |
No |
Sets the Default: 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. |
|
hot_fix |
dict |
No |
Text hot-fix configuration. Customizes the pronunciation of specified words or substitutes text before speech synthesis. Not supported by qwen-audio-3.0-tts-plus, qwen-audio-3.0-tts-flash, or cosyvoice-v2. Parameters:
Example: |
|
enable_markdown_filter |
bool |
No |
Specifies whether to enable Markdown filtering. When enabled, the system automatically strips Markdown markup from the input text before synthesis, preventing markup symbols from being read aloud. Only cloned voices of cosyvoice-v3-flash support this feature. Default: False. Valid values:
|
|
stream |
bool |
No |
Specifies whether to enable streaming mode. When set to |
|
api_key |
str |
No |
The API key. If not specified, the SDK automatically reads from the |
Return values:
-
Non-streaming mode (
stream=False): Returns a result object with the following properties:-
audio_url: The audio download URL (expires after a limited time). -
audio_id: The audio ID. -
expires_at: The URL expiration time.
-
-
Streaming mode (
stream=True): Returns an iterator. Each element contains the following properties:-
audio_data: The audio binary data (bytes) for the current chunk. -
sentences: Sentence-level synthesis information (if available).
ImportantIn streaming mode, the last element of the iterator contains both an audio data chunk and an
audio_urlfield (the download URL for the complete audio). To avoid duplicating audio content when concatenating chunks, filter out this element by checking thenot chunk.audio_urlcondition during iteration. -
Sample code
The following examples show non-streaming and streaming calls to Qwen-Audio-TTS/CosyVoice speech synthesis. Set the DASHSCOPE_API_KEY environment variable before running the code.
Different model versions require matching voice versions. For example, cosyvoice-v3-flash and cosyvoice-v3-plus use voices such as longanhuan, while cosyvoice-v2 uses voices such as longxiaochun_v2. When switching models, update the voice accordingly. Each voice supports different languages. To synthesize non-Chinese audio, select a voice that supports the target language. For the full mapping of models to voices, see CosyVoice Voice list.
Non-streaming call
A non-streaming call sets stream=False, waits for synthesis to complete, and returns an audio URL. Download the audio file from this URL.
# -*- coding: utf-8 -*-
import os
import dashscope
from dashscope.audio.http_tts.http_speech_synthesizer import HttpSpeechSynthesizer
# If the environment variable is not configured, replace the next line with: api_key = "sk-xxx", i.e., replace with your actual API Key
api_key = os.getenv("DASHSCOPE_API_KEY")
# Replace "{WorkspaceId}" with your actual Workspace ID
dashscope.base_http_api_url = 'https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1'
# Non-streaming call, returns an audio URL
result = HttpSpeechSynthesizer.call(
model="qwen-audio-3.0-tts-flash", # When switching models, you must also switch to the corresponding voice for that version
text="Today is a great day to build products that people love!",
voice="longanhuan_v3.6", # This voice is for qwen-audio-3.0-tts-flash; for qwen-audio-3.0-tts-plus, use longanlingxin or longanlufeng; for the cosyvoice-v3 series, use longanhuan; for cosyvoice-v2, use v2 voices such as longxiaochun_v2
format="wav",
sample_rate=24000,
stream=False,
api_key=api_key,
)
# Get the audio URL
print(f"Audio URL: {result.audio_url}")
print(f"Audio ID: {result.audio_id}")
if result.audio_id:
request_id = result.audio_id.removeprefix("audio_")
print(f"Request ID: {request_id}")
print(f"Expiration time: {result.expires_at}")
Streaming call
A streaming call sets stream=True and returns an iterator that yields audio data in chunks, enabling real-time playback with low first-packet latency. The last element of the iterator also returns a complete audio_url. When iterating, use not chunk.audio_url to filter out this element and avoid duplicating audio content.
# -*- coding: utf-8 -*-
import os
import dashscope
from dashscope.audio.http_tts.http_speech_synthesizer import HttpSpeechSynthesizer
# If the environment variable is not configured, replace the next line with: api_key = "sk-xxx", i.e., replace with your actual API Key
api_key = os.getenv("DASHSCOPE_API_KEY")
# Replace "{WorkspaceId}" with your actual Workspace ID
dashscope.base_http_api_url = 'https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1'
# Streaming call, returns audio data chunk by chunk
stream_result = HttpSpeechSynthesizer.call(
model="qwen-audio-3.0-tts-flash", # When switching models, you must also switch to the corresponding voice for that version
text="Today is a great day to build products that people love!",
voice="longanhuan_v3.6", # This voice is for qwen-audio-3.0-tts-flash; for qwen-audio-3.0-tts-plus, use longanlingxin or longanlufeng; for the cosyvoice-v3 series, use longanhuan; for cosyvoice-v2, use v2 voices such as longxiaochun_v2
format="wav",
sample_rate=24000,
stream=True,
api_key=api_key,
)
# Iterate over the iterator, receiving audio data chunk by chunk
audio_chunks = []
for chunk in stream_result:
if not chunk.audio_url and chunk.audio_data: # Filter out the last chunk containing the full audio URL to avoid audio duplication
audio_chunks.append(chunk.audio_data)
print(f"Received audio data chunk, size: {len(chunk.audio_data)} bytes")
if chunk.sentences:
print(f"Sentence info: {chunk.sentences}")
if chunk.audio_id:
print(f"Audio ID: {chunk.audio_id}")
request_id = chunk.audio_id.removeprefix("audio_")
print(f"Request ID: {request_id}")
# Merge all audio data and save
full_audio = b"".join(audio_chunks)
print(f"Total audio size: {len(full_audio)} bytes")
with open("output.wav", "wb") as f:
f.write(full_audio)
print("Audio saved to output.wav")