# 一、接口说明

用户录音上传后,如果有空闲训练资源,最快20分钟之内模型训练结束;如果训练资源紧张,采用排队等待机制;训练发起方可采用轮询方式查询训练进度。

# 二、接口Demo

Java示例demo (opens new window)
python3示例demo (opens new window)

# 三、接口要求

接入声音克隆API时,需按照以下要求:

内容
说明
请求协议 http[s](为提高安全性,强烈推荐https)
请求域名 http[s]: //ai-api.hivoice.cn/api/clone/ai-voice-clone-train
接口鉴权 签名机制,详情请参照下方接口鉴权
字符编码 UTF-8
响应格式 统一采用JSON格式
开发语言 任意
操作系统 任意
音频属性 采样率22k采样率,采样深度16bit、单声道
音频格式 wav、pcm
声音类型 男声、女声、童声

# 四、接口调用流程

如下参数需要在header中传递

参数名称 参数类型 是否必填 参数说明
appKey String Y 调用者应用的appKey
timestamp String Y 时间戳字段(毫秒)
signature String Y 签名,参考如下签名加密函数,签名字段:appKey、timestamp、appsercret(顺序不可变)

# 1. 签名加密函数

# 1.1 加密流程

A)将appKey,timestamp,appsercret的参数值按照自然顺序拼接成字符串,注意:计算signature时所有参数不应进行URLEncode;

B)将A形成字符串获取SHA256摘要,形成一个64位的十六进制(字母大写)字符串,即为本次请求signature(签名)的值;

# 1.2 构造签名算法的JAVA代码示例

public static void main(String[] args) throws Exception {
    String appKey = "45gn7md5n44******gv75saomys";
    String timestamp = System.currentTimeMillis()+"";
    String appSecret = "ba24a917a******b82a72e0d896";
 
    List<String> paramsList =
    Arrays.asList(
            appKey,
            timestamp,
            appSecret
    );
 
    System.out.println(buildSignature(paramsList));
}
 
public static String buildSignature(List<String> paramsList) {
    StringBuilder sb = new StringBuilder();
    for (String param : paramsList) {
        sb.append(param);
    }
    return getSHA256Digest(sb.toString());
}
 
private static String getSHA256Digest(String data) {
    String digest = null;
    try {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] bytes = md.digest(data.getBytes("UTF-8"));
        digest = byte2hex(bytes);
    } catch (Exception e) {
        logger.error("get bytes error ", e);
    }
    return digest;
}
 
private static String byte2hex(byte[] bytes) {
    StringBuilder sign = new StringBuilder();
    for (int i = 0; i < bytes.length; i++) {
        String hex = Integer.toHexString(bytes[i] & 0xFF);
        if (hex.length() == 1) {
            sign.append("0");
        }
        sign.append(hex.toUpperCase());
    }
    return sign.toString();
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

# 2. 获取默认文本

请求uri:/voiceclone/v1/text

请求方式:POST

Headers:

参数名称 参数值 是否必填 备注
Content-Type application/json Y

Body参数:无

返回参数:

参数名称 参数类型 备注
code String 返回码,0表示成功,其他表示异常,见错误码
msg String 错误描述
data Object[] 文本结果
data.textId String 音频文本Id
data.readText String 音频文本
data.readUrl String 样音url

返回示例

{
    "code": "0",
    "data": [
        {
            "readText": "园子里,田野里,瞧去,一大片一大片满是的。"
            "textId": "00000031",
			"readUrl":"xxxxxx"
        },
        {
            "readText": "坐着,躺着,打两个滚,踢几脚球,赛几趟跑,捉几回迷藏。",
            "textId": "00000032",
			"readUrl":"xxxxxx"
        },
        {
            "readText": "风轻悄悄的,草绵软软的。",
            "textId": "00000033",
			"readUrl":"xxxxxx"
        }

    ],
    "msg": "success"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 3. 创建克隆任务

请求uri:/voiceclone/v1/task

请求方式:POST

Headers:

参数名称 参数值 是否必填 备注
Content-Type application/json Y

Body参数:

参数名称 参数类型 是否必须 备注
user_id String Y 接入方需保证用户ID唯一性
name String Y 克隆任务名称
gender Integer Y 性别,0:男 1:女
age Integer Y 年龄,0:成年(>=12) 1:儿童(<12,内测中)

请求示例

{
    "user_id": "abc",
    "name": "name",
    "gender": 0,
    "age": 0
}
1
2
3
4
5
6

返回参数:

参数名称 参数类型 备注
code String 返回码,0表示成功,其他表示异常,见错误码
msg String 错误描述
data Object 文本结果
data.id String 克隆任务Id
data.user_id String 用户Id
data.name String 克隆任务名称
data.gender Integer 性别
data.age Integer 年龄

返回示例

{
    "code": "0",
    "data": {
        "age": 0,
        "gender": 0,
        "id": "252",
        "name": "name",
        "user_id": "abc"
    },
    "msg": "success"
}
1
2
3
4
5
6
7
8
9
10
11

# 4. 音频提交检测

请求uri:/voiceclone/v1/task/{id}/audio/{textId}/upload

请求方式:POST

Headers:

参数名称 参数值 是否必填 备注
Content-Type multipart/form-data Y

Path参数:

参数名称 参数类型 是否必填 备注
id String Y 克隆任务id
textId String Y 默认文本id

Body参数(文件以表单形式上传):

参数名称 参数类型 是否必填 备注
file 文件 Y 用户音频

返回参数:

参数名称 参数类型 备注
code String 返回码,0表示成功,其他表示异常,见错误码
msg String 错误描述
data Object 音频检测结果
data.valid Integer 音频是否可用,0:是,1:否
data.matchPercent Integer 音频、文本匹配度
data.highText String 标记为匹配失败的文本段

返回示例

{
    "code": "0",
    "msg": "success",
    "data": {
        "valid": 0,
        "matchPercent": 97,
        "highText": "只有中间的吧台,和角落上一个小小的表演圆台,被<mark>橙黄</mark>的牛眼灯照射着。"
}
}
1
2
3
4
5
6
7
8
9

# 5. 录制完成提交训练任务

请求uri:/voiceclone/v1/task/{id}/commit

请求方式:POST

Headers:

参数名称 参数值 是否必填 备注
Content-Type application/json Y

Path参数:

参数名称 参数类型 是否必填 备注
id String Y 克隆任务编号

Body参数:无

返回参数:

参数名称 参数类型 备注
code String 返回码,0表示成功,其他表示异常,见错误码
msg String 错误描述
data Object

返回示例:

{
    "code": "0",
    "msg": "success"
}
1
2
3
4

# 6. 我的声音列表接口

请求uri:/voiceclone/v1/user/{user_id}/voices

请求方式:POST

Headers:

参数名称 参数值 是否必填 备注
Content-Type application/json Y

Path参数:

参数名称 参数类型 是否必填 备注
user_id String Y 用户唯一标识

Body参数:无

返回参数:

参数名称 参数类型 备注
code String 返回码,0表示成功,其他表示异常,见错误码
msg String 错误描述
data Object[] 克隆声音列表
data.age Integer 年龄
data.gender Integer 性别
data.id String 克隆任务Id
data.name String 克隆任务名称
data.voiceId String 音色Id,用于合成音频的数据
data.trainState Integer 训练状态,0:无效训练 1:训练成功 2:训练中 3:训练失败 4:已过期 5:已删除
data.errorCode String 训练失败的唯一码
data.errorMsg String 训练失败的描述信息

返回示例:

{
    "code": "0",
    "msg": "success",
    "data": [
        {
            "age": 0,
            "createTime": "2022-11-23 18:21:00",
            "gender": 0,
            "id": "abc",
            "name": "bbk",
            "trainState": 1,
            "voiceId": "5491685dbf244b1cbd2ce99a045c467b",
			"errorCode":"20481",
			"errorMsg":""
        }
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 7. 删除声音

请求uri:/voiceclone/v1/voice/delete/{id}

请求方式:post

Headers:

参数名称 参数值 是否必填 备注
Content-Type application/json Y

Path参数:

参数名称 参数类型 是否必填 备注
id String Y 克隆任务编号

Body参数:无

返回参数:

参数名称 参数类型 备注
code String 返回码,0表示成功,其他表示异常,见错误码
msg String 错误描述
data Object

返回示例

{
    "code": "0",
    "msg": "success"
}
1
2
3
4

# 8. 查询训练状态

此接口需要调用方轮训请求

请求uri:/voiceclone/v1/task/status/{id}

请求方式:post

参数名称 参数值 是否必填 备注
Content-Type application/json Y

Path参数:

参数名称 参数类型 是否必填 备注
id String Y 克隆任务编号

Body参数:无

响应结果

参数名称 参数类型 备注
code String 返回码,0表示成功,其他表示异常,见错误码
msg String 错误描述
data Object 克隆声音列表
data.trainState Integer 训练状态,0:无效训练 1:训练成功 2:训练中 3:训练失败 4:已过期 5:已删除
data.modelAddress String 离线模型下载地址,仅限离线合成场景使用
data.errorCode String 训练失败的唯一码
data.errorMsg String 训练失败的描述信息

返回示例

{
    "code": "0",
    "msg": "success",
    "data": {
        "trainState": 1,
        "modelAddress": "https://xxxxxx",
		"errorCode":"20481",
		"errorMsg":""
	}
}
1
2
3
4
5
6
7
8
9
10

# 9. 环境噪音检测

请求uri:/voiceclone/v1/task/checkenv

请求方式:POST

Headers:

参数名称 参数值 是否必填 备注
Content-Type multipart/form-data Y

Body参数(文件以表单形式上传):

参数名称 参数类型 是否必填 备注
file 文件 Y 环境检测音频

返回参数:

参数名称 参数类型 备注
code String 返回码,0表示成功,其他表示异常,见错误码
msg String 错误描述
data Object 音频检测结果
data.envDecibel Integer 环境噪音分贝值
data.valid Integer 样音检测编码,0:声音检测成功,1:环境检测不通过(声音大于20分贝)

返回示例

{
    "code": "0",
    "msg": "success",
    "data": {
        "envDecibel": 20,
        "valid": 1
	}
}
1
2
3
4
5
6
7
8

# 五、错误码

错误码 说明 解决办法
0 成功
20401 appkey不存在 检查appkey是否配置正确
20402 请求参数错误 客户端检查参数是否正确
20403 文件为空 检查音频文件是否存在
20404 训练任务提交失败 检查任务编号是否正确
20405 可供训练的录音文件不足 音频文件不能少于20
20406 套餐已用完 购买时长套餐
20407 环境噪音检测不通过 找个安静地方录制音频
20408 训练中的任务不允许删除 训练完成后可删除
20499 服务器内部错误 建议重试,或者提工单,工单详情请提供任务编号