個性化人聲定制服務可以幫助您通過少量的錄音,訓練得到自己的聲音模型,快速“克隆”個性化的聲音,進而使用該聲音講故事、播天氣、讀小說、導航播報等。本文介紹如何通過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接口使用。 | 登錄阿里云智能語音交互控制臺,選擇服務管理與開通長文本語音合成,單擊升級商用版。 | 在長文本語音合成區域,選擇商用,商用后為付費使用服務。 | 更多異步長文本語音合成接口內容,請參見接口說明。 | |
更多實時長文本語音合成接口內容,請參見接口說明。 |