API接口详情

CosyVoice声音复刻服务依托先进的大模型技术进行特征提取,无需训练过程就可以完成声音的复刻。仅需提供10~20秒的音频,即可迅速生成高度相似且听感自然的定制声音。本文将详细介绍CosyVoice声音复刻服务的使用方法和操作流程,帮助您快速实现声音复刻。

应用场景

  • 陪伴场景:通过复刻家人的声音提供个性化陪伴。可用于智能助手和车载导航语音,以及家庭娱乐项目,例如,为家人朗读绘本、控制家用电器或提供教育辅导。

  • 教育场景:复刻老师的声音,加强师生互动,丰富教学视频和课件的内容,打造更亲切、更生动的学习体验。

  • 音视频产业:复刻主播的声音,以便于后期的补录和配音等,从而提高音视频的制作效率。

  • 智能客服:通过复刻客户经理的声音,提供语音服务,包括但不限于客户回访和市场营销电话,以增强服务的个性化和人性化特征。

产品优势

  • 低样本音频要求:仅需短短10~20秒的录音便能完成声音复刻,显著降低了录制成本,提升了效率。

  • 高度拟真:利用阿里通义语音实验室自研的CosyVoice生成式神经网络语音大模型算法,结合前沿的零样本学习技术,能够在语调、韵律以及情感表达上高度还原真人声音,很难与真实录音相辨。

  • 即时合成:秒级还原真实音色,提供高效、实时的声音复刻服务。

支持的模型

声音复刻服务只支持cosyvoice-v1模型。

注意事项

使用CosyVoice声音复刻服务请注意以下事项:

  • 音频文件格式要求:

    • 声道数:单/双声道

    • 采样率:大于等于 16000 Hz

    • 格式:WAV(16bit)、MP3、M4A

    • 文件大小:10MB 以内

    • 音频时长:10~20秒,不建议超过60秒。在朗读时请保持连贯,至少包含一段超过5秒的连续语音。

  • 声音复刻数量限制:每个阿里云主账号最多可复刻1000个音色。若您的需求超过此限额,请提前与我们的售前团队联系沟通或加入开发者群。超过1年未使用的声音将下线处理。

  • 版权与合法性:您需对所提供声音的所有权及合法使用权负责,请注意阅读服务协议

  • 复刻后音色的使用:使用声音复刻服务生成的音色(VoiceName)与音色列表中官方默认提供的音色(例如:longxiaoxia)的使用方法相同。

  • 服务调用方式:声音复刻服务当前仅支持通过SDK方式使用。

计费说明

声音复刻为免费服务,后续使用cosyvoice-v1模型调用复刻的音色进行语音合成时,将会产生相应的模型调用费用。计费详情,请参见CosyVoice

前提条件

  • 已开通服务并获得API-KEY:获取API Key

  • 推荐您将API-KEY配置到环境变量中以降低API-KEY的泄漏风险,详情可参考配置API Key到环境变量。您也可以在代码中配置API-KEY,但是泄漏风险会提高。

  • 已安装最新版SDK:安装SDK

  • 已准备公网可访问的音频URL,推荐将音频上传至OSS。具体操作,请参见操作步骤

代码示例

以下示例代码展示如何复刻声音,并使用cosyvoice-v1模型调用复刻的声音,将文本“今天天气怎么样?”转为语音。

说明
  • VoiceEnrollmentService的接口并发调用限制为 10 RPS。

  • 克隆音色语音合成并发调用限制和CosyVoice音色一致,为 3 RPS。

请求示例

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

dashscope.api_key = os.getenv('DASHSCOPE_API_KEY')  # 如果您没有配置环境变量,请在此处用您的API-KEY进行替换
url = "https://your-audio-file-url"  # 请按实际情况进行替换
prefix = 'prefix'
target_model = "cosyvoice-v1"

# 创建语音注册服务实例
service = VoiceEnrollmentService()

# 调用create_voice方法复刻声音,并生成voice_id
voice_id = service.create_voice(target_model=target_model, prefix=prefix, url=url)
print("requestId: ", service.get_last_request_id())
print(f"your voice id is {voice_id}")

# 使用复刻的声音进行语音合成
synthesizer = SpeechSynthesizer(model=target_model, voice=voice_id)
audio = synthesizer.call("今天天气怎么样?")
print("requestId: ", synthesizer.get_last_request_id())

# 将合成的音频文件保存到本地文件
with open("output.mp3", "wb") as f:
    f.write(audio)
import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesisParam;
import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesizer;
import com.alibaba.dashscope.audio.ttsv2.enrollment.Voice;
import com.alibaba.dashscope.audio.ttsv2.enrollment.VoiceEnrollmentService;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import static java.lang.System.exit;

public class VoiceEnrollmentSampleCodes {
    public static String apiKey = System.getenv("DASHSCOPE_API_KEY");  // 如果您没有配置环境变量,请在此处用您的API-KEY进行替换
    private static String fileUrl = "https://your-audio-file-url";  // 请按实际情况进行替换
    private static String prefix = "prefix";
    private static String targetModel = "cosyvoice-v1";

    public static void main(String[] args)
            throws NoApiKeyException, InputRequiredException {
        // 复刻声音
        VoiceEnrollmentService service = new VoiceEnrollmentService(apiKey);
        Voice myVoice = service.createVoice(targetModel, prefix, fileUrl);
        System.out.println("RequestId: " + service.getLastRequestId());
        System.out.println("your voice id is " + myVoice.getVoiceId());
        // 使用复刻的声音来合成文本为语音
        SpeechSynthesisParam param = SpeechSynthesisParam.builder()
                .apiKey(apiKey)
                .model(targetModel)
                .voice(myVoice.getVoiceId())
                .build();
        SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, null);
        ByteBuffer audio = synthesizer.call("今天天气怎么样?");
        // 保存合成的语音到文件
        System.out.println("TTS RequestId: " + synthesizer.getLastRequestId());
        File file = new File("output.mp3");
        try (FileOutputStream fos = new FileOutputStream(file)) {
            fos.write(audio.array());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        exit(0);
    }
}

API详情

创建克隆音色

def create_voice(self, target_model: str, prefix: str, url: str) -> str:
    '''
    创建新克隆音色
    param: target_model 克隆音色对应的语音合成模型版本
    param: prefix 音色自定义前缀,仅允许数字和小写字母,小于十个字符。 
    param: url 用于克隆的音频文件url
    return: voice_id
    '''
/**
 * 创建新克隆音色
 *
 * @param targetModel 克隆音色对应的语音合成模型版本
 * @param prefix 音色自定义前缀,仅允许数字和小写字母,小于十个字符。
 * @param url 用于克隆的音频文件url
 * @return Voice 音色对象
 * @throws NoApiKeyException 如果apikey为空
 * @throws InputRequiredException 如果必须参数为空
 */
public Voice createVoice(String targetModel, String prefix, String url)
    throws NoApiKeyException, InputRequiredException

查询所有音色

def list_voices(self, prefix=None, page_index: int = 0, page_size: int = 10) -> List[dict]:
    '''
    查询已创建的所有音色
    param: prefix 音色前缀,设置为None则返回所有音色
    param: page_index 查询的页索引
    param: page_size 查询页大小
    return: List[dict] 音色列表,包含每个音色的id,创建时间,修改时间,状态。
    '''
/**
 * 查询已创建的所有音色 默认的页索引为0,默认的页大小为10
 *
 * @param prefix 音色自定义前缀,仅允许数字和小写字母,小于十个字符。可以为null。
 * @return Voice[] 音色对象数组
 * @throws NoApiKeyException 如果apikey为空
 * @throws InputRequiredException 如果必须参数为空
 */
public Voice[] listVoice(String prefix) throws NoApiKeyException, InputRequiredException 

/**
 * 查询已创建的所有音色
 *
 * @param prefix 音色自定义前缀,仅允许数字和小写字母,小于十个字符。
 * @param pageIndex 查询的页索引
 * @param pageSize 查询的页大小
 * @return Voice[] 音色对象数组
 * @throws NoApiKeyException 如果apikey为空
 * @throws InputRequiredException 如果必须参数为空
 */
public Voice[] listVoice(String prefix, int pageIndex, int pageSize)
    throws NoApiKeyException, InputRequiredException

响应示例

[
    {
        "gmt_create": "2024-09-13 11:29:41",
        "voice_id": "cosyvoice-prefix-9c4477f281ef4fb189648df0********",
        "gmt_modified": "2024-09-13 11:29:41",
        "status": "OK"
    },
    {
        "gmt_create": "2024-09-13 13:22:38",
        "voice_id": "cosyvoice-prefix-be555a4ddb0246fc9240dcd0********",
        "gmt_modified": "2024-09-13 13:22:38",
        "status": "OK"
    }
]

status

说明

UNDEPLOYED

不可调用

OK

可调用

查询指定的音色

def query_voices(self, voice_id: str) -> List[str]:
    '''
    查询已创建的所有音色
    param: voice_id 需要查询的音色
    return: bytes 注册音色使用的音频
    '''
/**
 * 查询指定音色
 *
 * @param voiceId 需要查询的音色
 * @return Voice 音色对象,包含状态信息和用于克隆的音频文件url
 * @throws NoApiKeyException 如果apikey为空
 * @throws InputRequiredException 如果必须参数为空
 */
public Voice queryVoice(String voiceId) throws NoApiKeyException, InputRequiredException

响应示例

{
    "gmt_create": "2024-09-13 11:29:41",
    "resource_link": "http://nls-cloud-cn-beijing.oss-cn-beijing.aliyuncs.com/nls-customization-data-prod/tts/voice/1758054162438655/prefix/cosyvoice-prefix-9c4477f281ef4fb189648df0********/orig/cosyvoice-prefix-9c4477f281ef4fb189648df0e9adc3c0.wav?Expires=1726307787&OSSAccessKeyId=LTAIbiW********&Signature=1lMuxk7wk%2BmiaiokbLX********%3D",
    "target_model": "cosyvoice-v1",
    "gmt_modified": "2024-09-13 11:29:41",
    "status": "OK"
}

更新音色

def update_voice(self, voice_id: str, url: str) -> None:
    '''
    更新音色
    param: voice_id 音色id
    param: url 用于克隆的音频文件url
    '''
/**
 * 更新音色
 *
 * @param voiceId 需要更新的音色
 * @param url 用于克隆的音频文件url
 * @throws NoApiKeyException 如果apikey为空
 * @throws InputRequiredException 如果必须参数为空
 */
public void updateVoice(String voiceId, String url)
    throws NoApiKeyException, InputRequiredException

删除音色

def delete_voice(self, voice_id: str) -> None:
    '''
    删除音色
    param: voice_id 需要删除的音色
    '''
/**
 * 删除音色
 *
 * @param voiceId 需要删除的音色
 * @throws NoApiKeyException 如果apikey为空
 * @throws InputRequiredException 如果必须参数为空
 */
public void deleteVoice(String voiceId) throws NoApiKeyException, InputRequiredException 

错误处理

在 Python SDK 中调用发生错误将通过异常 VoiceEnrollmentException 抛出。异常包括:状态码、异常代码、异常描述。

class VoiceEnrollmentException(Exception):
  def __init__(self, status_code: int, code: str, error_message: str)

在 Java SDK 中调用发生错误将通过 NoApiKeyException、InputRequiredException异常抛出。

通过HTTP调用

声音复刻服务的协议为HTTPS,开发者可以通过HTTP创建、查询、更新、删除音色。

如您没将API Key配置到环境变量中,请将cURL中的“Authorization: Bearer $DASHSCOPE_API_KEY”改成Authorization: Bearer your-api-key”,其中your-api-key为您的API Key。

说明

返回结果中的 usage 字段用于计费计数。声音复刻服务是免费的,因此您无需关注该字段。

创建克隆音色

curl调用示例:

curl -X POST https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
    "model": "voice-enrollment",
    "input": {
            "action": "create_voice",
            "target_model": "cosyvoice-v1",
            "prefix": "testpfx",
            "url": "https://your-audio-file-url"
        }
}'

返回示例:

{
    "output": {
        "voice_id": "cosyvoice-testpfx-1f80bfbd44c44692be19xxxxxxxxxxxx"
    },
    "usage": {
        "count": 1
    },
    "request_id": "37fc7e5a-78c0-930b-a99f-xxxxxxxxxxxx"
}

查询所有音色

curl调用示例:

curl -X POST https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
    "model": "voice-enrollment",
    "input": {
                "action": "list_voice",
                "prefix": null,
                "page_index": 0,
                "page_size": 10
            }
}'
说明

prefix字段在示例中为null,会返回所有音色,您可以根据需要修改为指定字符串。

返回示例:

{
    "output": {
        "voice_list": [
            {
                "gmt_create": "2024-12-11 13:38:02",
                "voice_id": "cosyvoice-testpfx-1f80bfbd44c44692be19xxxxxxxxxxxx",
                "gmt_modified": "2024-12-11 13:38:02",
                "status": "OK"
            }
        ]
    },
    "usage": {
        "count": 1
    },
    "request_id": "321e4537-049e-9d6e-9a9b-xxxxxxxxxxxx"
}

查询指定的音色

curl调用示例:

curl -X POST https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
    "model": "voice-enrollment",
    "input": {
                "action": "query_voice",
                "voice_id": "cosyvoice-testpfx-1f80bfbd44c44692be1988bb66c5e3bd"
            }
}'

返回示例:

{
    "output": {
        "gmt_create": "2024-12-11 13:38:02",
        "resource_link": "http://nls-cloud-cn-beijing.oss-cn-beijing.aliyuncs.com/nls-customization-data-prod/tts/voice/xxxxxxxx",
        "target_model": "cosyvoice-v1",
        "gmt_modified": "2024-12-11 13:38:02",
        "status": "OK"
    },
    "usage": {
        "count": 1
    },
    "request_id": "8c8ef554-da6a-9355-9a4b-f04b30a8d2ce"
}

更新音色

curl调用示例:

curl -X POST https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
    "model": "voice-enrollment",
    "input": {
                "action": "update_voice",
                "voice_id": "cosyvoice-testpfx-1f80bfbd44c44692be1988bb66c5e3bd",
                "url": "https://your-audio-file-url"
            }
}'

返回示例:

{
    "output": {},
    "usage": {
        "count": 1
    },
    "request_id": "2450f969-d9ea-9483-bafc-a2e6a6cb3b16"
}

删除音色

curl调用示例:

curl -X POST https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
    "model": "voice-enrollment",
    "input": {
                "action": "delete_voice",
                "voice_id": "cosyvoice-testpfx-1f80bfbd44c44692be1988bb66c5e3bd"
            }
}'

返回示例:

{
    "output": {},
    "usage": {
        "count": 1
    },
    "request_id": "0e54f121-6d5e-9de9-b91c-211eb90f99b6"
}

错误码说明

HTTP返回码

错误代码 Code

错误信息 Message

(具体信息内容可能跟随场景有所变化)

含义说明

415

BadRequest.UnsupportedFileFormat

File format unsupported.

文件格式不支持。

416

BadRequest.ResourceNotExist

The Required resource not exist.

更新、查询或删除接口调用时资源不存在。

430

Audio.DecoderError

Decoder audio file failed.

音频文件解码失败。

430

Audio.FileSizeExceed

File too large

文件大小超限,声音克隆文件需10M以内。

430

Audio.AudioRateError

File sample rate unsupported

文件采样率不支持,要求16KHz 及以上。

430

Audio.AudioSilentError

Silent file unsupported

文件为静音或非静音长度过短,声音克隆要求10秒以上有效音频。

更多通用错误码的详细信息,请参阅错误码