个性化人声定制服务可以帮助您通过少量的录音,训练得到自己的声音模型,快速“克隆”个性化的声音,进而使用该声音讲故事、播天气、读小说、导航播报等。本文介绍如何通过OpenAPI定制个性化人声。
通过OpenAPI定制
您可以通过使用智能语音交互服务提供的OpenAPI,将个性化人声定制功能集成在您自己的产品当中。集成后,即可通过接口来实现声音定制的功能。
个性化人声定制的步骤
以智能语音交互实现的页面举例以上步骤(红框部分)。
OpenAPI概览
对应定制步骤 | 接口名称 | 参数 | 参数说明 | 返回结果示例 | 返回结果说明 | 备注 |
1 | GetDemonstrationForCustomizedVoice | Scenario | 场景,取值范围如下:
|
| 通过本接口来获取需要给用户朗读的文本及示例音频。
| 您可以获取相关文案及音频地址进行缓存,再次使用为可选接口。 |
2 | CustomizedVoiceAudioDetect | Scenario | 场景,取值范围如下:
|
| 本接口用来检测用户的朗读是否有明显的发音错误、嘈杂的环境等。
| 云端在进行完音频检测后,对于检测合格的音频会暂存在云端,供后续训练声音时使用,请勿省略该步骤。 |
VoiceName | 您自定义的声音名称,不能和您其他的定制声音重名。支持15个字符以内的英文、汉字或数字。 | |||||
RecordUrl | 录音文件地址。 | |||||
AudioRecordId | RecordUrl对应的音频序号,取值范围为[1,20]。例如故事场景下,用户朗读的“希望我们大家都能像他一样”这句话,对应序号为1。 | |||||
3 | SubmitCustomizedVoice | VoiceName | 您自定义的声音名称,不能和您其他的定制声音重名。支持15个字符以内的英文、汉字或数字。 |
| 提交合成,VoiceName需要与音频检测时传递至云端的一致,云端依赖此参数寻找暂存的音频进行训练。 | 无 |
Gender | 性别,取值范围如下:
| |||||
Scenario | 场景,取值范围如下:
| |||||
4 | ListCustomizedVoice | VoiceName | 您在提交合成时自定义的声音名称。 |
| 您可以在提交合成后,通过查询此接口的方式来检查是否合成完成,返回结果中的Status字段为合成状态,取值范围为:WAIT,合成中; SUCCESS,合成完成;FAILED,合成失败。当状态为合成失败时,您可以通过ErrorMessage字段获取失败的原因。 合成成功后,您可以通过ModelId字段作为voiceName调用克隆的声音模型 | 无 |
准备音频文件
音频格式要求
支持的输入格式:单声道(mono)16bit采样位数音频,包括无压缩的PCM、WAV格式。
音频采样率:16000 Hz、24000 Hz、48000 Hz。
音频保存
SDK
个性化人声定制的OpenAPI均通过阿里云CommonRequest进行调用,SDK可从如下文档中获取:
如果您无法使用上述语言提供的基础SDK进行调用,则可以参照RPC 调用机制自行构造HTTP请求进行调用。因自行构造HTTP请求涉及签名等复杂机制,强烈建议您尽量使用基础SDK进行调用。
OpenAPI调用基础参数
地域 | 调用参数 |
华东2(上海) |
|
示例代码
调用接口前,需配置环境变量,通过环境变量读取访问凭证。智能语音交互的AccessKey ID和AccessKey Secret的环境变量名:ALIYUN_AKID和ALIYUN_AKKEY。
示例音频
为了方便您快速了解OpenAPI的调用流程,我们提供了如下示例音频供您运行示例代码使用,该音频为故事(story)场景。
1. https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/viwf/1.wav
2. https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/dycw/2.wav
3. https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/dopl/3.wav
4. https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/anfd/4.wav
5. https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/cyoy/5.wav
6. https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/dsjw/6.wav
7. https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/vevd/7.wav
8. https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/ulno/8.wav
9. https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/kwlw/9.wav
10. https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/lafu/10.wav
11. https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/uozh/11.wav
12. https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/gdpp/12.wav
13. https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/lisa/13.wav
14. https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/bmvv/14.wav
15. https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/ijzx/15.wav
16. https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/kdla/16.wav
17. https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/govf/17.wav
18. https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/kcid/18.wav
19. https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/srdx/19.wav
20. https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/stol/20.wav
Java
相关依赖,请参见SDK核心依赖。
package com.alibaba.nls.ptts;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
public class PttsDemo {
//域名
private static final String DOMAIN = "nls-measure.cn-shanghai.aliyuncs.com";
// API版本
private static final String API_VERSION = "2019-09-05";
private static IAcsClient client;
static {
// 创建DefaultAcsClient实例并初始化
DefaultProfile profile = DefaultProfile.getProfile(
"",
System.getenv("ALIYUN_AKID"),
System.getenv("ALIYUN_AKKEY"));
client = new DefaultAcsClient(profile);
}
public static void main(String[] args) throws InterruptedException {
//20句音频,此处为了方便演示接口的调用,提前准备好了音频的url,在您集成时,可以在用户录制的过程中,将音频进行存储
String[] urls = {"viwf/1.wav", "dycw/2.wav", "dopl/3.wav", "anfd/4.wav", "cyoy/5.wav", "dsjw/6.wav",
"vevd/7.wav", "ulno/8.wav", "kwlw/9.wav", "lafu/10.wav", "uozh/11.wav", "gdpp/12.wav", "lisa/13.wav",
"bmvv/14.wav", "ijzx/15.wav", "kdla/16.wav", "govf/17.wav", "kcid/18.wav", "srdx/19.wav", "stol/20.wav"};
//训练的基本信息,voiceName请替换成您自己的命名
String voiceName = "示例voice";
String scenario = "story";
String gender = "female";
//Step1: 获取需要朗读的文本
CommonRequest getDemonstrationRequest = buildRequest("GetDemonstrationForCustomizedVoice");
getDemonstrationRequest.putQueryParameter("Scenario", scenario);
String getDemonstrationResponse = sendRequest(getDemonstrationRequest);
System.out.println("|获取需要朗读的内容|response=" + getDemonstrationResponse);
//Step2: 采集用户朗读的音频,进行音频检测
for (int i = 1; i <= 20; i++) {
String audioUrl = audioRecordUrlPrefix + urls[i - 1];
CommonRequest audioDetectRequest = buildRequest("CustomizedVoiceAudioDetect");
audioDetectRequest.putQueryParameter("Scenario", scenario);
audioDetectRequest.putQueryParameter("VoiceName", voiceName);
audioDetectRequest.putQueryParameter("RecordUrl", audioUrl);
audioDetectRequest.putQueryParameter("AudioRecordId", String.valueOf(i));
String audioDetectResponse = sendRequest(audioDetectRequest);
System.out.println("|音频检测|[" + i + "]response=" + audioDetectResponse);
}
//Step3: 20句音频检测完成后,提交训练
CommonRequest submitTrainRequest = buildRequest("SubmitCustomizedVoice");
submitTrainRequest.putQueryParameter("VoiceName", voiceName);
submitTrainRequest.putQueryParameter("Gender", gender);
submitTrainRequest.putQueryParameter("Scenario", scenario);
String submitTrainResponse = sendRequest(submitTrainRequest);
System.out.println("|提交训练|response=" + submitTrainResponse);
//Step4: 轮询训练结果
CommonRequest queryTrainResultRequest = buildRequest("ListCustomizedVoice");
queryTrainResultRequest.putQueryParameter("VoiceName", voiceName);
String queryTrainResultResponse = sendRequest(queryTrainResultRequest);
System.out.println("|查询训练结果|response=" + queryTrainResultResponse);
}
private static String audioRecordUrlPrefix
= "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/";
private static CommonRequest buildRequest(String popApiName) {
CommonRequest request = new CommonRequest();
request.setSysMethod(MethodType.POST);
request.setSysDomain(DOMAIN);
request.setSysVersion(API_VERSION);
request.setSysAction(popApiName);
request.setSysProtocol(ProtocolType.HTTPS);
return request;
}
private static String sendRequest(CommonRequest request) {
try {
CommonResponse response = client.getCommonResponse(request);
return response.getData();
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
e.printStackTrace();
}
return null;
}
}
Python
依赖安装方式
pip install aliyun-python-sdk-core
代码
import os
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.http import method_type
from aliyunsdkcore.request import CommonRequest
# api基础信息
client = AcsClient(os.environ.get('ALIYUN_AKID'),
os.environ.get('ALIYUN_AKKEY'))
domain = 'nls-measure.cn-shanghai.aliyuncs.com'
version = '2019-09-05'
# voice训练基础信息
scenario = 'story'
gender = 'female'
voice_name = '示例voice'
# 训练用音频示例,请替换为您自己的音频
audio_record_prefix = 'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/'
audio_records = ['viwf/1.wav', 'dycw/2.wav', 'dopl/3.wav', 'anfd/4.wav', 'cyoy/5.wav', 'dsjw/6.wav', 'vevd/7.wav',
'ulno/8.wav', 'kwlw/9.wav', 'lafu/10.wav', 'uozh/11.wav', 'gdpp/12.wav', 'lisa/13.wav', 'bmvv/14.wav',
'ijzx/15.wav', 'kdla/16.wav', 'govf/17.wav', 'kcid/18.wav', 'srdx/19.wav', 'stol/20.wav']
def build_request(api_name):
request = CommonRequest()
request.set_domain('nls-measure.cn-shanghai.aliyuncs.com')
request.set_version('2019-09-05')
request.set_action_name(api_name)
request.set_method(method_type.POST)
return request
if __name__ == '__main__':
# step1: 获取需要朗读的文本
get_demonstration_request = build_request(
'GetDemonstrationForCustomizedVoice')
get_demonstration_request.add_query_param('Scenario', scenario)
get_demonstration_response = client.do_action_with_exception(
get_demonstration_request)
print(get_demonstration_response)
# step2:声音检测
for audio_record_id in range(1, 21):
audio_record_url = audio_record_prefix + \
audio_records[audio_record_id-1]
audio_detect_request = build_request('CustomizedVoiceAudioDetect')
audio_detect_request.add_query_param('Scenario', scenario)
audio_detect_request.add_query_param('VoiceName', voice_name)
audio_detect_request.add_query_param('RecordUrl', audio_record_url)
audio_detect_request.add_query_param('AudioRecordId', audio_record_id)
audio_detect_response = client.do_action_with_exception(
audio_detect_request)
print(audio_record_id)
print(audio_detect_response)
# step3: 提交训练
submit_train_request = build_request('SubmitCustomizedVoice')
submit_train_request.add_query_param('Scenario', scenario)
submit_train_request.add_query_param('VoiceName', voice_name)
submit_train_request.add_query_param('Gender', gender)
submit_train_response = client.do_action_with_exception(
submit_train_request)
print(submit_train_response)
# step4: 查询训练结果
query_train_result_request = build_request('ListCustomizedVoice')
query_train_result_request.add_query_param('VoiceName', voice_name)
query_train_result_response = client.do_action_with_exception(
query_train_result_request)
print(query_train_result_response)
Go
依赖安装方式
go get -u github.com/aliyun/alibaba-cloud-sdk-go/sdk
代码
package main
import (
"os"
"fmt"
"strconv"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
)
func main() {
//初始化客户端
client, err := sdk.NewClientWithAccessKey("cn-hangzhou", os.Getenv("ALIYUN_AKID"), os.Getenv("ALIYUN_AKKEY"))
if err != nil {
panic(err)
}
//API信息
const DOMAIN string = "nls-measure.cn-shanghai.aliyuncs.com"
const API_VERSION string = "2019-09-05"
// voice训练基本信息
var scenario = "story"
var gender = "female"
var voiceName = "示例voice"
//
var audioRecords = [20]string{
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/viwf/1.wav",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/dycw/2.wav",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/dopl/3.wav",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/anfd/4.wav",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/cyoy/5.wav",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/dsjw/6.wav",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/vevd/7.wav",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/ulno/8.wav",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/kwlw/9.wav",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/lafu/10.wav",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/uozh/11.wav",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/gdpp/12.wav",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/lisa/13.wav",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/bmvv/14.wav",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/ijzx/15.wav",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/kdla/16.wav",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/govf/17.wav",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/kcid/18.wav",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/srdx/19.wav",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/stol/20.wav",
}
// step1: 获取需要朗读的文本
getDemonstrationRequest := requests.NewCommonRequest()
getDemonstrationRequest.Domain = DOMAIN
getDemonstrationRequest.Version = API_VERSION
getDemonstrationRequest.ApiName = "GetDemonstrationForCustomizedVoice"
getDemonstrationRequest.Method = "POST"
getDemonstrationRequest.QueryParams["Scenario"] = scenario
postResponse, err := client.ProcessCommonRequest(getDemonstrationRequest)
if err != nil {
panic(err)
}
postResponseContent := postResponse.GetHttpContentString()
fmt.Println(postResponseContent)
// step2:声音检测
for i := 1; i <= 20; i++ {
audioDetectRequest := requests.NewCommonRequest()
audioDetectRequest.Domain = DOMAIN
audioDetectRequest.Version = API_VERSION
audioDetectRequest.ApiName = "CustomizedVoiceAudioDetect"
audioDetectRequest.Method = "POST"
audioDetectRequest.QueryParams["Scenario"] = scenario
audioDetectRequest.QueryParams["VoiceName"] = voiceName
audioDetectRequest.QueryParams["RecordUrl"] = audioRecords[i-1]
audioDetectRequest.QueryParams["AudioRecordId"] = strconv.Itoa(i)
audioDetectResponse, err := client.ProcessCommonRequest(audioDetectRequest)
if err != nil {
panic(err)
}
postResponseContent := audioDetectResponse.GetHttpContentString()
fmt.Println(postResponseContent)
}
// step3: 提交训练
submitTrainRequest := requests.NewCommonRequest()
submitTrainRequest.Domain = DOMAIN
submitTrainRequest.Version = API_VERSION
submitTrainRequest.ApiName = "SubmitCustomizedVoice"
submitTrainRequest.Method = "POST"
submitTrainRequest.QueryParams["Scenario"] = scenario
submitTrainRequest.QueryParams["VoiceName"] = voiceName
submitTrainRequest.QueryParams["Gender"] = gender
submitTrainResponse, err := client.ProcessCommonRequest(submitTrainRequest)
if err != nil {
panic(err)
}
submitTrainResponseContent := submitTrainResponse.GetHttpContentString()
fmt.Println(submitTrainResponseContent)
// step4: 查询训练结果
queryTrainRequest := requests.NewCommonRequest()
queryTrainRequest.Domain = DOMAIN
queryTrainRequest.Version = API_VERSION
queryTrainRequest.ApiName = "ListCustomizedVoice"
queryTrainRequest.Method = "POST"
queryTrainRequest.QueryParams["VoiceName"] = voiceName
queryTrainResponse, err := client.ProcessCommonRequest(queryTrainRequest)
if err != nil {
panic(err)
}
queryTrainResponseContent := queryTrainResponse.GetHttpContentString()
fmt.Println(queryTrainResponseContent)
}
PHP
依赖安装方式,请参见SDK核心依赖。
<?php
require __DIR__ . '/vendor/autoload.php';
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
// 创建一个客户端并链式调用设置其它选项
AlibabaCloud::accessKeyClient(getenv('ALIYUN_AKID'), getenv('ALIYUN_AKKEY'))
->regionId('cn-shanghai') // 设置客户端区域,使用该客户端且没有单独设置的请求都使用此设置
->asGlobalClient();
# 训练用音频示例,请替换为您自己的音频
$audio_record_urls = array(
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/viwf/1.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/dycw/2.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/dopl/3.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/anfd/4.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/cyoy/5.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/dsjw/6.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/vevd/7.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/ulno/8.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/kwlw/9.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/lafu/10.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/uozh/11.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/gdpp/12.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/lisa/13.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/bmvv/14.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/ijzx/15.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/kdla/16.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/govf/17.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/kcid/18.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/srdx/19.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/stol/20.wav'
);
# voice训练基础信息
$scenario = 'story';
$gender = 'female';
$voice_name = '示例voice';
try {
# step1: 获取需要朗读的文本
$get_demonstration_request = AlibabaCloud::rpc()
->product('nls-cloud-measure')
->version('2019-09-05')
->action('GetDemonstrationForCustomizedVoice')
->host('nls-measure.cn-shanghai.aliyuncs.com')
->method('POST')
->options([
'query' => [
'Scenario' => $scenario,
],
])
->request();
print_r($get_demonstration_request->toArray());
# step2:声音检测
for ($i = 1; $i <= 20; $i++) {
$audio_detect_request = AlibabaCloud::rpc()
->product('nls-cloud-measure')
->version('2019-09-05')
->action('CustomizedVoiceAudioDetect')
->host('nls-measure.cn-shanghai.aliyuncs.com')
->method('POST')
->options([
'query' => [
'Scenario' => $scenario,
'VoiceName' => $voice_name,
'RecordUrl' => $audio_record_urls[$i-1],
'AudioRecordId' => $i,
],
])->request();
print_r($audio_detect_request->toArray());
}
# step3: 提交训练
$submit_train_request = AlibabaCloud::rpc()
->product('nls-cloud-measure')
->version('2019-09-05')
->action('SubmitCustomizedVoice')
->host('nls-measure.cn-shanghai.aliyuncs.com')
->method('POST')
->options([
'query' => [
'Scenario' => $scenario,
'VoiceName' => $voice_name,
'Gender' => $gender
],
])->request();
print_r($submit_train_request->toArray());
# step4: 查询训练结果
$query_train_result_request = AlibabaCloud::rpc()
->product('nls-cloud-measure')
->version('2019-09-05')
->action('ListCustomizedVoice')
->host('nls-measure.cn-shanghai.aliyuncs.com')
->method('POST')
->options([
'query' => [
'VoiceName' => $voice_name,
],
])->request();
print_r($query_train_result_request->toArray());
} catch (ClientException $exception) {
print_r($exception->getErrorMessage());
} catch (ServerException $exception) {
print_r($exception->getErrorMessage());
}
?>
Node.js
依赖安装方式
var RPCClient = require('@alicloud/pop-core');
var client = new RPCClient({
accessKeyId: process.env.ALIYUN_AKID,
accessKeySecret: process.env.ALIYUN_AKKEY,
endpoint: 'https://nls-measure.cn-shanghai.aliyuncs.com',
apiVersion: '2019-09-05'
});
// voice训练基础信息, voiceName请设置成您自己的名称
var scenario = 'story', gender = 'female', voiceName = '示例voice'
// 训练用音频示例,请替换为您自己的音频
var audioRecordUrls = [
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/viwf/1.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/dycw/2.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/dopl/3.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/anfd/4.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/cyoy/5.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/dsjw/6.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/vevd/7.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/ulno/8.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/kwlw/9.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/lafu/10.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/uozh/11.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/gdpp/12.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/lisa/13.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/bmvv/14.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/ijzx/15.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/kdla/16.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/govf/17.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/kcid/18.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/srdx/19.wav',
'https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20221118/stol/20.wav'];
(async function () {
// step1: 获取需要朗读的文本
var getDemonstrationForCustomizedVoiceParam = {
Scenario: scenario
}
const response1 = await client.request("GetDemonstrationForCustomizedVoice", getDemonstrationForCustomizedVoiceParam, { method: 'POST' })
console.log('step1', JSON.stringify(response1))
// step2: 声音检测
for (var i = 1; i <= 20; i++) {
var audioDetectParam = {
Scenario: scenario,
VoiceName: voiceName,
RecordUrl: audioRecordUrls[i - 1],
AudioRecordId: i
}
const response2 = await client.request("CustomizedVoiceAudioDetect", audioDetectParam, { method: 'POST' })
console.log(`声音检测-${i}`, JSON.stringify(response2))
}
// step3: 提交训练
var submitTrainParam = {
Scenario: scenario,
VoiceName: voiceName,
Gender: gender
}
const response3 = await client.request("SubmitCustomizedVoice", submitTrainParam, { method: 'POST' })
console.log('step3', JSON.stringify(response3))
// step4: 查询训练结果
var queryTrainResultParam = {
VoiceName: voiceName
}
const response4 = await client.request("ListCustomizedVoice", queryTrainResultParam, { method: 'POST' })
console.log('step4', JSON.stringify(response4))
}())
错误码列表
当发生错误时,返回值中的Success字段为false,ErrorCode为此时的错误码,ErrorMessage为错误信息。
ErrorCode | ErrorMessage | 处理方式 |
100001 | Service temporarily unavailable | 服务端错误,此类错误您可以提交工单,发送ResuestId,由工程师进行定位排查。 |
100002 | Illegal record url | 错误的音频文件地址,请确保您传递给OpenAPI的音频文件公网可以访问,且为正确的音频。 |
100004 | Missing record for train | 用于训练的音频数据不完整,请确保20句音频都完成音频检测后再提交训练。 |
100009 | 会包含具体错误的信息,一般为业务错误等 | 根据错误信息修正您的代码。 |
100010 | 您尚未开通智能语音交互服务,无法使用该功能 | 使用接口前,请先开通智能语音交互服务。 |
100012 | 参数错误,会包含具体的参数错误原因 | 根据提示修正您的参数。 |
定制成功后进行语音合成
通过个性化人声定制合成了您想要的声音后,可以试用控制台进行文本转语音,也可以通过接口进行,请您检查以下调用条件是否具备:
如何通过代码调用控制台中定制的音色
定制完成后,推荐您使用语音合成接口调用该声音。更多接口文档,请参见接口说明。
调用定制声音需要在语音合成中将个性化人声的模型调用ID(在阿里云智能语音交互控制台,单击音色试听,在详情页中获取,如下图)填入voice参数,示例代码如下。
synthesizer.setVoice("${模型调用ID}");
您也可以通过实时/异步长文本语音合成来调用,方法同上。更多接口文档,请参见长文本语音合成。
试用期过后,使用方式请见下表。
使用声音合成文本的方式
需要开通服务
开通位置
开通方法
文本转语音方式
控制台界面试用
新开通服务的3个月内,无需开通,免费试听。
免费试听
免费试听
界面操作,下载音频。
控制台界面试用
语音合成
登录阿里云智能语音交互控制台,选择服务管理与开通语音合成,单击升级商用版。
在语音合成区域,选择商用,商用后为付费使用服务。
更多调用相关信息,请参见下表。
调用方式 | 调用服务 | 注意事项 | 操作步骤 | 说明 | |
语音合成 | 若您单次合成内容小于等于300字,请选择语音合成,控制台界面使用文字转语音,仅支持单次300字以内合成。 | 登录阿里云智能语音交互控制台,选择服务管理与开通语音合成,单击升级商用版。 | 在语音合成区域,选择商用,商用后为付费使用服务。 | 更多接口内容,请参见接口说明。 | |
长文本语音合成 | 若您合成内容大于300字,选择长文本语音合成,仅支持SDK或API接口使用。 | 登录阿里云智能语音交互控制台,选择服务管理与开通长文本语音合成,单击升级商用版。 | 在长文本语音合成区域,选择商用,商用后为付费使用服务。 | 更多异步长文本语音合成接口内容,请参见接口说明。 | |
更多实时长文本语音合成接口内容,请参见接口说明。 |