声音复刻接入说明
一、产品介绍
TTS个性化“声音复刻”,又称“声音克隆”,是赋能用户通过少量的录音,训练得到音色和发音风格与录音非常相似的声音模型,快速“克隆”个性化的声音,进而使用该音色完成讲故事、播天气、读小说、导航播报等功能。
二、技术说明
2.2 技术流程
2.1 技术特性
- 支持男声、女声、童声复刻,支持中、英文文本,支持UTF-8等多种文本格式,支持SSML标签控制。
- 支持8k、16k、32k等多种采样率,支持合成mp3、wav、pcm等多种音频格式。
- 平均首帧延时<=300ms,P95首帧延时<=500ms。
2.2 模型训练机制介绍
- 用户录⾳上传后,如果有空闲训练资源,10分钟之内模型训练结束;如果训练资源紧张,采⽤排队等待机制;
- 训练结束后,会下发训练结束通知,可以在手机APP端试听合成音效果,用户试听结束后可通过账号系统将音色信息下发到设备;
二、业务流程介绍
三、控制台操作流程
3.1 整体流程
- 首先,打开思必驰DUI开放平台(duiopen.com),创建开发者账号,并登录。
- 第二步,进入“控制台”,创建“基础技术产品”,并勾选“声音复刻”服务。
- 第三步,给创建的产品配置授权参数:选择接入API,创建APIKEY。
- 第四步,获取免费调用量套餐包:用于调试时请求训练接口的用量消耗。
- 第五步,联系思必驰客户经理,配置用于测试的产品。
- 第六步,体验产品(非必须):在产品详情页面,点击“查看配置”,切换到“扫码体验”,使用微信扫一扫小程序码,体验官方声音复刻小程序。
- 第七步,按照快速集成指南,集成思必驰声音复刻云端服务。
调试完成后,联系思必驰客户经理,签署合作协议,思必驰客户经理完成调用量的充值操作。
3.2 创建产品
3.3 创建APIKEY
3.4 获取免费调用量
3.5 体验声音复刻小程序
点击“声音复刻”,进入声音复刻流程。按提示操作。
训练完成之后,即可试听训练好的音色。
四、产品价格
4.1 计费方式
- 按调用量预付费
- 按调用量后付费
4.2 免费额度
声音复刻接口免费额度如下:
接口服务 | 免费并发 | 免费调用次数 | 有效期 |
---|---|---|---|
音色训练 | 2并发 | 10 | 180天 |
说明:
1、声音复刻接口的免费额度自用户在思必驰开放平台控制台领取后生效
2、有效期自领取成功之日开始计算,有效期截止后,免费调用次数清零
4.3 产品定价
请联系思必驰客户经理,获取报价。
五、快速集成指南
调用说明
接口访问地址:https://s-ezvc.duiopen.com
注意:所有接口均需进行用户鉴权,即query参数均包含对应环境的合法productId,并且已经完成了用户账户体系和与思必驰账户体系的打通。
完整的请求示例:https://s-ezvc.duiopen.com/voiceclone/api/v1/clone?productId=299972200
|
检测噪声
仅作为录音前环境噪音检测参考,(过时接口,推荐端侧实现该功能,不建议新用户接入)。
请求uri:/api/v1/task/getDB
请求方式:GET
调用方向:端侧 –> 思必驰云
Ø Header参数:
参数名称 |
类型 |
必须 |
备注 |
示例 |
Content-Type |
multipart/form-data |
是 |
|
|
Ø Body参数:
参数名称 |
类型 |
必须 |
备注 |
file |
文件 |
是 |
用户音频,wav格式(16k,16-bit) |
Ø 请求示例:
https://s-ezvc.duiopen.com/api/v1/tasks/getDB?productId=299972200
返回参数:
参数名称 |
类型 |
备注 |
code |
String |
返回码,0表示成功,其他表示异常,见错误码 |
message |
String |
消息 |
data |
String |
分贝值,一般建议50dB以下 |
Ø 返回示例:
{ "code": 0, "data": "59.051450880965604", "message": "success" }
{ "code": 110003, "data": null, "message": "unexpected error" } |
获取默认文本
请求uri:/voiceclone/api/v1/product/{productId}/text
请求方式:GET
调用方向:端侧 –> 思必驰云
Ø Path参数:
参数名称 |
类型 |
必须 |
备注 |
示例 |
productId |
String |
是 |
DUI平台注册的基础技术产品(包含声音复刻功能)的ID |
299972200 |
Ø 请求示例:
https://s-ezvc.duiopen.com/voiceclone/api/v1/product/299972200/text
返回参数:
参数名称 |
类型 |
备注 |
code |
String |
返回码,0表示成功,其他表示异常,见错误码 |
message |
String |
错误描述 |
data |
Object[] |
文本结果 |
data.textId |
String |
音频文本Id |
data.readText |
String |
音频文本 |
data.selected |
Integer |
是否选中,1:已选中 |
Ø 返回示例:
{ "code": "0", "data": [ { "readText": "园子里,田野里,瞧去,一大片一大片满是的。", "selected": 1, "textId": "9" } ], "detailCode": "", "message": "success", "ok": true } |
创建任务
请求uri:/voiceclone/api/v1/clone
请求方式:POST
调用方向:端侧 –> 思必驰云
Ø Headers:
参数名称 |
参数值 |
必须 |
备注 |
Content-Type |
application/json |
是 |
|
Ø Body参数:
参数名称 |
类型 |
必须 |
备注 |
userId |
String |
是 |
不接受特殊字符,如| _ &等 |
name |
String |
是 |
任务名/音色名称 |
gender |
String |
是 |
性别: MALE, FEMALE, BOY, GIRL |
age |
String |
是 |
年龄: ADULT, CHILD |
lang |
String |
否 |
默认chn |
productId |
String |
是 |
复刻产品id |
Ø 请求示例:
http://s-ezvc.duiopen.com/voiceclone/api/v1/clone?productId=299972200
{ "productId": "299972200", "userId": "100012345", "name": "我的音色01", "gender": "MALE", "age": "ADULT" } |
Ø 返回参数:
参数名称 |
类型 |
备注 |
code |
String |
返回码,0表示成功,其他表示异常,见错误码 |
message |
String |
错误描述 |
data |
Object |
复刻任务基础信息 |
data.id |
Integer |
任务编号 |
data.userId |
String |
用户Id |
data.name |
String |
任务名称/音色名 |
data.gender |
String |
性别 |
data.age |
String |
年龄 |
返回示例:
{ "code": "0", "data": { "age": "ADULT", "gender": "MALE", "id": 255, "name": "我的音色01", "userId": "100012345" }, "detailCode": "", "message": "success", "ok": true } |
更新任务
请求uri:/voiceclone/api/v1/clone /{id}/optimize
请求方式:POST
调用方向:端侧 –> 思必驰云
Ø Headers:
参数名称 |
参数值 |
必须 |
备注 |
Content-Type |
application/json |
是 |
|
Ø Path参数:
参数名称 |
类型 |
必须 |
备注 |
示例 |
id |
Integer |
是 |
任务编号 |
255 |
Ø Body参数:
参数名称 |
类型 |
必须 |
备注 |
userId |
String |
是 |
不接受特殊字符,如| _ &等 |
name |
String |
否 |
新的音色名称 |
Ø 请求示例:
https://s-ezvc.duiopen.com/voiceclone/api/v1/clone/255/optimize?productId=299972200
{ "userId": "100012345", "name": "新音色名" } |
Ø 返回参数:
参数名称 |
类型 |
备注 |
code |
String |
返回码,0表示成功,其他表示异常,见错误码 |
message |
String |
错误描述 |
data |
Object |
复刻任务基础信息 |
data.id |
Integer |
复刻任务编号 |
data.userId |
String |
用户Id |
data.name |
String |
任务名称/音色名 |
data.gender |
String |
性别 |
data.age |
String |
年龄 |
返回示例:
{ "code": "0", "data": { "age": "ADULT", "gender": "MALE", "id": 255, "name": "新音色名", "userId": "100012345" }, "detailCode": "", "message": "success", "ok": true } |
检测录音
请求uri:/voiceclone/api/v1/clone/{id}/audio/{textId}/upload
请求方式:POST
调用方向:端侧 –> 思必驰云
备注:音频保留一段时间,重复提交成功的音频会覆盖前面的音频
Ø Headers:
参数名称 |
参数值 |
必须 |
备注 |
Content-Type |
multipart/form-data |
是 |
|
Ø Path参数:
参数名称 |
类型 |
必须 |
备注 |
示例 |
id |
Integer |
是 |
|
255 |
textId |
String |
是 |
|
00000031 |
Ø Body参数:
参数名称 |
类型 |
必须 |
备注 |
file |
文件 |
是 |
用户音频,wav格式 |
Ø 请求示例:
https://s-ezvc.duiopen.com/voiceclone/api/v1/clone/255/audio/00000031/upload?productId=299972200
Ø 返回参数:
参数名称 |
类型 |
备注 |
code |
String |
返回码,0表示成功,其他表示异常,见错误码 |
message |
String |
错误描述 |
data |
Object |
音频检测结果 |
data.valid |
Integer |
音频是否可用,0:是,1:否 |
data.matchPercent |
Integer |
音频、文本匹配度 |
data.highText |
String |
<mark></mark>标记为匹配失败的文本段 |
Ø 返回示例:
{ "code": "0", "message": "success", "data": { "valid": 0, "matchPercent": 97, "highText": "只有中间的吧台,和角落上一个小小的表演圆台,被<mark>橙黄</mark>的牛眼灯照射着。" }, "detailCode": "", "ok": true } |
提交任务(开始训练)
请求uri:/voiceclone/api/v1/clone/{id}/commit
请求方式:POST
调用方向:端侧 –> 思必驰云
Ø Path参数:
参数名称 |
类型 |
必须 |
备注 |
示例 |
id |
String |
是 |
复刻任务编号 |
255 |
请求示例:
https://s-ezvc.duiopen.com/voiceclone/api/v1/clone/255/commit?productId=299972200
Ø 返回参数:
参数名称 |
类型 |
备注 |
code |
String |
返回码,0表示成功,其他表示异常,见错误码 |
message |
String |
错误描述 |
data |
Object |
空 |
Ø 返回示例:
{ "code": "0", "message": "success", "data": null, "detailCode": "", "ok": true } |
查询音色列表
请求uri:/voiceclone/api/v1/user/{userId}/voices
请求方式:GET
调用方向:端侧 –> 思必驰云
Ø Path参数:
参数名称 |
类型 |
必须 |
备注 |
userId |
String |
是 |
|
Ø Query参数:
参数名称 |
类型 |
必须 |
备注 |
productId |
String |
是 |
|
Ø 请求示例:
https://s-ezvc.duiopen.com/voiceclone/api/v1/user/100012345/voices?productId=299972200
Ø 返回参数:
参数名称 |
类型 |
备注 |
code |
String |
返回码,0表示成功,其他表示异常,见错误码 |
message |
String |
错误描述 |
data |
Object[] |
复刻声音列表 |
data.age |
String |
年龄 |
data.gender |
String |
性别 |
data.id |
Integer |
复刻任务编号 |
data.userId |
Strign |
用户id |
data.name |
String |
音色名称 |
data.voiceId |
String |
音色Id,用于合成音频的数据 |
data.trainState |
String |
训练状态,0:无效训练 1:训练成功 2:训练中 3:训练失败 |
data.pretts |
Object[] |
试听音列表 |
data.offlineModelUrl |
String |
离线模型下载地址 |
Ø 返回示例:
{ "code": "0", "message": "success", "data": [ { "age": "ADULT", "createTime": "2021-07-01T15:16:57", "gender": "MALE", "id": 255, "userId": “100012345”, "name": "新的音色", "trainState": "1", "voiceId": "5491685dbf244b1c", " pretts ": [{ "text": "xxx", //文本 "url": "http://xxxx", //播放地址 } ], "offlineModelUrl": "http://xxxx/xxx/" } ] } |
删除音色
请求uri:/voiceclone/api/v1/voice/{id}
请求方式:DELETE
调用方向:端侧 –> 思必驰云
Ø Path参数:
参数名称 |
类型 |
必须 |
备注 |
示例 |
id |
Integer |
是 |
复刻任务编号 |
255 |
Ø Query参数:
参数名称 |
类型 |
必须 |
备注 |
userId |
String |
是 |
用户id |
请求示例:
https://s-ezvc.duiopen.com/voiceclone/api/v1/voice/255?productId=299972200
Ø 返回参数:
参数名称 |
类型 |
备注 |
code |
String |
返回码,0表示成功,其他表示异常,见错误码 |
message |
String |
错误描述 |
data |
Object |
空 |
Ø 返回示例:
{ "code": "0", "message": "success", "data": null } |
推送完成的任务
请求url:http://IP:PORT/xxx/xxx (客户提供云端回调地址)。
请求方式:POST
调用方向:思必驰云 –> 客户云
Ø 请求参数:
参数名称 |
类型 |
位置 |
必须 |
备注 |
Authorization |
String |
header |
是 |
Authorization用作鉴权,由客户提供 |
id |
Long |
body |
是 |
复刻任务编号 |
voiceId |
String |
body |
是 |
复刻音色id |
userId |
String |
body |
是 |
复刻发起人 |
productId |
String |
body |
是 |
复刻产品编号 |
status |
String |
body |
是 |
训练状态1-成功,其他-失败 |
finishTime |
String |
body |
是 |
训练完成时刻 |
preTtsList |
List |
body |
是 |
试听音频列表 |
message |
String |
body |
是 |
附加消息 |
Ø 请求示例:http://IP:PORT/xxx/xxxx
{ "finishTime": "2023-11-10 11:43:06", "message": "complete_train", "preTtsList": [ { "text": "你好,我是你定制的专属声音,很高兴为你服务。", "url": "xxxxxx" } ], "productId": "299972200", "status": "1", "userId": "100012345", "id": 255, "voiceId": "ezvc_75a6a3ac2fac7047" } |
Ø 返回参数:
参数名称 |
类型 |
备注 |
code |
String |
返回码,0表示成功收到推送 |
message |
String |
错误描述 |
data |
Object |
|
Ø 返回示例:
{ "code": "0", "message": "success", "data": "" } |
错误码
100201 |
服务器内部请求失败 |
100301 |
文件为空 |
100302 |
接收训练任务失败 |
100305 |
不存在该产品的配置 |
100307 |
可供训练的录音文件不足 |
103103 |
参数错误 |
103191 |
服务器内部错误 |
100210 |
任务不存在 |
100211 |
删除音色失败:数据校验失败 |