全部產品
Search
文件中心

Alibaba Cloud Model Studio:語音合成CosyVoice Java SDK

更新時間:Jan 27, 2026

本文介紹語音合成CosyVoice Java SDK的參數和介面細節。

重要

如需使用“中國內地(北京)”地區的模型,請前往“中國內地(北京)”地區的API-KEY頁面

使用者指南:關於模型介紹和選型建議請參見即時語音合成-CosyVoice/Sambert

前提條件

  • 已開通服務並擷取API Key。請配置API Key到環境變數(準備下線,併入配置 API Key),而非寫入程式碼在代碼中,防範因代碼泄露導致的安全風險。

    說明

    當您需要為第三方應用或使用者提供臨時存取權限,或者希望嚴格控制敏感性資料訪問、刪除等高風險操作時,建議使用臨時鑒權Token

    與長期有效 API Key 相比,臨時鑒權 Token 具備時效性短(60秒)、安全性高的特點,適用於臨時調用情境,能有效降低API Key泄露的風險。

    使用方式:在代碼中,將原本用於鑒權的 API Key 替換為擷取到的臨時鑒權 Token 即可。

  • 安裝最新版DashScope SDK

模型與價格

模型名稱

單價

免費額度(注)

cosyvoice-v3-plus

$0.286706/萬字元

無免費額度

cosyvoice-v3-flash

$0.14335/萬字元

cosyvoice-v2

$0.286706/萬字元

語音合成文本限制與格式規範

文本長度限制

  • 非流式調用單向流式調用或Flowable單向流式調用:單次發送文本長度不得超過 20000 字元。

  • 雙向流式調用或Flowable雙向流式調用:單次發送文本長度不得超過 20000 字元,且累計發送文本總長度不得超過 20 萬字元。

字元計算規則

  • 漢字(包括簡/繁體漢字、日文漢字和韓文漢字)按2個字元計算,其他所有字元(如標點符號、字母、數字、日韓文假名/諺文等)均按 1個字元計算

  • 計算文本長度時,不包含SSML 標籤內容

  • 樣本:

    • "你好" → 2(你)+2(好)=4字元

    • "中A文123" → 2(中)+1(A)+2(文)+1(1)+1(2)+1(3)=8字元

    • "中文。" → 2(中)+2(文)+1(。)=5字元

    • "中 文。" → 2(中)+1(空格)+2(文)+1(。)=6字元

    • "<speak>你好</speak>" → 2(你)+2(好)=4字元

編碼格式

需採用UTF-8編碼。

數學運算式支援說明

當前數學運算式解析功能僅適用於cosyvoice-v2cosyvoice-v3-flashcosyvoice-v3-plus模型,支援識別中小學常見的數學運算式,包括但不限於基礎運算、代數、幾何等內容。

詳情請參見LaTeX 方程式轉語音

SSML標記語言支援說明

當前SSML(Speech Synthesis Markup Language,語音合成標記語言)功能僅適用於cosyvoice-v3-flash、cosyvoice-v3-plus和cosyvoice-v2模型的複刻音色,以及音色列表中標記為支援的系統音色,使用時需滿足以下條件:

快速開始

SpeechSynthesizer類提供了語音合成的關鍵介面,支援以下幾種調用方式:

  • 非流式調用:阻塞式,一次性發送完整文本,直接返回完整音頻。適合短文本語音合成情境。

  • 單向流式調用:非阻塞式,一次性發送完整文本,通過回呼函數接收音頻資料(可能分區)。適用於對即時性要求高的短文本語音合成情境。

  • 雙向流式調用:非阻塞式,可分多次發送文本片段,通過回呼函數即時接收增量合成的音頻流。適合即時性要求高的長文本語音合成情境。

非流式調用

同步提交語音合成任務,直接擷取完整結果。

image

執行個體化SpeechSynthesizer類綁定請求參數,調用call方法進行合成並擷取二進位音頻資料。

發送的文本長度不得超過2000字元(詳情請參見SpeechSynthesizer類call方法)。

重要

每次調用call方法前,需要重新初始化SpeechSynthesizer執行個體。

點擊查看完整樣本

import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesisParam;
import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesizer;

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-flash";
    // 音色
    private static String voice = "longanyang";

    public static void streamAudioDataToSpeaker() {
        // 請求參數
        SpeechSynthesisParam param =
                SpeechSynthesisParam.builder()
                        // 若沒有將API Key配置到環境變數中,需將下面這行代碼注釋放開,並將your-api-key替換為自己的API Key
                        // .apiKey("your-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) {
        streamAudioDataToSpeaker();
        System.exit(0);
    }
}

單向流式調用

非同步提交語音合成任務,通過註冊ResultCallback回調,逐幀接收即時語音分段資料。

image

執行個體化SpeechSynthesizer類綁定請求參數回調介面(ResultCallback),調用call方法進行合成並通過回調介面(ResultCallback)onEvent方法即時擷取合成結果。

發送的文本長度不得超過2000字元(詳情請參見SpeechSynthesizer類call方法)。

重要

每次調用call方法前,需要重新初始化SpeechSynthesizer執行個體。

點擊查看完整樣本

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 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 {
    // 模型
    private static String model = "cosyvoice-v3-flash";
    // 音色
    private static String voice = "longanyang";

    public static void streamAudioDataToSpeaker() {
        CountDownLatch latch = new CountDownLatch(1);

        // 實現回調介面ResultCallback
        ResultCallback<SpeechSynthesisResult> callback = new ResultCallback<SpeechSynthesisResult>() {
            @Override
            public void onEvent(SpeechSynthesisResult result) {
                // System.out.println("收到訊息: " + result);
                if (result.getAudioFrame() != null) {
                    // 此處實現儲存音頻資料到本地的邏輯
                    System.out.println(TimeUtils.getTimestamp() + " 收到音頻");
                }
            }

            @Override
            public void onComplete() {
                System.out.println(TimeUtils.getTimestamp() + " 收到Complete,語音合成結束");
                latch.countDown();
            }

            @Override
            public void onError(Exception e) {
                System.out.println("出現異常:" + e.toString());
                latch.countDown();
            }
        };

        // 請求參數
        SpeechSynthesisParam param =
                SpeechSynthesisParam.builder()
                        // 若沒有將API Key配置到環境變數中,需將下面這行代碼注釋放開,並將your-api-key替換為自己的API Key
                        // .apiKey("your-api-key")
                        .model(model) // 模型
                        .voice(voice) // 音色
                        .build();
        // 第二個參數“callback”傳入回調即啟用非同步模式
        SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, callback);
        // 非阻塞調用,立即返回null(實際結果通過回調介面非同步傳遞),在回調介面的onEvent方法中即時擷取二進位音頻
        try {
            synthesizer.call("今天天氣怎麼樣?");
            // 等待合成完成
            latch.await();
            // 等待播放線程全部播放完
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            // 任務結束後關閉websocket串連
            synthesizer.getDuplexApi().close(1000, "bye");
        }
        // 首次發送文本時需建立 WebSocket 串連,因此首包延遲會包含串連建立的耗時
        System.out.println(
                "[Metric] requestId為:"
                        + synthesizer.getLastRequestId()
                        + ",首包延遲(毫秒)為:"
                        + synthesizer.getFirstPackageDelay());
    }

    public static void main(String[] args) {
        streamAudioDataToSpeaker();
        System.exit(0);
    }
}

雙向流式調用

分多次提交文本,通過註冊ResultCallback回調,逐幀接收即時語音分段資料。

說明
  • 流式輸入時可多次調用streamingCall按順序提交文本片段。服務端接收文本片段後自動進行分句:

    • 完整語句立即合成

    • 不完整語句緩衝至完整後合成

    調用 streamingComplete 時,服務端會強制合成所有已接收但未處理的文本片段(包括未完成的句子)。

  • 發送文本片段的間隔不得超過23秒,否則觸發“request timeout after 23 seconds”異常。

    若無待發送文本,需及時調用 streamingComplete結束任務。

    服務端強制設定23秒逾時機制,用戶端無法修改該配置。
image
  1. 執行個體化SpeechSynthesizer類

    執行個體化SpeechSynthesizer類綁定請求參數回調介面(ResultCallback)

  2. 串流

    多次調用SpeechSynthesizer類streamingCall方法分區提交待合成文本,將待合成文本分段發送至服務端。

    在發送文本的過程中,服務端會通過回調介面(ResultCallback)onEvent方法,將合成結果即時返回給用戶端。

    每次調用streamingCall方法發送的文本片段(即text)長度不得超過2000字元,累計發送的文本總長度不得超過20萬字元。

  3. 結束處理

    調用SpeechSynthesizer類streamingComplete方法結束語音合成。

    該方法會阻塞當前線程,直到回調介面(ResultCallback)onComplete或者onError回調觸發後才會釋放線程阻塞。

    請務必確保調用該方法,否則可能會導致結尾部分的文本無法成功轉換為語音。

點擊查看完整樣本

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 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 {
    private static String[] textArray = {"流式文本語音合成SDK,",
            "可以將輸入的文本", "合成為語音位元據,", "相比於非流式語音合成,",
            "流式合成的優勢在於即時性", "更強。使用者在輸入文本的同時",
            "可以聽到接近同步的語音輸出,", "極大地提升了互動體驗,",
            "減少了使用者等待時間。", "適用於調用大規模", "語言模型(LLM),以",
            "流式輸入文本的方式", "進行語音合成的情境。"};
    private static String model = "cosyvoice-v3-flash"; // 模型
    private static String voice = "longanyang"; // 音色

    public static void streamAudioDataToSpeaker() {
        // 配置回呼函數
        ResultCallback<SpeechSynthesisResult> callback = new ResultCallback<SpeechSynthesisResult>() {
            @Override
            public void onEvent(SpeechSynthesisResult result) {
                // System.out.println("收到訊息: " + result);
                if (result.getAudioFrame() != null) {
                    // 此處實現處理音頻資料的邏輯
                    System.out.println(TimeUtils.getTimestamp() + " 收到音頻");
                }
            }

            @Override
            public void onComplete() {
                System.out.println(TimeUtils.getTimestamp() + " 收到Complete,語音合成結束");
            }

            @Override
            public void onError(Exception e) {
                System.out.println("出現異常:" + e.toString());
            }
        };

        // 請求參數
        SpeechSynthesisParam param =
                SpeechSynthesisParam.builder()
                        // 若沒有將API Key配置到環境變數中,需將下面這行代碼注釋放開,並將your-api-key替換為自己的API Key
                        // .apiKey("your-api-key")
                        .model(model)
                        .voice(voice)
                        .format(SpeechSynthesisAudioFormat
                                .PCM_22050HZ_MONO_16BIT) // 流式合成使用PCM或者MP3
                        .build();
        SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, callback);
        // 帶Callback的call方法將不會阻塞當前線程
        try {
            for (String text : textArray) {
                // 發送文本片段,在回調介面的onEvent方法中即時擷取二進位音頻
                synthesizer.streamingCall(text);
            }
            // 等待結束流式語音合成
            synthesizer.streamingComplete();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            // 任務結束關閉websocket串連
            synthesizer.getDuplexApi().close(1000, "bye");
        }

        // 首次發送文本時需建立 WebSocket 串連,因此首包延遲會包含串連建立的耗時
        System.out.println(
                "[Metric] requestId為:"
                        + synthesizer.getLastRequestId()
                        + ",首包延遲(毫秒)為:"
                        + synthesizer.getFirstPackageDelay());
    }

    public static void main(String[] args) {
        streamAudioDataToSpeaker();
        System.exit(0);
    }
}

通過Flowable調用

Flowable是一個用於工作流程和商務程序管理的開源架構,它基於Apache 2.0許可證發布。關於Flowable的使用,請參見Flowable API詳情

使用Flowable前需確保已整合RxJava庫,並瞭解響應式編程基礎概念。

單向流式調用

以下樣本展示了通過Flowable對象的blockingForEach介面,阻塞式地擷取每次流式返回的SpeechSynthesisResult類型資料。

您也可以在Flowable的所有流式資料返回完成後,通過SpeechSynthesizer類getAudioData來擷取完整的合成結果。

點擊查看完整樣本

import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesisParam;
import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesizer;
import com.alibaba.dashscope.exception.NoApiKeyException;

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 = "cosyvoice-v3-flash"; // 模型
    private static String voice = "longanyang"; // 音色

    public static void streamAudioDataToSpeaker() throws NoApiKeyException {
        // 請求參數
        SpeechSynthesisParam param =
                SpeechSynthesisParam.builder()
                        // 若沒有將API Key配置到環境變數中,需將下面這行代碼注釋放開,並將your-api-key替換為自己的API Key
                        // .apiKey("your-api-key")
                        .model(model) // 模型
                        .voice(voice) // 音色
                        .build();
        SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, null);
        synthesizer.callAsFlowable("今天天氣怎麼樣?").blockingForEach(result -> {
            // System.out.println("收到訊息: " + result);
            if (result.getAudioFrame() != null) {
                // 此處實現處理音頻資料的邏輯
                System.out.println(TimeUtils.getTimestamp() + " 收到音頻");
            }
        });
        // 任務結束關閉 WebSocket 串連
        synthesizer.getDuplexApi().close(1000, "bye");
        // 首次發送文本時需建立 WebSocket 串連,因此首包延遲會包含串連建立的耗時
        System.out.println(
                "[Metric] requestId為:"
                        + synthesizer.getLastRequestId()
                        + "首包延遲(毫秒)為:"
                        + synthesizer.getFirstPackageDelay());
    }

    public static void main(String[] args) throws NoApiKeyException {
        streamAudioDataToSpeaker();
        System.exit(0);
    }
}

雙向流式調用

以下樣本展示了通過Flowable對象作為輸入參數,輸入文字資料流。並通過Flowable對象作為傳回值,利用的blockingForEach介面,阻塞式地擷取每次流式返回的SpeechSynthesisResult類型資料。

您也可以在Flowable的所有流式資料返回完成後,通過SpeechSynthesizer類getAudioData來擷取完整的合成結果。

點擊查看完整樣本

import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesisParam;
import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesizer;
import com.alibaba.dashscope.exception.NoApiKeyException;
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 = {"流式文本語音合成SDK,",
            "可以將輸入的文本", "合成為語音位元據,", "相比於非流式語音合成,",
            "流式合成的優勢在於即時性", "更強。使用者在輸入文本的同時",
            "可以聽到接近同步的語音輸出,", "極大地提升了互動體驗,",
            "減少了使用者等待時間。", "適用於調用大規模", "語言模型(LLM),以",
            "流式輸入文本的方式", "進行語音合成的情境。"};
    private static String model = "cosyvoice-v3-flash";
    private static String voice = "longanyang";

    public static void streamAudioDataToSpeaker() throws NoApiKeyException {
        // 類比流式輸入
        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);

        // 請求參數
        SpeechSynthesisParam param =
                SpeechSynthesisParam.builder()
                        // 若沒有將API Key配置到環境變數中,需將下面這行代碼注釋放開,並將apiKey替換為自己的API Key
                        // .apiKey("yourApikey")
                        .model(model) // 模型
                        .voice(voice) // 音色
                        .build();
        SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, null);
        synthesizer.streamingCallAsFlowable(textSource).blockingForEach(result -> {
            if (result.getAudioFrame() != null) {
                // 此處實現播放音訊邏輯
                System.out.println(
                        TimeUtils.getTimestamp() +
                                " 二進位音頻大小為:" + result.getAudioFrame().capacity());
            }
        });
        synthesizer.getDuplexApi().close(1000, "bye");
        // 首次發送文本時需建立 WebSocket 串連,因此首包延遲會包含串連建立的耗時
        System.out.println(
                "[Metric] requestId為:"
                        + synthesizer.getLastRequestId()
                        + ",首包延遲(毫秒)為:"
                        + synthesizer.getFirstPackageDelay());
    }

    public static void main(String[] args) throws NoApiKeyException {
        streamAudioDataToSpeaker();
        System.exit(0);
    }
}

高並發調用

在DashScope Java SDK中,採用了OkHttp3的串連池技術,以減少重複建立串連的開銷。詳情請參見高並發情境

請求參數

通過SpeechSynthesisParam的鏈式方法配置模型、音色等參數。配置完成的參數對象傳入SpeechSynthesizer類的建構函式中使用。

點擊查看樣本

SpeechSynthesisParam param = SpeechSynthesisParam.builder()
    .model("cosyvoice-v3-flash") // 模型
    .voice("longanyang") // 音色
    .format(SpeechSynthesisAudioFormat.WAV_8000HZ_MONO_16BIT) // 音頻編碼格式、採樣率
    .volume(50) // 音量,取值範圍:[0, 100]
    .speechRate(1.0f) // 語速,取值範圍:[0.5, 2]
    .pitchRate(1.0f) // 語調,取值範圍:[0.5, 2]
    .build();

參數

類型

是否必須

說明

model

String

語音合成模型

不同模型版本需要使用對應版本的音色:

  • cosyvoice-v3-flash/cosyvoice-v3-plus:使用longanyang等音色。

  • cosyvoice-v2:使用longxiaochun_v2等音色。

  • 完整音色列表請參見音色列表

voice

String

語音合成所使用的音色。

支援系統音色和複刻音色:

  • 系統音色:參見音色列表

  • 複刻音色:通過聲音複刻功能定製。使用複刻音色時,請確保聲音複刻與語音合成使用同一帳號。詳細操作步驟請參見CosyVoice聲音複刻API

    使用聲音複刻產生的複刻音色時,本請求的model參數值,必須與建立該音色時所用的模型版本(即target_model參數)完全一致。

format

enum

音頻編碼格式及採樣率。

若未指定format,則合成音頻採樣率為22.05kHz,格式為mp3。

說明

預設採樣率代表當前音色的最佳採樣率,預設條件下預設按照該採樣率輸出,同時支援降採樣或升採樣。

可指定的音頻編碼格式及採樣率如下:

  • 所有模型均支援的音頻編碼格式及採樣率:

    • SpeechSynthesisAudioFormat.WAV_8000HZ_MONO_16BIT,代表音頻格式為wav,採樣率為8kHz

    • SpeechSynthesisAudioFormat.WAV_16000HZ_MONO_16BIT,代表音頻格式為wav,採樣率為16kHz

    • SpeechSynthesisAudioFormat.WAV_22050HZ_MONO_16BIT,代表音頻格式為wav,採樣率為22.05kHz

    • SpeechSynthesisAudioFormat.WAV_24000HZ_MONO_16BIT,代表音頻格式為wav,採樣率為24kHz

    • SpeechSynthesisAudioFormat.WAV_44100HZ_MONO_16BIT,代表音頻格式為wav,採樣率為44.1kHz

    • SpeechSynthesisAudioFormat.WAV_48000HZ_MONO_16BIT,代表音頻格式為wav,採樣率為48kHz

    • SpeechSynthesisAudioFormat.MP3_8000HZ_MONO_128KBPS,代表音頻格式為mp3,採樣率為8kHz

    • SpeechSynthesisAudioFormat.MP3_16000HZ_MONO_128KBPS,代表音頻格式為mp3,採樣率為16kHz

    • SpeechSynthesisAudioFormat.MP3_22050HZ_MONO_256KBPS,代表音頻格式為mp3,採樣率為22.05kHz

    • SpeechSynthesisAudioFormat.MP3_24000HZ_MONO_256KBPS,代表音頻格式為mp3,採樣率為24kHz

    • SpeechSynthesisAudioFormat.MP3_44100HZ_MONO_256KBPS,代表音頻格式為mp3,採樣率為44.1kHz

    • SpeechSynthesisAudioFormat.MP3_48000HZ_MONO_256KBPS,代表音頻格式為mp3,採樣率為48kHz

    • SpeechSynthesisAudioFormat.PCM_8000HZ_MONO_16BIT,代表音頻格式為pcm,採樣率為8kHz

    • SpeechSynthesisAudioFormat.PCM_16000HZ_MONO_16BIT,代表音頻格式為pcm,採樣率為16kHz

    • SpeechSynthesisAudioFormat.PCM_22050HZ_MONO_16BIT,代表音頻格式為pcm,採樣率為22.05kHz

    • SpeechSynthesisAudioFormat.PCM_24000HZ_MONO_16BIT,代表音頻格式為pcm,採樣率為24kHz

    • SpeechSynthesisAudioFormat.PCM_44100HZ_MONO_16BIT,代表音頻格式為pcm,採樣率為44.1kHz

    • SpeechSynthesisAudioFormat.PCM_48000HZ_MONO_16BIT,代表音頻格式為pcm,採樣率為48kHz

  • 音頻格式為opus時,支援通過bit_rate參數調整碼率。僅對2.21.0及之後版本的DashScope適用。

    • SpeechSynthesisAudioFormat.OGG_OPUS_8KHZ_MONO_32KBPS,代表音頻格式為opus,採樣率為8kHz,碼率為32kbps

    • SpeechSynthesisAudioFormat.OGG_OPUS_16KHZ_MONO_16KBPS,代表音頻格式為opus,採樣率為16kHz,碼率為16kbps

    • SpeechSynthesisAudioFormat.OGG_OPUS_16KHZ_MONO_32KBPS,代表音頻格式為opus,採樣率為16kHz,碼率為32kbps

    • SpeechSynthesisAudioFormat.OGG_OPUS_16KHZ_MONO_64KBPS,代表音頻格式為opus,採樣率為16kHz,碼率為64kbps

    • SpeechSynthesisAudioFormat.OGG_OPUS_24KHZ_MONO_16KBPS,代表音頻格式為opus,採樣率為24kHz,碼率為16kbps

    • SpeechSynthesisAudioFormat.OGG_OPUS_24KHZ_MONO_32KBPS,代表音頻格式為opus,採樣率為24kHz,碼率為32kbps

    • SpeechSynthesisAudioFormat.OGG_OPUS_24KHZ_MONO_64KBPS,代表音頻格式為opus,採樣率為24kHz,碼率為64kbps

    • SpeechSynthesisAudioFormat.OGG_OPUS_48KHZ_MONO_16KBPS,代表音頻格式為opus,採樣率為48kHz,碼率為16kbps

    • SpeechSynthesisAudioFormat.OGG_OPUS_48KHZ_MONO_32KBPS,代表音頻格式為opus,採樣率為48kHz,碼率為32kbps

    • SpeechSynthesisAudioFormat.OGG_OPUS_48KHZ_MONO_64KBPS,代表音頻格式為opus,採樣率為48kHz,碼率為64kbps

volume

int

音量。

預設值:50。

取值範圍:[0, 100]。50代表標準音量。音量大小與該值呈線性關係,0為靜音,100為最大音量。

speechRate

float

語速。

預設值:1.0。

取值範圍:[0.5, 2.0]。1.0為標準語速,小於1.0則減慢,大於1.0則加快。

pitchRate

float

音高。該值作為音高調節的乘數,但其與聽感上的音高變化並非嚴格的線性或對數關係,建議通過測試選擇合適的值。

預設值:1.0。

取值範圍:[0.5, 2.0]。1.0為音色自然音高。大於1.0則音高變高,小於1.0則音高變低。

bit_rate

int

音頻碼率(單位kbps)。音頻格式為opus時,支援通過bit_rate參數調整碼率。

預設值:32。

取值範圍:[6, 510]。

說明

bit_rate需要通過SpeechSynthesisParam執行個體的parameter方法或者parameters方法進行設定:

通過parameter設定

SpeechSynthesisParam param = SpeechSynthesisParam.builder()
    .model("cosyvoice-v3-flash") // 模型
    .voice("longanyang") // 音色
    .parameter("bit_rate", 32)
    .build();

通過parameters設定

SpeechSynthesisParam param = SpeechSynthesisParam.builder()
    .model("cosyvoice-v3-flash") // 模型
    .voice("longanyang") // 音色
    .parameters(Collections.singletonMap("bit_rate", 32))
    .build();

enableWordTimestamp

boolean

是否開啟字層級時間戳記。

預設值:false。

  • true:開啟。

  • false:關閉。

該功能僅適用於cosyvoice-v3-flash、cosyvoice-v3-plus和cosyvoice-v2模型的複刻音色,以及音色列表中標記為支援的系統音色。

時間戳記結果僅能通過回調介面擷取

seed

int

產生時使用的隨機數種子,使合成的效果產生變化。在模型版本、文本、音色及其他參數均相同的前提下,使用相同的seed可複現相同的合成結果。

預設值0。

取值範圍:[0, 65535]。

languageHints

List

指定語音合成的目標語言,提升合成效果。

當數字、縮寫、符號等朗讀方式或者小語種合成效果不符合預期時使用,例如:

  • 數字朗讀方式不符合預期,“hello, this is 110”讀成“hello, this is one one zero”而非“hello, this is 么么零”

  • 符號朗讀不準確,“@”讀成“艾特”而非“at”

  • 小語種合成效果差,合成不自然

取值範圍:

  • zh:中文

  • en:英文

  • fr:法語

  • de:德語

  • ja:日語

  • ko:韓語

  • ru:俄語

注意:此參數為數組,但目前的版本僅處理第一個元素,因此建議只傳入一個值。

重要

此參數用於指定語音合成的目標語言,該設定與聲音複刻時的樣本音訊語種無關。如果您需要設定複刻任務的源語言,請參見CosyVoice聲音複刻API

instruction

String

設定指令,用於控制方言、情感或角色等合成效果。該功能僅適用於cosyvoice-v3-flash模型的複刻音色,以及音色列表中標記為支援Instruct的系統音色。

使用要求

  • 指令必須使用固定格式和內容(見下方說明)

  • 不設定時不生效(無預設值)

支援的功能

  • 指定方言

    • 適用音色:僅複刻音色

    • 格式:“請用<方言>表達。”(注意,結尾一定不要遺漏句號,使用時將“<方言>”替換為具體的方言,例如替換為廣東話)。

    • 樣本:“請用廣東話表達。

    • 支援的方言:廣東話、東北話、甘肅話、貴州話、河南話、湖北話、江西話、閩南話、寧夏話、山西話、陝西話、山東話、上海話、四川話、天津話、雲南話。

  • 指定情感

    • 適用音色

      • 複刻音色

      • 音色列表中標記為支援Instruct的系統音色

    • 格式:

      • 複刻音色:

        點擊查看複刻音色指令格式

        • 請儘可能非常大聲地說一句話。

        • 請用儘可能慢地語速說一句話。

        • 請用儘可能快地語速說一句話。

        • 請非常輕聲地說一句話。

        • 你可以慢一點說嗎

        • 你可以非常快一點說嗎

        • 你可以非常慢一點說嗎

        • 你可以快一點說嗎

        • 請非常生氣地說一句話。

        • 請非常開心地說一句話。

        • 請非常恐懼地說一句話。

        • 請非常傷心地說一句話。

        • 請非常驚訝地說一句話。

        • 請儘可能表現出堅定的感覺。

        • 請儘可能表現出憤怒的感覺。

        • 請嘗試一下親和的語調。

        • 請用冷酷的語調講話。

        • 請用威嚴的語調講話。

        • 我想體驗一下自然的語氣。

        • 我想看看你如何表達威脅。

        • 我想看看你怎麼表現智慧。

        • 我想看看你怎麼表現誘惑。

        • 我想聽聽用活潑的方式說話。

        • 我想聽聽你用激昂的感覺說話。

        • 我想聽聽用沉穩的方式說話的樣子。

        • 我想聽聽你用自信的感覺說話。

        • 你能用興奮的感覺和我交流嗎?

        • 你能否展示狂傲的情緒表達?

        • 你能展現一下優雅的情緒嗎?

        • 你可以用幸福的方式回答問題嗎?

        • 你可以做一個溫柔的情感示範嗎?

        • 能用冷靜的語調和我談談嗎?

        • 能用深沉的方法回答我嗎?

        • 能用粗獷的情緒態度和我對話嗎?

        • 用陰森的聲音告訴我這個答案。

        • 用堅韌的聲音告訴我這個答案。

        • 用自然親切的閑聊風格敘述。

        • 用廣播劇部落客的語氣講話。

      • 系統音色:系統音色和複刻音色的情感指令格式不同,詳情請參見音色列表

  • 指定情境、角色或身份等

enable_aigc_tag

boolean

是否在產生的音頻中添加AIGC隱性標識。設定為true時,會將隱性標識嵌入到支援格式(wav/mp3/opus)的音頻中。

預設值:false。

僅cosyvoice-v3-flash、cosyvoice-v3-plus、cosyvoice-v2支援該功能。

說明

enable_aigc_tag需要通過SpeechSynthesisParam執行個體的parameter方法或者parameters方法進行設定:

通過parameter設定

SpeechSynthesisParam param = SpeechSynthesisParam.builder()
    .model("cosyvoice-v3-flash") // 模型
    .voice("longanyang") // 音色
    .parameter("enable_aigc_tag", true)
    .build();

通過parameters設定

SpeechSynthesisParam param = SpeechSynthesisParam.builder()
    .model("cosyvoice-v3-flash") // 模型
    .voice("longanyang") // 音色
    .parameters(Collections.singletonMap("enable_aigc_tag", true))
    .build();

aigc_propagator

String

設定AIGC隱性標識中的 ContentPropagator 欄位,用於標識內容的傳播者。僅在 enable_aigc_tag 為 true 時生效。

預設值:阿里雲UID。

僅cosyvoice-v3-flash、cosyvoice-v3-plus、cosyvoice-v2支援該功能。

說明

aigc_propagator需要通過SpeechSynthesisParam執行個體的parameter方法或者parameters方法進行設定:

通過parameter設定

SpeechSynthesisParam param = SpeechSynthesisParam.builder()
    .model("cosyvoice-v3-flash") // 模型
    .voice("longanyang") // 音色
    .parameter("enable_aigc_tag", true)
    .parameter("aigc_propagator", "xxxx")
    .build();

通過parameters設定

Map<String, Object> map = new HashMap();
map.put("enable_aigc_tag", true);
map.put("aigc_propagator", "xxxx");

SpeechSynthesisParam param = SpeechSynthesisParam.builder()
    .model("cosyvoice-v3-flash") // 模型
    .voice("longanyang") // 音色
    .parameters(map)
    .build();

aigc_propagate_id

String

設定AIGC隱性標識中的 PropagateID 欄位,用於唯一標識一次具體的傳播行為。僅在 enable_aigc_tag 為 true 時生效。

預設值:本次語音合成請求Request ID。

僅cosyvoice-v3-flash、cosyvoice-v3-plus、cosyvoice-v2支援該功能。

說明

aigc_propagate_id需要通過SpeechSynthesisParam執行個體的parameter方法或者parameters方法進行設定:

通過parameter設定

SpeechSynthesisParam param = SpeechSynthesisParam.builder()
    .model("cosyvoice-v3-flash") // 模型
    .voice("longanyang") // 音色
    .parameter("enable_aigc_tag", true)
    .parameter("aigc_propagate_id", "xxxx")
    .build();

通過parameters設定

Map<String, Object> map = new HashMap();
map.put("enable_aigc_tag", true);
map.put("aigc_propagate_id", "xxxx");

SpeechSynthesisParam param = SpeechSynthesisParam.builder()
    .model("cosyvoice-v3-flash") // 模型
    .voice("longanyang") // 音色
    .parameters(map)
    .build();

關鍵介面

SpeechSynthesizer

SpeechSynthesizer通過“import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesizer;”方式引入,提供語音合成的關鍵介面。

介面/方法

參數

傳回值

描述

public SpeechSynthesizer(SpeechSynthesisParam param, ResultCallback<SpeechSynthesisResult> callback)

SpeechSynthesizer執行個體

建構函式。

public ByteBuffer call(String text)

text:待合成文本(UTF-8)

ByteBuffernull

將整段文本(無論是純文字還是包含SSML的文本)轉換為語音。

在建立SpeechSynthesizer執行個體時,存在以下兩種情況:

重要

每次調用call方法前,需要重新初始化SpeechSynthesizer執行個體。

public void streamingCall(String text)

text:待合成文本(UTF-8)

流式發送待合成文本(不支援包含SSML的文本)。

您可以多次調用該介面,將待合成文本分多次發送給服務端。合成結果通過回調介面(ResultCallback)onEvent方法擷取。

詳細調用流程和參考樣本請參見雙向流式調用

public void streamingComplete() throws RuntimeException

結束流式語音合成。

該方法阻塞調用線程直至發生以下條件之一:

  • 服務端完成最終音頻合成(成功)

  • 流式會話異常中斷(失敗)

  • 達到10分鐘逾時閾值(自動解除阻塞)

詳細的調用流程和參考樣本請參見雙向流式調用

重要

雙向流式調用時,請確保調用該方法,以免導致合成語音缺失。

public Flowable<SpeechSynthesisResult> callAsFlowable(String text)

text:待合成文本,須為UTF-8格式

合成結果,封裝在 Flowable<SpeechSynthesisResult>

非流式文本(不支援包含SSML的文本)輸入即時轉換為流式語音輸出,合成結果在flowable中流式返回。

詳細的調用流程和參考樣本請參見通過Flowable調用

boolean getDuplexApi().close(int code, String reason)

code: WebSocket關閉碼(Close Code)

reason:關閉原因

這兩個參數可參考The WebSocket Protocol文檔進行配置

true

在任務結束後,無論是否出現異常都需要關閉WebSocket串連,避免造成串連泄漏。關於如何複用串連提升效率請參考高並發情境

public Flowable<SpeechSynthesisResult> streamingCallAsFlowable(Flowable<String> textStream)

textStream:封裝了待合成文本的Flowable執行個體

合成結果,封裝在 Flowable<SpeechSynthesisResult>

流式文本(不支援包含SSML的文本)輸入即時轉換為流式語音輸出,合成結果在flowable中流式返回。

詳細的調用流程和參考樣本請參見通過Flowable調用

public String getLastRequestId()

上一個任務的Request ID

擷取上一個任務的Request ID,在調用callstreamingCallcallAsFlowablestreamingCallAsFlowable開始新任務之後可以使用。

public long getFirstPackageDelay()

當前任務首包延遲

擷取當前任務的首包延遲(一般在500ms左右),任務結束後使用。

首包延遲是開始發送文本和接收第一個音頻包之間的時間,單位為毫秒。

首次發送文本時需建立 WebSocket 串連,因此首包延遲會包含串連建立的耗時;若在高並發情境下複用串連,則不包含串連耗時。

回調介面(ResultCallback

單向流式調用雙向流式調用時,通過回調介面ResultCallback擷取合成結果。通過“import com.alibaba.dashscope.common.ResultCallback;”方式引入。

點擊查看樣本

ResultCallback<SpeechSynthesisResult> callback = new ResultCallback<SpeechSynthesisResult>() {
    @Override
    public void onEvent(SpeechSynthesisResult result) {
        System.out.println("RequestId為:" + result.getRequestId());
        // 即時處理音頻分區(如播放/寫入緩衝)
    }

    @Override
    public void onComplete() {
        System.out.println("任務完成");
        // 處理合成結束邏輯(如釋放播放器)
    }

    @Override
    public void onError(Exception e) {
        System.out.println("任務失敗:" + e.getMessage());
        // 處理異常(網路錯誤/服務端錯誤碼)
    }
};

介面/方法

參數

傳回值

描述

public void onEvent(SpeechSynthesisResult result)

result:SpeechSynthesisResult執行個體

當服務端推送語音合成資料時被非同步回調。

調用SpeechSynthesisResultgetAudioFrame方法能夠獲得二進位音頻資料。

調用SpeechSynthesisResultgetUsage方法能夠獲得截止當前,本次請求中計費的有效字元數。

public void onComplete()

當所有合成資料全部返回(語音合成完成)後被非同步回調。

public void onError(Exception e)

e:異常資訊

發生異常時該介面被非同步回調。

建議在onError方法中實現完整的異常日誌記錄和資源清理邏輯。

響應結果

伺服器返回二進位音頻資料:

  • 非流式調用:對SpeechSynthesizer類call方法返回的二進位音頻資料進行處理。

  • 單向流式調用雙向流式調用:對回調介面(ResultCallback)onEvent方法的參數(SpeechSynthesisResult類型)進行處理。

    SpeechSynthesisResult的關鍵介面如下:

    介面/方法

    參數

    傳回值

    描述

    public ByteBuffer getAudioFrame()

    二進位音頻資料

    返回當前流式合成片段的二進位音頻資料,可能為空白(當無新資料到達時)。

    您可以將二進位音頻資料合成為一個完整的音頻檔案後使用播放器播放,也可以通過支援流式播放的播放器即時播放。

    重要
    • 流式語音合成中,對於mp3/opus等壓縮格式,音頻分段傳輸需使用流式播放器,不可逐幀播放,避免解碼失敗。

      支援流式播放的播放器:ffmpeg、pyaudio (Python)、AudioFormat (Java)、MediaSource (Javascript)等。
    • 將音頻資料合成完整的音頻檔案時,應以追加模式寫入同一檔案。

    • 流式語音合成的wav/mp3 格式音頻僅首幀包含頭資訊,後續幀為純音頻資料。

    public String getRequestId()

    任務的Request ID

    擷取任務的Request ID。當調用getAudioFrame擷取到二進位音頻資料時,getRequestId方法的傳回值為null

    public SpeechSynthesisUsage getUsage()

    SpeechSynthesisUsage:截止當前,本次請求中計費的有效字元數

    返回SpeechSynthesisUsagenull

    通過SpeechSynthesisUsagegetCharacters方法,可擷取截止當前,本次請求中計費的有效字元數,請以最後一次收到的SpeechSynthesisUsage為準。

    public Sentence getTimestamp()

    Sentence:截止當前,本次請求中計費的句子

    需要開啟enableWordTimestamp字層級時間戳記

    返回Sentencenull

    Sentence的方法:

    • getIndex:可擷取句子編號,從0開始。

    • getWords:可擷取組成句子的字元數組List<Word>,請以最後一次收到的Sentence為準。

    Word方法:

    • getText:擷取字的文本。

    • getBeginIndex:擷取字在句子中的開始位置索引,從 0 開始。

    • getEndIndex:擷取字在句子中的結束位置索引,從 1 開始。

    • getBeginTime:擷取字對應音訊開始時間戳,單位為毫秒。

    • getEndTime:擷取字對應音訊結束時間戳記,單位為毫秒。

錯誤碼

如遇報錯問題,請參見錯誤資訊進行排查。

更多樣本

更多樣本,請參見GitHub

常見問題

功能特性/計量計費/限流

Q:當遇到發音不準的情況時,有什麼解決方案可以嘗試?

通過SSML可以對語音合成效果進行個人化定製。

Q:語音合成是按文本字元數計費的,要如何查看或擷取每次合成的文本長度?

故障排查

如遇代碼報錯問題,請根據錯誤碼中的資訊進行排查。

Q:如何擷取Request ID

通過以下兩種方式可以擷取:

Q:使用SSML功能失敗是什麼原因?

請按以下步驟排查:

  1. 確保限制與約束正確

  2. 安裝最新版本 DashScope SDK

  3. 確保使用正確的介面:只有SpeechSynthesizer類call方法支援SSML

  4. 確保待合成文本為純文字格式且符合格式要求,詳情請參見SSML標記語言介紹

Q:為什麼音頻無法播放?

請根據以下情境逐一排查:

  1. 音頻儲存為完整檔案(如xx.mp3)的情況

    1. 音頻格式一致性:確保請求參數中設定的音頻格式與檔案尾碼一致。例如,如果請求參數設定的音頻格式為wav,但檔案尾碼為mp3,可能會導致播放失敗。

    2. 播放器相容性:確認使用的播放器是否支援該音頻檔案的格式和採樣率。例如,某些播放器可能不支援高採樣率或特定編碼的音頻檔案。

  2. 流式播放音訊情況

    1. 將音頻流儲存為完整檔案,嘗試使用播放器播放。如果檔案無法播放,請參考情境 1 的排查方法。

    2. 如果檔案可以正常播放,則問題可能出在流式播放的實現上。請確認使用的播放器是否支援流式播放。

      常見的支援流式播放的工具和庫包括:ffmpeg、pyaudio (Python)、AudioFormat (Java)、MediaSource (Javascript)等。

Q:為什麼音頻播放卡頓?

請根據以下情境逐一排查:

  1. 檢查文本發送速度: 確保發送文本的間隔合理,避免前一句音頻播放完畢後,下一句文本未能及時發送。

  2. 檢查回呼函數效能:

    • 檢查回呼函數中是否存在過多商務邏輯,導致阻塞。

    • 回呼函數運行在 WebSocket 線程中,若被阻塞,可能會影響 WebSocket 接收網路資料包,進而導致音頻接收卡頓。

    • 建議將音頻資料寫入一個獨立的音頻緩衝區(audio buffer),然後在其他線程中讀取並處理,避免阻塞 WebSocket 線程。

  3. 檢查網路穩定性: 確保網路連接穩定,避免因網路波動導致音頻傳輸中斷或延遲。

Q:語音合成慢(合成時間長)是什麼原因?

請按以下步驟排查:

  1. 檢查輸入間隔

    如果是流式語音合成,請確認文字發送間隔是否過長(如上段發出後延遲數秒才發送下段),過久間隔會導致合成總時間長度增加。

  2. 分析效能指標

    • 首包延遲:正常500ms左右。

    • RTF(RTF = 合成總耗時/音頻時間長度):正常小於1.0。

Q:合成的語音發音錯誤如何處理?

請使用SSML的<phoneme>標籤指定正確的發音。

Q:為什麼沒有返回語音?為什麼結尾部分的文本沒能成功轉換成語音?(合成語音缺失)

請檢查是否遺漏了調用SpeechSynthesizer類streamingComplete方法。在語音合成過程中,服務端會在緩衝足夠文本後才開始合成。如果未調用streamingComplete方法,可能會導致緩衝中的結尾部分文本未能被合成為語音。

許可權與認證

Q:我希望我的 API Key 僅用於 CosyVoice 語音合成服務,而不被百鍊其他模型使用(許可權隔離),我該如何做

可以通過建立業務空間並只授權特定模型來限制API Key的使用範圍。詳情請參見業務空間管理

更多問題

請參見GitHub QA