全部產品
Search
文件中心

Alibaba Cloud Model Studio:即時語音合成-CosyVoice

更新時間:Mar 31, 2026

語音合成,又稱文本轉語音(Text-to-Speech,TTS),是將文本轉換為自然語音的技術。該技術基於機器學習演算法,通過學習大量語音樣本,掌握語言的韻律、語調和發音規則,從而在接收到文本輸入時產生真人般自然的語音內容。

核心功能

  • 即時產生高保真語音,支援中英等多語種自然發聲

  • 提供聲音複刻與聲音設計兩種音色定製方式

  • 支援流式輸入輸出,低延遲響應即時互動情境

  • 可調節語速、語調、音量與碼率,精細控制語音表現

  • 相容主流音頻格式,最高支援48kHz採樣率輸出

適用範圍

支援的模型:

國際

國際部署模式下,存取點與資料存放區均位於新加坡地區,模型推理計算資源在全球範圍內動態調度(不含中國內地)。

調用以下模型時,請選擇新加坡地區的API Key

  • CosyVoice:cosyvoice-v3-plus、cosyvoice-v3-flash

中國內地

中國內地部署模式下,存取點與資料存放區均位於北京地區,模型推理計算資源僅限於中國內地。

調用以下模型時,請選擇北京地區的API Key

  • CosyVoice:cosyvoice-v3.5-plus、cosyvoice-v3.5-flash、cosyvoice-v3-plus、cosyvoice-v3-flash、cosyvoice-v2

更多資訊請參見模型列表

模型選型

情境

推薦模型

理由

注意事項

品牌形象、專屬聲音、擴充系統音色等語音定製(基於文本描述)

cosyvoice-v3.5-plus

支援聲音設計,無需音頻樣本,通過文本描述建立定製化音色,適合從零開始設計品牌專屬聲音

cosyvoice-v3.5-plus 僅在北京地區可用,且不支援系統音色

品牌形象、專屬聲音、擴充系統音色等語音定製(基於音頻樣本)

cosyvoice-v3.5-plus

支援聲音複刻,基於真實音頻樣本快速複刻音色,打造擬人化品牌聲紋,確保音色高度還原與一致性

cosyvoice-v3.5-plus 僅在北京地區可用,且不支援系統音色

智能客服 / 語音助手

cosyvoice-v3-flash、cosyvoice-v3.5-flash

比plus模型成本低,支援流式互動、情感表達,響應快,性價比高

cosyvoice-v3.5-flash 僅在北京地區可用,且不支援系統音色

方言廣播系統

cosyvoice-v3.5-plus

支援東北話、閩南語等多種方言,適合地方內容播報

cosyvoice-v3.5-plus僅在北京地區可用,且不支援系統音色

教育類應用(含公式朗讀)

cosyvoice-v2、cosyvoice-v3-flash、cosyvoice-v3-plus

支援LaTeX公式轉語音,適合數理化課程講解

cosyvoice-v2和cosyvoice-v3-plus成本較高($0.286706/萬字元

結構化語音播報(新聞/公告)

cosyvoice-v3-plus、cosyvoice-v3-flash、cosyvoice-v2

支援SSML控制語速、停頓、發音等,提升播報專業度

需額外開發 SSML 產生邏輯,不支援設定情感

語音與文本精準對齊(如字幕產生、教學回放、聽寫訓練)

cosyvoice-v3-flash、cosyvoice-v3-plus、cosyvoice-v2

支援時間戳記輸出,可實現合成語音與原文同步

需顯式啟用時間戳記功能,預設關閉

多語言出海產品

cosyvoice-v3-flash、cosyvoice-v3-plus

支援多語種

不同地區和模型的能力存在差異,請仔細閱讀模型功能特性對比後再選擇使用

快速開始

下面是調用API的範例程式碼。更多常用情境的程式碼範例,請參見GitHub

您需要已擷取API Key配置API Key到環境變數(準備下線,併入配置 API Key)。如果通過SDK調用,還需要安裝DashScope SDK。請將範例程式碼中的 DASHSCOPE_API_HOST 替換為擷取的 API Host。

CosyVoice

重要

cosyvoice-v3.5-plus 和 cosyvoice-v3.5-flash 模型目前僅在北京地區可用,且專門用於聲音設計和聲音複刻情境(無系統音色)。在使用它們進行語音合成之前,請先參見CosyVoice聲音複刻/設計API建立目標音色。建立完成後,只需將代碼中的 voice 欄位更新為您的音色 ID,並將 model 欄位指定為對應模型,即可正常運行。

使用系統音色進行語音合成

以下樣本示範如何使用系統音色(參見音色列表)進行語音合成。

將合成音頻儲存為檔案

Python

# coding=utf-8

import os
import dashscope
from dashscope.audio.tts_v2 import *

# 新加坡地區和北京地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# 若沒有配置環境變數,請用百鍊API Key將下行替換為:dashscope.api_key = "sk-xxx"
dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')

# 以下為新加坡地區url,若使用北京地區的模型,需將url替換為:wss://dashscope.aliyuncs.com/api-ws/v1/inference
dashscope.base_websocket_api_url='wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference'

# 模型
# 不同模型版本需要使用對應版本的音色:
# cosyvoice-v3-flash/cosyvoice-v3-plus:使用longanyang等音色。
# cosyvoice-v2:使用longxiaochun_v2等音色。
# 每個音色支援的語言不同,合成日語、韓語等非中文語言時,需選擇支援對應語言的音色。詳見CosyVoice音色列表。
model = "cosyvoice-v3-flash"
# 音色
voice = "longanyang"

# 執行個體化SpeechSynthesizer,並在構造方法中傳入模型(model)、音色(voice)等請求參數
synthesizer = SpeechSynthesizer(model=model, voice=voice)
# 發送待合成文本,擷取二進位音頻
audio = synthesizer.call("今天天氣怎麼樣?")
# 首次發送文本時需建立 WebSocket 串連,因此首包延遲會包含串連建立的耗時
print('[Metric] requestId為:{},首包延遲為:{}毫秒'.format(
    synthesizer.get_last_request_id(),
    synthesizer.get_first_package_delay()))

# 將音頻儲存至本地
with open('output.mp3', 'wb') as f:
    f.write(audio)

Java

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 {
    // 模型
    // 不同模型版本需要使用對應版本的音色:
    // cosyvoice-v3-flash/cosyvoice-v3-plus:使用longanyang等音色。
    // cosyvoice-v2:使用longxiaochun_v2等音色。
    // 每個音色支援的語言不同,合成日語、韓語等非中文語言時,需選擇支援對應語言的音色。詳見CosyVoice音色列表。
    private static String model = "cosyvoice-v3-flash";
    // 音色
    private static String voice = "longanyang";

    public static void streamAudioDataToSpeaker() {
        // 請求參數
        SpeechSynthesisParam param =
                SpeechSynthesisParam.builder()
                        // 新加坡地區和北京地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
                        // 若沒有配置環境變數,請用百鍊API Key將下行替換為:.apiKey("sk-xxx")
                        .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                        .model(model) // 模型
                        .voice(voice) // 音色
                        .build();

        // 同步模式:禁用回調(第二個參數為null)
        SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, null);
        ByteBuffer audio = null;
        try {
            // 阻塞直至音頻返回
            audio = synthesizer.call("今天天氣怎麼樣?");
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            // 任務結束關閉websocket串連
            synthesizer.getDuplexApi().close(1000, "bye");
        }
        if (audio != null) {
            // 將音頻資料儲存到本地檔案“output.mp3”中
            File file = new File("output.mp3");
            // 首次發送文本時需建立 WebSocket 串連,因此首包延遲會包含串連建立的耗時
            System.out.println(
                    "[Metric] requestId為:"
                            + synthesizer.getLastRequestId()
                            + "首包延遲(毫秒)為:"
                            + 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) {
        // 以下為新加坡地區url,若使用北京地區的模型,需將url替換為:wss://dashscope.aliyuncs.com/api-ws/v1/inference
        Constants.baseWebsocketApiUrl = "wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference";
        streamAudioDataToSpeaker();
        System.exit(0);
    }
}

將LLM產生的文本即時轉成語音並通過擴音器播放

以下代碼展示通過本地裝置播放千問大語言模型(qwen-turbo)即時返回的常值內容。

Python

運行Python樣本前,需要通過pip安裝第三方音頻播放庫。

# coding=utf-8
# Installation instructions for pyaudio:
# APPLE Mac OS X
#   brew install portaudio
#   pip install pyaudio
# Debian/Ubuntu
#   sudo apt-get install python-pyaudio python3-pyaudio
#   or
#   pip install pyaudio
# CentOS
#   sudo yum install -y portaudio portaudio-devel && pip install pyaudio
# Microsoft Windows
#   python -m pip install pyaudio

import os
import pyaudio
import dashscope
from dashscope.audio.tts_v2 import *


from http import HTTPStatus
from dashscope import Generation

# 新加坡地區和北京地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# 若沒有配置環境變數,請用百鍊API Key將下行替換為:dashscope.api_key = "sk-xxx"
dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')

# 以下為新加坡地區url,若使用北京地區的模型,需將url替換為:wss://dashscope.aliyuncs.com/api-ws/v1/inference
dashscope.base_websocket_api_url='wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference'

# 不同模型版本需要使用對應版本的音色:
# cosyvoice-v3-flash/cosyvoice-v3-plus:使用longanyang等音色。
# cosyvoice-v2:使用longxiaochun_v2等音色。
# 每個音色支援的語言不同,合成日語、韓語等非中文語言時,需選擇支援對應語言的音色。詳見CosyVoice音色列表。
model = "cosyvoice-v3-flash"
voice = "longanyang"


class Callback(ResultCallback):
    _player = None
    _stream = None

    def on_open(self):
        print("websocket is open.")
        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 task complete successfully.")

    def on_error(self, message: str):
        print(f"speech synthesis task failed, {message}")

    def on_close(self):
        print("websocket is closed.")
        # stop player
        self._stream.stop_stream()
        self._stream.close()
        self._player.terminate()

    def on_event(self, message):
        print(f"recv speech synthsis message {message}")

    def on_data(self, data: bytes) -> None:
        print("audio result length:", len(data))
        self._stream.write(data)


def synthesizer_with_llm():
    callback = Callback()
    synthesizer = SpeechSynthesizer(
        model=model,
        voice=voice,
        format=AudioFormat.PCM_22050HZ_MONO_16BIT,
        callback=callback,
    )

    messages = [{"role": "user", "content": "請介紹一下你自己"}]
    responses = Generation.call(
        model="qwen-turbo",
        messages=messages,
        result_format="message",  # set result format as 'message'
        stream=True,  # enable stream output
        incremental_output=True,  # enable incremental output 
    )
    for response in responses:
        if response.status_code == HTTPStatus.OK:
            print(response.output.choices[0]["message"]["content"], end="")
            synthesizer.streaming_call(response.output.choices[0]["message"]["content"])
        else:
            print(
                "Request id: %s, Status code: %s, error code: %s, error message: %s"
                % (
                    response.request_id,
                    response.status_code,
                    response.code,
                    response.message,
                )
            )
    synthesizer.streaming_complete()
    print('requestId: ', synthesizer.get_last_request_id())


if __name__ == "__main__":
    synthesizer_with_llm()

Java

使用聲音複刻音色進行語音合成

聲音複刻與語音合成是緊密關聯的兩個獨立步驟,遵循“先建立,後使用”的流程:

  1. 準備錄音檔案

    將符合聲音複刻:輸入音頻格式的音頻檔案上傳至公網可訪問的位置,如阿里雲Object Storage Service,並確保URL可公開訪問。

  2. 建立音色

    調用建立音色介面。此步驟必須指定target_model/targetModel,聲明建立的音色將由哪個語音合成模型驅動。

    若已有建立好的音色(調用查詢音色列表介面查看),可跳過這一步直接進行下一步。

  3. 使用音色進行語音合成

    使用建立音色介面建立音色成功後,系統會返回一個voice_id/voiceID

    • voice_id/voiceID 可直接作為語音合成介面或各語言 SDK 中的 voice 參數使用,用於後續的文本轉語音。

    • 支援多種調用形態,包括非流式、單向流式以及雙向流式合成。

    • 合成時指定的語音合成模型必須與建立音色時的 target_model/targetModel 保持一致,否則合成會失敗。

範例程式碼:

import os
import time
import dashscope
from dashscope.audio.tts_v2 import VoiceEnrollmentService, SpeechSynthesizer

# 1. 環境準備
# 推薦通過環境變數配置API Key
# 新加坡和北京地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# 若沒有配置環境變數,請用百鍊API Key將下行替換為:dashscope.api_key = "sk-xxx"
dashscope.api_key = os.getenv("DASHSCOPE_API_KEY")
if not dashscope.api_key:
    raise ValueError("DASHSCOPE_API_KEY environment variable not set.")

# 以下為新加坡地區WebSocket url,若使用北京地區的模型,需將url替換為:wss://dashscope.aliyuncs.com/api-ws/v1/inference
dashscope.base_websocket_api_url='wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference'
# 以下為新加坡地區HTTP url,若使用北京地區的模型,需將url替換為:https://dashscope.aliyuncs.com/api/v1
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'


# 2. 定義複刻參數
TARGET_MODEL = "cosyvoice-v3.5-plus" 
# 為音色起一個有意義的首碼
VOICE_PREFIX = "myvoice" # 僅允許數字和小寫字母,小於十個字元
# 公網可訪問音頻URL
AUDIO_URL = "https://dashscope.oss-cn-beijing.aliyuncs.com/samples/audio/cosyvoice/cosyvoice-zeroshot-sample.wav" # 樣本URL,請替換為自己的

# 3. 建立音色 (非同步任務)
print("--- Step 1: Creating voice enrollment ---")
service = VoiceEnrollmentService()
try:
    voice_id = service.create_voice(
        target_model=TARGET_MODEL,
        prefix=VOICE_PREFIX,
        url=AUDIO_URL
    )
    print(f"Voice enrollment submitted successfully. Request ID: {service.get_last_request_id()}")
    print(f"Generated Voice ID: {voice_id}")
except Exception as e:
    print(f"Error during voice creation: {e}")
    raise e
# 4. 輪詢查詢音色狀態
print("\n--- Step 2: Polling for voice status ---")
max_attempts = 30
poll_interval = 10 # 秒
for attempt in range(max_attempts):
    try:
        voice_info = service.query_voice(voice_id=voice_id)
        status = voice_info.get("status")
        print(f"Attempt {attempt + 1}/{max_attempts}: Voice status is '{status}'")
        
        if status == "OK":
            print("Voice is ready for synthesis.")
            break
        elif status == "UNDEPLOYED":
            print(f"Voice processing failed with status: {status}. Please check audio quality or contact support.")
            raise RuntimeError(f"Voice processing failed with status: {status}")
        # 對於 "DEPLOYING" 等中間狀態,繼續等待
        time.sleep(poll_interval)
    except Exception as e:
        print(f"Error during status polling: {e}")
        time.sleep(poll_interval)
else:
    print("Polling timed out. The voice is not ready after several attempts.")
    raise RuntimeError("Polling timed out. The voice is not ready after several attempts.")

# 5. 使用複刻音色進行語音合成
print("\n--- Step 3: Synthesizing speech with the new voice ---")
try:
    synthesizer = SpeechSynthesizer(model=TARGET_MODEL, voice=voice_id)
    text_to_synthesize = "恭喜,已成功複刻併合成了屬於自己的聲音!"
    
    # call()方法返回二進位音頻資料
    audio_data = synthesizer.call(text_to_synthesize)
    print(f"Speech synthesis successful. Request ID: {synthesizer.get_last_request_id()}")

    # 6. 儲存音頻檔案
    output_file = "my_custom_voice_output.mp3"
    with open(output_file, "wb") as f:
        f.write(audio_data)
    print(f"Audio saved to {output_file}")

except Exception as e:
    print(f"Error during speech synthesis: {e}")

使用聲音設計音色進行語音合成

聲音設計與語音合成是緊密關聯的兩個獨立步驟,遵循“先建立,後使用”的流程:

  1. 準備聲音設計所需的聲音描述與試聽文本。

    • 聲音描述(voice_prompt):定義目標音色的特徵(關於如何編寫請參見“聲音設計:如何編寫高品質的聲音描述?”)。

    • 試聽文本(preview_text):目標音色產生的預覽音頻朗讀的內容(如“大家好,歡迎收聽”)。

  2. 調用建立音色介面,建立一個專屬音色,擷取音色名和預覽音頻。

    此步驟必須指定target_model,聲明建立的音色將由哪個語音合成模型驅動

    試聽擷取預覽音頻來判斷是否符合預期;若符合要求,繼續下一步,否則,重新設計。

    若已有建立好的音色(調用查詢音色列表介面查看),可跳過這一步直接進行下一步。

  3. 使用音色進行語音合成

    使用建立音色介面建立音色成功後,系統會返回一個voice_id/voiceID

    • voice_id/voiceID 可直接作為語音合成介面或各語言 SDK 中的 voice 參數使用,用於後續的文本轉語音。

    • 支援多種調用形態,包括非流式、單向流式以及雙向流式合成。

    • 合成時指定的語音合成模型必須與建立音色時的 target_model/targetModel 保持一致,否則合成會失敗。

範例程式碼:

  1. 產生專屬音色並試聽效果,若對效果滿意,進行下一步;否則重建。

    Python

    import requests
    import base64
    import os
    
    def create_voice_and_play():
        # 新加坡和北京地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
        # 若沒有配置環境變數,請用百鍊API Key將下行替換為:api_key = "sk-xxx"
        api_key = os.getenv("DASHSCOPE_API_KEY")
        
        if not api_key:
            print("錯誤: 未找到DASHSCOPE_API_KEY環境變數,請先設定API Key")
            return None, None, None
        
        # 準備請求資料
        headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
        
        data = {
            "model": "voice-enrollment",
            "input": {
                "action": "create_voice",
                "target_model": "cosyvoice-v3.5-plus",
                "voice_prompt": "A composed middle-aged male announcer with a deep, rich and magnetic voice, a steady speaking speed and clear articulation, is suitable for news broadcasting or documentary commentary.",
                "preview_text": "Dear listeners, hello everyone. Welcome to the evening news.",
                "prefix": "announcer"
            },
            "parameters": {
                "sample_rate": 24000,
                "response_format": "wav"
            }
        }
        
        # 以下為新加坡地區url,若使用北京地區的模型,需將url替換為:https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization
        url = "https://dashscope-intl.aliyuncs.com/api/v1/services/audio/tts/customization"
        
        try:
            # 發送請求
            response = requests.post(
                url,
                headers=headers,
                json=data,
                timeout=60  # 添加逾時設定
            )
            
            if response.status_code == 200:
                result = response.json()
                
                # 擷取音色ID
                voice_id = result["output"]["voice_id"]
                print(f"音色ID: {voice_id}")
                
                # 擷取預覽音頻資料
                base64_audio = result["output"]["preview_audio"]["data"]
                
                # 解碼Base64音頻資料
                audio_bytes = base64.b64decode(base64_audio)
                
                # 儲存音頻檔案到本地
                filename = f"{voice_id}_preview.wav"
                
                # 將音頻資料寫入本地檔案
                with open(filename, 'wb') as f:
                    f.write(audio_bytes)
                
                print(f"音頻已儲存到本地檔案: {filename}")
                print(f"檔案路徑: {os.path.abspath(filename)}")
                
                return voice_id, audio_bytes, filename
            else:
                print(f"請求失敗,狀態代碼: {response.status_code}")
                print(f"響應內容: {response.text}")
                return None, None, None
                
        except requests.exceptions.RequestException as e:
            print(f"網路請求發生錯誤: {e}")
            return None, None, None
        except KeyError as e:
            print(f"響應資料格式錯誤,缺少必要的欄位: {e}")
            print(f"響應內容: {response.text if 'response' in locals() else 'No response'}")
            return None, None, None
        except Exception as e:
            print(f"發生未知錯誤: {e}")
            return None, None, None
    
    if __name__ == "__main__":
        print("開始建立語音...")
        voice_id, audio_data, saved_filename = create_voice_and_play()
        
        if voice_id:
            print(f"\n成功建立音色 '{voice_id}'")
            print(f"音頻檔案已儲存: '{saved_filename}'")
            print(f"檔案大小: {os.path.getsize(saved_filename)} 位元組")
        else:
            print("\n音色建立失敗")

    Java

    需要匯入Gson依賴,若是使用Maven或者Gradle,添加依賴方式如下:

    Maven

    pom.xml中添加如下內容:

    <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.13.1</version>
    </dependency>

    Gradle

    build.gradle中添加如下內容:

    // https://mvnrepository.com/artifact/com.google.code.gson/gson
    implementation("com.google.code.gson:gson:2.13.1")
    import com.google.gson.JsonObject;
    import com.google.gson.JsonParser;
    import java.io.*;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.Base64;
    
    public class Main {
        public static void main(String[] args) {
            Main example = new Main();
            example.createVoice();
        }
    
        public void createVoice() {
            // 新加坡和北京地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
            // 若沒有配置環境變數,請用百鍊API Key將下行替換為:String apiKey = "sk-xxx"
            String apiKey = System.getenv("DASHSCOPE_API_KEY");
    
            // 建立JSON請求體字串
            String jsonBody = "{\n" +
                    "    \"model\": \"voice-enrollment\",\n" +
                    "    \"input\": {\n" +
                    "        \"action\": \"create_voice\",\n" +
                    "        \"target_model\": \"cosyvoice-v3.5-plus\",\n" +
                    "        \"voice_prompt\": \"A composed middle-aged male announcer with a deep, rich and magnetic voice, a steady speaking speed and clear articulation, is suitable for news broadcasting or documentary commentary.\",\n" +
                    "        \"preview_text\": \"Dear listeners, hello everyone. Welcome to the evening news.\",\n" +
                    "        \"prefix\": \"announcer\"\n" +
                    "    },\n" +
                    "    \"parameters\": {\n" +
                    "        \"sample_rate\": 24000,\n" +
                    "        \"response_format\": \"wav\"\n" +
                    "    }\n" +
                    "}";
    
            HttpURLConnection connection = null;
            try {
                // 以下為新加坡地區url,若使用北京地區的模型,需將url替換為:https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization
                URL url = new URL("https://dashscope-intl.aliyuncs.com/api/v1/services/audio/tts/customization");
                connection = (HttpURLConnection) url.openConnection();
    
                // 佈建要求方法和頭部
                connection.setRequestMethod("POST");
                connection.setRequestProperty("Authorization", "Bearer " + apiKey);
                connection.setRequestProperty("Content-Type", "application/json");
                connection.setDoOutput(true);
                connection.setDoInput(true);
    
                // 發送請求體
                try (OutputStream os = connection.getOutputStream()) {
                    byte[] input = jsonBody.getBytes("UTF-8");
                    os.write(input, 0, input.length);
                    os.flush();
                }
    
                // 擷取響應
                int responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    // 讀取響應內容
                    StringBuilder response = new StringBuilder();
                    try (BufferedReader br = new BufferedReader(
                            new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
                        String responseLine;
                        while ((responseLine = br.readLine()) != null) {
                            response.append(responseLine.trim());
                        }
                    }
    
                    // 解析JSON響應
                    JsonObject jsonResponse = JsonParser.parseString(response.toString()).getAsJsonObject();
                    JsonObject outputObj = jsonResponse.getAsJsonObject("output");
                    JsonObject previewAudioObj = outputObj.getAsJsonObject("preview_audio");
    
                    // 擷取音色名稱
                    String voiceId = outputObj.get("voice_id").getAsString();
                    System.out.println("音色ID: " + voiceId);
    
                    // 擷取Base64編碼的音頻資料
                    String base64Audio = previewAudioObj.get("data").getAsString();
    
                    // 解碼Base64音頻資料
                    byte[] audioBytes = Base64.getDecoder().decode(base64Audio);
    
                    // 儲存音頻到本地檔案
                    String filename = voiceId + "_preview.wav";
                    saveAudioToFile(audioBytes, filename);
    
                    System.out.println("音頻已儲存到本地檔案: " + filename);
    
                } else {
                    // 讀取錯誤響應
                    StringBuilder errorResponse = new StringBuilder();
                    try (BufferedReader br = new BufferedReader(
                            new InputStreamReader(connection.getErrorStream(), "UTF-8"))) {
                        String responseLine;
                        while ((responseLine = br.readLine()) != null) {
                            errorResponse.append(responseLine.trim());
                        }
                    }
    
                    System.out.println("請求失敗,狀態代碼: " + responseCode);
                    System.out.println("錯誤響應: " + errorResponse.toString());
                }
    
            } catch (Exception e) {
                System.err.println("請求發生錯誤: " + e.getMessage());
                e.printStackTrace();
            } finally {
                if (connection != null) {
                    connection.disconnect();
                }
            }
        }
    
        private void saveAudioToFile(byte[] audioBytes, String filename) {
            try {
                File file = new File(filename);
                try (FileOutputStream fos = new FileOutputStream(file)) {
                    fos.write(audioBytes);
                }
                System.out.println("音頻已儲存到: " + file.getAbsolutePath());
            } catch (IOException e) {
                System.err.println("儲存音頻檔案時發生錯誤: " + e.getMessage());
                e.printStackTrace();
            }
        }
    }
  2. 使用上一步產生的專屬音色進行語音合成。

    這裡參考了非流式調用範例程式碼,將voice參數替換為聲音設計產生的專屬音色進行語音合成。

    關鍵原則:聲音設計時使用的模型 (target_model) 必須與後續進行語音合成時使用的模型 (model) 保持一致,否則會導致合成失敗。

    Python

    # coding=utf-8
    
    import dashscope
    from dashscope.audio.tts_v2 import *
    import os
    
    # 新加坡地區和北京地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
    # 若沒有配置環境變數,請用百鍊API Key將下行替換為:dashscope.api_key = "sk-xxx"
    dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')
    
    # 以下為新加坡地區url,若使用北京地區的模型,需將url替換為:wss://dashscope.aliyuncs.com/api-ws/v1/inference
    dashscope.base_websocket_api_url='wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference'
    
    # 聲音設計、語音合成要使用相同的模型
    model = "cosyvoice-v3.5-plus"
    # 將voice參數替換為聲音設計產生的專屬音色
    voice = "your_voice"
    
    # 執行個體化SpeechSynthesizer,並在構造方法中傳入模型(model)、音色(voice)等請求參數
    synthesizer = SpeechSynthesizer(model=model, voice=voice)
    # 發送待合成文本,擷取二進位音頻
    audio = synthesizer.call("今天天氣怎麼樣?")
    # 首次發送文本時需建立 WebSocket 串連,因此首包延遲會包含串連建立的耗時
    print('[Metric] requestId為:{},首包延遲為:{}毫秒'.format(
        synthesizer.get_last_request_id(),
        synthesizer.get_first_package_delay()))
    
    # 將音頻儲存至本地
    with open('output.mp3', 'wb') as f:
        f.write(audio)

    Java

    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 {
        // 聲音設計、語音合成要使用相同的模型
        private static String model = "cosyvoice-v3.5-plus";
        // 將voice參數替換為聲音設計產生的專屬音色
        private static String voice = "your_voice_id";
    
        public static void streamAudioDataToSpeaker() {
            // 請求參數
            SpeechSynthesisParam param =
                    SpeechSynthesisParam.builder()
                            // 新加坡地區和北京地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
                            // 若沒有配置環境變數,請用百鍊API Key將下行替換為:.apiKey("sk-xxx")
                            .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                            .model(model) // 模型
                            .voice(voice) // 音色
                            .build();
    
            // 同步模式:禁用回調(第二個參數為null)
            SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, null);
            ByteBuffer audio = null;
            try {
                // 阻塞直至音頻返回
                audio = synthesizer.call("今天天氣怎麼樣?");
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                // 任務結束關閉websocket串連
                synthesizer.getDuplexApi().close(1000, "bye");
            }
            if (audio != null) {
                // 將音頻資料儲存到本地檔案“output.mp3”中
                File file = new File("output.mp3");
                // 首次發送文本時需建立 WebSocket 串連,因此首包延遲會包含串連建立的耗時
                System.out.println(
                        "[Metric] requestId為:"
                                + synthesizer.getLastRequestId()
                                + "首包延遲(毫秒)為:"
                                + 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) {
            // 以下為新加坡地區url,若使用北京地區的模型,需將url替換為:wss://dashscope.aliyuncs.com/api-ws/v1/inference
            Constants.baseWebsocketApiUrl = "wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference";
            streamAudioDataToSpeaker();
            System.exit(0);
        }
    }

聲音複刻:輸入音頻格式

重要

新加坡地區不支援該功能。

高品質的輸入音頻是獲得優質複刻效果的基礎。

專案

要求

支援格式

WAV (16bit), MP3, M4A

音頻時間長度

推薦10~20秒,最長不得超過60秒

檔案大小

≤ 10 MB

採樣率

≥ 16 kHz

聲道

單聲道 / 雙聲道,雙聲道音頻僅處理首聲道,請確保首聲道包含有效人聲

內容

音頻必須包含至少5秒連續清晰朗讀(無背景音),其餘部分僅允許短暫停頓(≤2秒);整段音頻應避免背景音樂、噪音或其他人聲,確保核心朗讀內容品質;請使用正常說話音頻作為輸入,不要上傳歌曲或唱歌音頻,以確保複刻效果準確和可用。

聲音設計:如何編寫高品質的聲音描述?

重要

新加坡地區不支援該功能。

要求與限制

在編寫聲音描述(voice_prompt)時,請務必遵循以下技術約束:

  • 長度限制:voice_prompt 的內容長度不得超過 500 個字元。

  • 支援語言:描述文本僅支援中文和英文。

核心原則

高品質的聲音描述(voice_prompt)是成功建立理想音色的關鍵。它如同聲音設計的“藍圖”,直接指導模型產生具有特定特徵的聲音。

請遵循以下核心原則對聲音進行描述:

  1. 具體而非模糊:使用能夠描繪具體聲音特質的詞語,如“低沉”、“清脆”、“語速偏快”。避免使用“好聽”、“普通”等主觀且缺乏資訊量的詞彙。

  2. 多維而非單一:優秀的描述通常結合多個維度(如下文所述的性別、年齡、情感等)。單一維度描述(如僅“女聲”)過於寬泛,難以產生特色鮮明的音色。

  3. 客觀而非主觀:專註於聲音本身的物理和感知特徵,而不是個人的喜好。例如,用“音調偏高,帶有活力”代替“我最喜歡的聲音”。

  4. 原創而非模仿:請描述聲音的特質,而不是要求模仿特定人物(如名人、演員)。此類請求涉及著作權風險且模型不支援直接模仿。

  5. 簡潔而非冗餘:確保每個詞都有其意義。避免重複使用同義字或無意義的強調詞(如“非常非常棒的聲音”)。

描述維度參考

維度

描述樣本

性別

男性、女性、中性

年齡

兒童 (5-12歲)、青少年 (13-18歲)、青年 (19-35歲)、中年 (36-55歲)、老年 (55歲以上)

音調

高音、中音、低音、偏高、偏低

語速

快速、中速、緩慢、偏快、偏慢

情感

開朗、沉穩、溫柔、嚴肅、活潑、冷靜、治癒

特點

有磁性、清脆、沙啞、圓潤、甜美、渾厚、有力

用途

新聞播報、廣告配音、有聲書、動畫角色、語音助手、紀錄片解說

樣本對比

✅ 推薦樣本

  • “年輕活潑的女性聲音,語速較快,帶有明顯的上揚語調,適合介紹時尚產品。”

    分析:結合了年齡、性格、語速和語調,並指明了適用情境,形象立體。

  • “沉穩的中年男性,語速緩慢,音色低沉有磁性,適合朗讀新聞或紀錄片解說。”

    分析:清晰定義了性別、年齡段、語速、音色特點和應用領域。

  • “可愛的兒童聲音,大約8歲女孩,說話略帶稚氣,適合動畫角色配音。”

    分析:精確到具體年齡和聲音特質(稚氣),目標明確。

  • “溫柔知性的女性,30歲左右,語調平和,適合有聲書朗讀。”

    分析:通過“知性”、“平和”等詞彙,有效傳遞了聲音的情感和風格。

❌ 不推薦樣本與改進建議

不推薦樣本

主要問題

改進建議

好聽的聲音

過於模糊,主觀性強,缺乏可執行檔特徵。

添加具體維度,如:“聲線清澈的青年女聲,語調溫柔”。

像某明星的聲音

涉及著作權風險,模型無法直接模仿。

提取其聲音特質進行描述,如:“聲音成熟、富有磁性、語速沉穩的男聲”。

非常非常非常好聽的女聲

資訊冗餘,重複詞彙無助於定義音色。

移除重複詞,並增加有效描述,如:“一個20~24歲,語氣輕快、音調活潑、音色甜美的女聲”。

123456

無效輸入,無法解析為聲音特徵。

請提供有意義的文本描述,參考上方的推薦樣本。

API參考

模型功能特性對比

國際

國際部署模式下,存取點與資料存放區均位於新加坡地區,模型推理計算資源在全球範圍內動態調度(不含中國內地)。

功能/特性

cosyvoice-v3-plus

cosyvoice-v3-flash

支援語言

系統音色而異:中文(普通話、東北話、閩南話、陝西話)、英文、日語、韓語

系統音色而異:中文(普通話)、英文

音頻格式

pcm、wav、mp3、opus

音頻採樣率

8kHz、16kHz、22.05kHz、24kHz、44.1kHz、48kHz

聲音複刻

不支援

聲音設計

不支援

SSML

支援

該功能適用於複刻音色,以及音色列表中已標記為支援 SSML 的系統音色
使用方法請參見SSML標記語言介紹

LaTeX

支援

使用方法請參見LaTeX 方程式轉語音

音量大小

支援

使用方法請參見請求參數volume

語速調節

支援

使用方法請參見請求參數speech_rate
在 Java SDK 中,該參數為speechRate

語調(音高)調節

支援

使用方法請參見請求參數pitch_rate
在 Java SDK 中,該參數為pitchRate

碼率調節

支援

僅opus格式音頻支援該功能
使用方法請參見請求參數bit_rate
在 Java SDK 中,該參數為pitchRate

時間戳記

支援 預設關閉,可開啟

該功能適用於複刻音色,以及音色列表中已標記為支援時間戳記的系統音色
使用方法請參見請求參數word_timestamp_enabled
在 Java SDK 中,該參數為enableWordTimestamp

指令控制(Instruct)

不支援

支援

該功能適用音色列表中已標記為支援 Instruct 的系統音色
使用方法請參見請求參數instruction

流式輸入

支援

流式輸出

支援

限流(RPS)

3

接入方式

Java/Python SDK、WebSocket API

價格

$0.26/萬字元

$0.13/萬字元

中國內地

中國內地部署模式下,存取點與資料存放區均位於北京地區,模型推理計算資源僅限於中國內地。

功能/特性

cosyvoice-v3.5-plus

cosyvoice-v3.5-flash

cosyvoice-v3-plus

cosyvoice-v3-flash

cosyvoice-v2

支援語言

無系統音色,複刻音色支援如下語言:中文(普通話、廣東話、河南話、湖北話、閩南話、寧夏話、陝西話、山東話、上海話、四川話)、英文、法語、德語、日語、韓語、俄語、葡萄牙語、泰語、印尼語、越南語

聲音設計音色支援如下語言:中文(普通話)、英文

系統音色(因音色而異):中文(普通話、東北話、閩南話、陝西話)、英文、日語、韓語

複刻音色:中文(普通話)、英文、法語、德語、日語、韓語、俄語

系統音色(因音色而異):中文(普通話)、英文

複刻音色:中文(普通話、廣東話、東北話、甘肅話、貴州話、河南話、湖北話、江西話、閩南話、寧夏話、山西話、陝西話、山東話、上海話、四川話、天津話、雲南話)、英文、法語、德語、日語、韓語、俄語、葡萄牙語、泰語、印尼語、越南語

系統音色(因音色而異):中文(普通話)、英文、韓語、日語

複刻音色:中文(普通話)、英文

音頻格式

pcm、wav、mp3、opus

音頻採樣率

8kHz、16kHz、22.05kHz、24kHz、44.1kHz、48kHz

聲音複刻

支援

使用方法請參見CosyVoice聲音複刻/設計API
聲音複刻支援的語言如下:
cosyvoice-v2:中文(普通話)、英文
cosyvoice-v3-flash:中文(普通話、廣東話、東北話、甘肅話、貴州話、河南話、湖北話、江西話、閩南話、寧夏話、山西話、陝西話、山東話、上海話、四川話、天津話、雲南話)、英文、法語、德語、日語、韓語、俄語、葡萄牙語、泰語、印尼語、越南語
cosyvoice-v3-plus:中文(普通話)、英文、法語、德語、日語、韓語、俄語
cosyvoice-v3.5-plus、cosyvoice-v3.5-flash:中文(普通話、廣東話、河南話、湖北話、閩南話、寧夏話、陝西話、山東話、上海話、四川話)、英文、法語、德語、日語、韓語、俄語、葡萄牙語、泰語、印尼語、越南語

聲音設計

支援

使用方法請參見CosyVoice聲音複刻/設計API
聲音設計支援的語言:中文、英文

不支援

SSML

支援

該功能適用於複刻音色,以及音色列表中已標記為支援 SSML 的系統音色
使用方法請參見SSML標記語言介紹

LaTeX

支援

使用方法請參見LaTeX 方程式轉語音

音量大小

支援

使用方法請參見請求參數volume

語速調節

支援

使用方法請參見請求參數speech_rate
在 Java SDK 中,該參數為speechRate

語調(音高)調節

支援

使用方法請參見請求參數pitch_rate
在 Java SDK 中,該參數為pitchRate

碼率調節

支援

僅opus格式音頻支援該功能
使用方法請參見請求參數bit_rate
在 Java SDK 中,該參數為pitchRate

時間戳記

支援 預設關閉,可開啟

該功能適用於複刻音色,以及音色列表中已標記為支援時間戳記的系統音色
使用方法請參見請求參數word_timestamp_enabled
在 Java SDK 中,該參數為enableWordTimestamp

指令控制(Instruct)

支援

該功能適用於複刻音色,以及音色列表中已標記為支援 Instruct 的系統音色
適合視頻配音、有聲書等表現力誇張的情境,若還原原始音色韻律,則無需開啟
Instruct指令與音色原本風格衝突時,可能會無法生效(如:對開心的音色,使用悲傷的指令)
使用方法請參見請求參數instruction

不支援

支援

該功能適用於複刻音色,以及音色列表中已標記為支援 Instruct 的系統音色
使用方法請參見請求參數instruction

不支援

流式輸入

支援

流式輸出

支援

限流(RPS)

3

接入方式

Java/Python SDK、WebSocket API

價格

$0.22/萬字元

$0.116/萬字元

$0.286706/萬字元

$0.14335/萬字元

$0.286706/萬字元

支援的系統音色

CosyVoice音色列表

常見問題

Q:語音合成的發音讀錯怎麼辦?多音字如何控制發音?

  • 將多音字替換成同音的其他漢字,快速解決發音問題。

  • 使用SSML標記語言控制發音。

Q:使用複刻音色產生的音頻無聲音如何排查?

  1. 確認音色狀態

    調用CosyVoice聲音複刻/設計API介面,查看音色status是否為OK

  2. 檢查模型版本一致性

    確保複刻音色時使用的target_model參數與語音合成時的model參數完全一致。例如:

    • 複刻時使用cosyvoice-v3-plus

    • 合成時也必須使用cosyvoice-v3-plus

  3. 驗證源音頻品質

    檢查複刻音色時使用的源音頻是否符合CosyVoice聲音複刻/設計API

    • 音頻時間長度:10-20秒

    • 音質清晰

    • 無背景雜音

  4. 檢查請求參數

    確認語音合成時請求參數voice設定為複刻音色的ID。

Q:聲音複刻後合成效果不穩定或語音不完整如何處理?

如果複刻音色後合成的語音出現以下問題:

  • 語音播放不完整,唯讀出部分文字

  • 合成效果不穩定,時好時壞

  • 語音中包含異常停頓或靜音段

可能原因:源音頻品質不符合要求

解決方案:檢查源音頻是否符合如下要求,建議按照錄音操作指南重新錄製

  • 檢查音頻連續性:確保源音頻中語音內容連續,避免長時間停頓或靜音段(超過2秒)。如果音頻中存在明顯的空白段,會導致模型將靜音或雜訊作為音色特徵的一部分,影響產生效果

  • 檢查語音活動比例:確保有效語音占音頻總時間長度的60%以上。如果背景雜訊、非語音段過多,會干擾音色特徵提取

  • 驗證音頻品質細節:

    • 音頻時間長度:10-20秒(推薦15秒左右)

    • 發音清晰,語速平穩

    • 無背景雜音、迴音、雜音

    • 語音能量集中,無長時間靜音段