音色克隆接口
通过上传参考音频,克隆出专属音色,后续 TTS 生成直接使用自定义 voice_id 调用即可。
使用限制
- 每个账户最多保存 5 个自定义音色
响应说明
- 本页三个接口均返回 JSON,HTTP 状态码固定为
200 - 请通过
succeed判断操作是否成功,通过error_code和error_message查看失败原因 - 成功响应的结果位于
data字段内
{
"error_code": 0,
"error_message": "成功",
"succeed": true,
"data": {}
}
完整使用流程
Step 1:上传本地参考音频,取得 object_key
Step 2:使用 object_key、参考文本和自定义名称保存音色
Step 3:(可选)查看已保存的音色列表
Step 4:在 TTS 生成接口中使用自定义 voice_id
Step 5:(可选)删除不再使用的音色
如果参考音频已经有可公开访问的 HTTP/HTTPS URL,可以跳过 Step 1,直接把 URL 作为 ref_audio。
一、保存音色
创建新音色或更新已有音色(同名则覆盖)。
接口信息
- 接口路径:
/v1/voice/save - 请求方式:
POST - 认证方式: Header 中的
X-API-Key
请求头
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| X-API-Key | string | 是 | 应用密钥 |
请求参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| voice_id | string | 是 | 自定义音色名称,只允许小写字母、数字、-、_,最长 64 字符 |
| ref_audio | string | 是 | 参考音频,支持公开 HTTP/HTTPS URL 或 OSS object_key;HTTP/HTTPS URL 必须解析到公网地址 |
| ref_text | string | 是 | 参考音频中说的文字内容,最长 500 字符 |
ref_audio与ref_text必须同时提供。参考音频支持常见格式(MP3、WAV、M4A 等),大小不超过 50MB,时长不超过 30 秒。
响应说明
请求成功时,data 为空对象:
{
"error_code": 0,
"error_message": "成功",
"succeed": true,
"data": {}
}
请求示例
推荐方式:先上传参考音频
调用通用文件上传接口上传本地文件。上传和保存音色必须使用同一个 X-API-Key:
上传文件要求
上传前请确保参考音频符合以下要求:
- 文件大小不超过 50MB。
- 音频时长不超过 30 秒。
不符合要求的文件将无法用于音色克隆。
curl -X POST "https://api.vuilabs.cn/v1/files/upload" \
-H "X-API-Key: your-secret-key-here" \
-F "scene=audio" \
-F "file=@/path/to/sample.wav"
从成功响应中读取 data.object_key:
{
"error_code": 0,
"error_message": "成功",
"succeed": true,
"data": {
"object_key": "uploads/audio/1001/20260630/1782820801123_abcd1234_sample.wav",
"file_name": "sample.wav",
"size": 123456,
"scene": "audio"
}
}
将 data.object_key 原样填入保存音色请求的 ref_audio:
curl -X POST "https://api.vuilabs.cn/v1/voice/save" \
-H "X-API-Key: your-secret-key-here" \
-H "Content-Type: application/json" \
-d '{
"voice_id": "my-voice",
"ref_audio": "uploads/audio/1001/20260630/1782820801123_abcd1234_sample.wav",
"ref_text": "这是一段参考音频,用于克隆音色。"
}'
上传接口默认不返回
url;这里直接使用object_key,不需要自行拼接 OSS URL。
使用已有公开 URL
curl -X POST "https://api.vuilabs.cn/v1/voice/save" \
-H "X-API-Key: your-secret-key-here" \
-H "Content-Type: application/json" \
-d '{
"voice_id": "my-voice",
"ref_audio": "https://example.com/sample.wav",
"ref_text": "这是一段参考音频,用于克隆音色。"
}'
各语言示例
Python
import requests
response = requests.post(
"https://api.vuilabs.cn/v1/voice/save",
headers={"X-API-Key": "your-secret-key-here"},
json={
"voice_id": "my-voice",
"ref_audio": "https://example.com/sample.wav",
"ref_text": "这是一段参考音频,用于克隆音色。"
}
)
payload = response.json()
if payload["succeed"]:
print("音色保存成功")
else:
print(payload["error_code"], payload["error_message"])
Node.js
const https = require("https");
const body = JSON.stringify({
voice_id: "my-voice",
ref_audio: "https://example.com/sample.wav",
ref_text: "这是一段参考音频,用于克隆音色。",
});
const req = https.request(
{
hostname: "api.vuilabs.cn",
path: "/v1/voice/save",
method: "POST",
headers: {
"X-API-Key": "your-secret-key-here",
"Content-Type": "application/json",
"Content-Length": Buffer.byteLength(body),
},
},
(res) => {
let data = "";
res.on("data", (chunk) => (data += chunk));
res.on("end", () => {
const payload = JSON.parse(data);
if (payload.succeed) {
console.log("音色保存成功");
} else {
console.error("Error:", payload.error_code, payload.error_message);
}
});
}
);
req.write(body);
req.end();
二、查看音色列表
分页列出当前账户下已保存的自定义音色。每页最多返回 20 条,下一页使用上次响应中的 next_voice_id 作为请求参数。
接口信息
- 接口路径:
/v1/voice/list - 请求方式:
GET - 认证方式: Header 中的
X-API-Key
请求头
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| X-API-Key | string | 是 | 应用密钥 |
查询参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| voice_id | string | 否 | 上一页响应中的 next_voice_id;首次查询不传 |
| page_size | int | 否 | 每页数量,默认 20,最大 20 |
响应参数
| 字段 | 类型 | 说明 |
|---|---|---|
| error_code | int | 错误码;成功为 0 |
| error_message | string | 错误信息;成功为 成功 |
| succeed | boolean | 查询是否成功 |
| data | object | 音色列表分页数据 |
| data.list | array | 音色列表 |
| data.list[].voice_id | string | 音色名称 |
| data.list[].voice_url | string | 参考音频地址 |
| data.list[].created_at | int64 | 创建时间(Unix 秒) |
| data.total | int64 | 当前页返回数量 |
| data.next_voice_id | string | 下一页起始音色 ID;has_more 为 false 时为空或不返回 |
| data.has_more | boolean | 是否还有下一页 |
响应示例
{
"error_code": 0,
"error_message": "成功",
"succeed": true,
"data": {
"list": [
{
"voice_id": "my-voice",
"voice_url": "https://lunalab-res.oss-cn-hangzhou.aliyuncs.com/ttsVoiceV1/20260326/xxx.wav",
"created_at": 1743000000
}
],
"total": 1,
"next_voice_id": "",
"has_more": false
}
}
请求示例
首次查询:
curl -X GET "https://api.vuilabs.cn/v1/voice/list" \
-H "X-API-Key: your-secret-key-here"
查询下一页:
curl -X GET "https://api.vuilabs.cn/v1/voice/list?voice_id=my-voice&page_size=20" \
-H "X-API-Key: your-secret-key-here"
Python
import requests
response = requests.get(
"https://api.vuilabs.cn/v1/voice/list",
headers={"X-API-Key": "your-secret-key-here"}
)
payload = response.json()
print(payload)
if payload["succeed"] and payload["data"]["has_more"]:
next_response = requests.get(
"https://api.vuilabs.cn/v1/voice/list",
headers={"X-API-Key": "your-secret-key-here"},
params={"voice_id": payload["data"]["next_voice_id"], "page_size": 20},
)
print(next_response.json())
elif not payload["succeed"]:
print(payload["error_code"], payload["error_message"])
三、删除音色
删除当前账户下指定的自定义音色。该操作为幂等删除:如果 voice_id 未对应当前账户的自定义音色,也可能返回成功;成功不表示系统预置音色被删除。
接口信息
- 接口路径:
/v1/voice/{voice_id} - 请求方式:
DELETE - 认证方式: Header 中的
X-API-Key
请求头
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| X-API-Key | string | 是 | 应用密钥 |
路径参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| voice_id | string | 是 | 要删除的音色名称 |
响应说明
请求成功时,data 为空对象:
{
"error_code": 0,
"error_message": "成功",
"succeed": true,
"data": {}
}
请求示例
curl -X DELETE "https://api.vuilabs.cn/v1/voice/my-voice" \
-H "X-API-Key: your-secret-key-here"
Python
import requests
response = requests.delete(
"https://api.vuilabs.cn/v1/voice/my-voice",
headers={"X-API-Key": "your-secret-key-here"}
)
payload = response.json()
if payload["succeed"]:
print("音色删除成功")
else:
print(payload["error_code"], payload["error_message"])
四、在 TTS 中使用自定义音色
音色保存成功后,在 音频生成接口 中直接使用自定义的 voice_id 即可,接口调用方式完全相同。
# 同步生成
curl -X POST "https://api.vuilabs.cn/v1/text-to-speech" \
-H "X-API-Key: your-secret-key-here" \
-H "Content-Type: application/json" \
-d '{
"voice_id": "my-voice",
"generate_text": "你好,这是用我的克隆音色生成的语音。",
"model_id": "luna-tts"
}' \
--output audio.wav
# 流式生成
curl -X POST "https://api.vuilabs.cn/v1/text-to-speech/stream" \
-H "X-API-Key: your-secret-key-here" \
-H "Content-Type: application/json" \
-d '{
"voice_id": "my-voice",
"generate_text": "你好,这是用我的克隆音色生成的语音。",
"model_id": "luna-tts"
}' \
--output audio.wav
五、错误响应
操作失败时,HTTP 状态码仍为 200,请通过 JSON 响应中的 succeed 和错误信息判断结果:
{
"error_code": 10018,
"error_message": "该名称已被占用,请换一个名称",
"succeed": false,
"data": null
}
错误码说明
| error_code | error_message | 说明 |
|---|---|---|
| 10000 | 服务器内部错误 | 操作失败,请查看 error_message;持续失败请联系支持 |
| 10001 | 参数错误 | voice_id 格式不合法、ref_audio 与 ref_text 未同时提供、ref_text 超长、ref_audio URL 非公网地址等 |
| 10003 | 未授权 | X-API-Key 缺失、无效或无音色克隆权限 |
| 10014 | 连接数限制 | 请求频率超限 |
| 20003 | 余额不足 | 免费次数已用完且账户余额不足 |
| 10017 | 最多创建 5 个自定义音色 | 当前账户自定义音色数量达到上限 |
| 10018 | 该名称已被占用,请换一个名称 | voice_id 与系统预置音色重名 |
| 10019 | 音色ID冲突,请重试 | voice_id 与已有自定义音色冲突 |
| 20012 | 音频文件格式错误,请重新上传正确的音频格式文件 | 音频格式不支持、文件损坏、下载或解析失败 |
| 20015 | 克隆音色参考音频时长不能超过30秒,请重新上传30秒以内的音频 | 参考音频超过 30 秒 |
六、计费说明
具体计费规则、价格和免费额度请参见 产品计费。