共计 12649 个字符,预计需要花费 32 分钟才能阅读完成。
华为 HMS Core 音频编辑服务(Audio Editor Kit)依靠本身 AI 技术的研发劣势,上线全新的歌声合成音色及伴奏,给音视频创作者提供更多的创作可能。在短视频场景中,用户自定义歌词的歌声联合视频让用户感触到身临其境,自在表白本人的情绪;在虚构偶像场景中,歌声合成性能赋予虚构歌手们演唱风格各异的歌曲,带来创意有限。
HMS Core 音频编辑服务歌声合成的 AI Singer 模型能力通过字级别输出歌词进行音素转换,就能够为用户创作音乐,也可预置曲目合成歌声。通过自研音高模型,让音高曲线在放弃输出曲谱的音高精准度的同时改善天然度,更靠近人的实在演唱。应用最新的生成式模型,带来更好的音色还原度、建模更多的演唱细节,同时高清声码器可能实在还原 48k 高清音质。
另外,用户通过自在调整颤音、滑音、呼吸音等性能,可依据情感需要调整歌声演唱技巧。以后歌声合成服务已凋谢了情风行女声、国风女声和民谣男声音色,将来会继续更新更多音色。
华为 HMS Core 音频编辑服务(Audio Editor Kit)让机器“演唱”出真实度的歌声,仅需简略的集成取得,以下是开发者利用集成音频编辑服务歌声合成能力的具体步骤。
开发步骤
1. 开发筹备
1.1 注册成为开发者
在开发利用前须要在华为开发者联盟网站上注册成为开发者并实现实名认证,具体方法请参见帐号注册认证。
1.2 创立我的项目及利用
参见创立我的项目,而后在我的项目下创立利用实现利用的创立,非凡配置如下:
抉择平台:抉择“Web”。
1.3 关上相干服务
应用 Audio Editor Kit 服务须要您在 AppGallery Connect 上关上 Audio Editor Kit 服务开关,具体操作步骤请参见关上服务开关。
2. 歌声合成性能集成
2.1 同步接口(流式)
2.1.1 获取 access_token 鉴权信息
应用开发者联盟界面取得的客户端 ID 以及对应密钥,发送 HTTPS POST 申请,获取查问 access_token。获取形式请参见客户端模式(Client Credentials)。
2.1.2 调用同步接口(流式)
通过以上步骤获取的 access_token 信息,发送 HTTPS POST 调用同步接口(流式)。
示例代码(Java)如下所示:
其中 requestUrl = “https://audioeditor-api-drcn.cloud.huawei.com/v1/audioeditor/gateway/ai/ttsing/sync”。
请点击下载 MusicXML 文件,并上传:
/**
* 调用同步接口(流式)* @throws Exception IO 异样
*/
private static void syncTask() throws Exception {
// 设置申请 header
PostMethod postMethod = new PostMethod(requestUrl);
// 设置文本类型(String),例:"application/json;charset=utf-8"
postMethod.setRequestHeader("Content-Type", contentType);
// 设置申请 ID(String),例:"9af1aeda-531b-407a-80b4-65b40ef77bd6"
postMethod.setRequestHeader("X-Request-ID", requestId);
// 设置 App 包名(String),例:"com.huawei.demo"
postMethod.setRequestHeader("X-Package-Name", pacageName);
// 设置 App 所在国家(String),例:"cn"
postMethod.setRequestHeader("X-Country-Code", countryCode);
// 设置 App 标识(String),例:"9af1aeda-531b-407a-80b4-65b40ef77bd6"
postMethod.setRequestHeader("HMS-APPLICATION-ID", applicationId);
// 设置证书指纹(String),例:"xxxxxxxxxxxxxxx"
postMethod.setRequestHeader("certFingerprint", certFingerprint);
// 设置动静获取的 AccessToken(String)postMethod.setRequestHeader("Authorization","Bearer" + accessToken);
// 设置申请 body
Map<String, Object> bodyMap = new HashMap<>();
Map<String, Object> dataMap = new HashMap<>();
Map<String, Object> configMap = new HashMap<>();
// filePath 是 MusicXML 文件门路(含文件名、后缀)String lyricFilePath = "filePath";
dataMap.put("lyric", FileUtils.readFileToString(new File(lyricFilePath), "UTF-8"));
dataMap.put("language", "chinese");
configMap.put("type", 1);
configMap.put("outputEncoderFormat", 0);
configMap.put("wordDurationForceAlign", "false");
bodyMap.put("data", dataMap);
bodyMap.put("config", configMap);
RequestEntity requestEntity = new StringRequestEntity(JSONObject.toJSONString(bodyMap),"application/json" ,"UTF-8");
postMethod.setRequestEntity(requestEntity);
HttpClient httpClient = new HttpClient();
int ret = httpClient.executeMethod(postMethod);
if (ret == 200) {Header responseHeader = postMethod.getResponseHeader("content-type");
if ("application/octet-stream".equals(responseHeader.getValue())) {InputStream rpsContent = postMethod.getResponseBodyAsStream();
// filePath 是要保留文件的门路(含文件名、PCM 文件后缀)String filePath = "filePath";
FileUtils.copyInputStreamToFile(rpsContent, new File(filePath));
} else {String errorString = postMethod.getResponseBodyAsString();
System.out.println(errorString);
}
} else {System.out.println("callApi failed: ret =" + ret + "rsp=" + postMethod.getResponseBodyAsString());
}
}
应用预置曲目输出歌词:
/**
* 调用同步接口(流式)* @throws Exception IO 异样
*/
private static void syncTask() throws Exception {
// 设置申请 header
PostMethod postMethod = new PostMethod(requestUrl);
// 设置文本类型(String),例:"application/json;charset=utf-8"
postMethod.setRequestHeader("Content-Type", contentType);
// 设置申请 ID(String),例:"9af1aeda-531b-407a-80b4-65b40ef77bd6"
postMethod.setRequestHeader("X-Request-ID", requestId);
// 设置 App 包名(String),例:"com.huawei.demo"
postMethod.setRequestHeader("X-Package-Name", pacageName);
// 设置 App 所在国家(String),例:"cn"
postMethod.setRequestHeader("X-Country-Code", countryCode);
// 设置 App 标识(String),例:"9af1aeda-531b-407a-80b4-65b40ef77bd6"
postMethod.setRequestHeader("HMS-APPLICATION-ID", applicationId);
// 设置证书指纹(String),例:"xxxxxxxxxxxxxxx"
postMethod.setRequestHeader("certFingerprint", certFingerprint);
// 设置动静获取的 AccessToken(String)postMethod.setRequestHeader("Authorization","Bearer" + accessToken);
// 设置申请 body
Map<String, Object> bodyMap = new HashMap<>();
Map<String, Object> dataMap = new HashMap<>();
Map<String, Object> configMap = new HashMap<>();
String[] lyrics = {"追随心跳的节奏", "感触自在的畅快", "把懊恼统统抛开", "咱们一起嗨", "调整呼吸的节奏", "放弃最好的状态", "奔向夺目的将来", "哦康忙北北"};
dataMap.put("lyrics", lyrics);
dataMap.put("accompanimentId", "1");
dataMap.put("isAutoFill", "false");
dataMap.put("language", "chinese");
configMap.put("type", 1);
configMap.put("outputEncoderFormat", 0);
configMap.put("wordDurationForceAlign", "false");
bodyMap.put("data", dataMap);
bodyMap.put("config", configMap);
RequestEntity requestEntity = new StringRequestEntity(JSONObject.toJSONString(bodyMap),"application/json" ,"UTF-8");
postMethod.setRequestEntity(requestEntity);
HttpClient httpClient = new HttpClient();
int ret = httpClient.executeMethod(postMethod);
if (ret == 200) {Header responseHeader = postMethod.getResponseHeader("content-type");
if ("application/octet-stream".equals(responseHeader.getValue())) {InputStream rpsContent = postMethod.getResponseBodyAsStream();
// filePath 是要保留文件的门路(含文件名、PCM 文件后缀)String filePath = "filePath";
FileUtils.copyInputStreamToFile(rpsContent, new File(filePath));
} else {String errorString = postMethod.getResponseBodyAsString();
System.out.println(errorString);
}
} else {System.out.println("callApi failed: ret =" + ret + "rsp=" + postMethod.getResponseBodyAsString());
}
}
留神:
上述代码中 xxxxx 对应的值请依据理论状况填写,具体取值请参见同步接口(流式)。
2.2 异步接口
2.2.1 创立异步工作
通过 access_token 信息,发送 HTTPS POST 创立歌声合成异步工作。
示例代码(Java)如下所示:
其中 requestUrl = “https://audioeditor-api-drcn.cloud.huawei.com/v1/audioeditor/gateway/ai/ttsing/async/task/create”。
请点击下载 MusicXML 文件,并上传:
/**
* 调用创立异步工作接口
* @throws Exception IO 异样
*/
private static void creatAsyncTask() throws Exception {
// 设置申请 header
PostMethod postMethod = new PostMethod(requestUrl);
// 设置文本类型(String),例:"application/json;charset=utf-8"
postMethod.setRequestHeader("Content-Type", contentType);
// 设置申请 ID(String),例:"9af1aeda-531b-407a-80b4-65b40ef77bd6"
postMethod.setRequestHeader("X-Request-ID", requestId);
// 设置 App 包名(String),例:"com.huawei.demo"
postMethod.setRequestHeader("X-Package-Name", pacageName);
// 设置 App 所在国家(String),例:"cn"
postMethod.setRequestHeader("X-Country-Code", countryCode);
// 设置 App 标识(String),例:"9af1aeda-531b-407a-80b4-65b40ef77bd6"
postMethod.setRequestHeader("HMS-APPLICATION-ID", applicationId);
// 设置证书指纹(String),例:"xxxxxxxxxxxxxxx"
postMethod.setRequestHeader("certFingerprint", certFingerprint);
// 设置动静获取的 AccessToken(String)postMethod.setRequestHeader("Authorization","Bearer" + accessToken);
// 设置申请 body
Map<String, Object> bodyMap = new HashMap<>();
Map<String, Object> dataMap = new HashMap<>();
Map<String, Object> configMap = new HashMap<>();
// filePath 是 MusicXML 文件门路(含文件名、后缀)String lyricFilePath = "filePath";
dataMap.put("lyric", FileUtils.readFileToString(new File(lyricFilePath), "UTF-8"));
dataMap.put("language", "chinese");
configMap.put("type", 1);
configMap.put("outputEncoderFormat", 0);
configMap.put("wordDurationForceAlign", "false");
bodyMap.put("data", dataMap);
bodyMap.put("config", configMap);
RequestEntity requestEntity = new StringRequestEntity(JSONObject.toJSONString(bodyMap),"application/json" ,"UTF-8");
postMethod.setRequestEntity(requestEntity);
HttpClient httpClient = new HttpClient();
int ret = httpClient.executeMethod(postMethod);
String rpsContent = postMethod.getResponseBodyAsString();
if (ret == 200) {System.out.println(rpsContent);
} else {System.out.println("callApi failed: ret =" + ret + "rsp=" + rpsContent);
}
}
应用预置曲目输出歌词:
/**
* 调用创立异步工作接口
* @throws Exception IO 异样
*/
private static void creatAsyncTask() throws Exception {
// 设置申请 header
PostMethod postMethod = new PostMethod(requestUrl);
// 设置文本类型(String),例:"application/json;charset=utf-8"
postMethod.setRequestHeader("Content-Type", contentType);
// 设置申请 ID(String),例:"9af1aeda-531b-407a-80b4-65b40ef77bd6"
postMethod.setRequestHeader("X-Request-ID", requestId);
// 设置 App 包名(String),例:"com.huawei.demo"
postMethod.setRequestHeader("X-Package-Name", pacageName);
// 设置 App 所在国家(String),例:"cn"
postMethod.setRequestHeader("X-Country-Code", countryCode);
// 设置 App 标识(String),例:"9af1aeda-531b-407a-80b4-65b40ef77bd6"
postMethod.setRequestHeader("HMS-APPLICATION-ID", applicationId);
// 设置证书指纹(String),例:"xxxxxxxxxxxxxxx"
postMethod.setRequestHeader("certFingerprint", certFingerprint);
// 设置动静获取的 AccessToken(String)postMethod.setRequestHeader("Authorization","Bearer" + accessToken);
// 设置申请 body
Map<String, Object> bodyMap = new HashMap<>();
Map<String, Object> dataMap = new HashMap<>();
Map<String, Object> configMap = new HashMap<>();
String[] lyrics = {"追随心跳的节奏", "感触自在的畅快", "把懊恼统统抛开", "咱们一起嗨", "调整呼吸的节奏", "放弃最好的状态", "奔向夺目的将来", "哦康忙北北"};
dataMap.put("lyrics", lyrics);
dataMap.put("accompanimentId", "1");
dataMap.put("isAutoFill", "false");
dataMap.put("language", "chinese");
configMap.put("type", 1);
configMap.put("outputEncoderFormat", 0);
configMap.put("wordDurationForceAlign", "false");
bodyMap.put("data", dataMap);
bodyMap.put("config", configMap);
RequestEntity requestEntity = new StringRequestEntity(JSONObject.toJSONString(bodyMap),"application/json" ,"UTF-8");
postMethod.setRequestEntity(requestEntity);
HttpClient httpClient = new HttpClient();
int ret = httpClient.executeMethod(postMethod);
String rpsContent = postMethod.getResponseBodyAsString();
if (ret == 200) {System.out.println(rpsContent);
} else {System.out.println("callApi failed: ret =" + ret + "rsp=" + rpsContent);
}
}
留神:
上述代码中 xxxxx 对应的值请依据理论状况填写,具体取值请参见创立异步工作。
2.2.2 查问异步工作状态
用户创立异步工作后,能够通过调用该接口,获取工作解决状态等信息。工作解决实现后,会返回工作的下载地址,间接拜访该地址即可下载文件。
通过 access_token 信息,和创立异步工作获取到的 taskId 发送 HTTPS POST 查问歌声合成异步工作状态。
示例代码(Java)如下所示:
其中 requestUrl = “https://audioeditor-api-drcn.cloud.huawei.com/v1/audioeditor/gateway/ai/ttsing/async/task/status”。
/**
* 调用查问异步工作状态接口
* @param taskId 创立异步工作获取的 taskId
* @throws Exception IO 异样
*/
private static void queryAsyncTaskInfo(String taskId) throws Exception {
// 设置申请 header
PostMethod postMethod = new PostMethod(requestUrl);
// 设置文本类型(String),例:"application/json;charset=utf-8"
postMethod.setRequestHeader("Content-Type", contentType);
// 设置申请 ID(String),例:"9af1aeda-531b-407a-80b4-65b40ef77bd6"
postMethod.setRequestHeader("X-Request-ID", requestId);
// 设置 App 包名(String),例:"com.huawei.demo"
postMethod.setRequestHeader("X-Package-Name", pacageName);
// 设置 App 所在国家(String),例:"cn"
postMethod.setRequestHeader("X-Country-Code", countryCode);
// 设置 App 标识(String),例:"9af1aeda-531b-407a-80b4-65b40ef77bd6"
postMethod.setRequestHeader("HMS-APPLICATION-ID", applicationId);
// 设置证书指纹(String),例:"xxxxxxxxxxxxxxx"
postMethod.setRequestHeader("certFingerprint", certFingerprint);
// 设置动静获取的 AccessToken(String)postMethod.setRequestHeader("Authorization","Bearer" + accessToken);
// 设置申请 body
Map<String, Object> bodyMap = new HashMap<>();
// taskId 对应的值是创立异步工作时返回的工作 ID(taskId)bodyMap.put("taskId", taskId);
RequestEntity requestEntity = new StringRequestEntity(JSONObject.toJSONString(bodyMap),"application/json" ,"UTF-8");
postMethod.setRequestEntity(requestEntity);
HttpClient httpClient = new HttpClient();
int ret = httpClient.executeMethod(postMethod);
String rpsContent = postMethod.getResponseBodyAsString();
if (ret == 200) {System.out.println(rpsContent);
} else {System.out.println("callApi failed: ret =" + ret + "rsp=" + rpsContent);
}
}
留神:
上述代码中 xxxxx 对应的值请依据理论状况填写,具体取值请参见查问异步工作状态。
2.2.3 勾销异步工作
用户创立歌声合成异步工作后,能够通过调用此接口,勾销指定异步工作并删除相应工作数据。
通过 access_token 信息和创立异步工作获取到的 taskId,发送 HTTPS POST 勾销异步工作。
示例代码(Java)如下所示:
其中 requestUrl = “https://audioeditor-api-drcn.cloud.huawei.com/v1/audioeditor/gateway/ai/ttsing/async/task/cancel”。
/**
* 调用勾销异步工作接口
* @param taskId 创立异步工作获取的 taskId
* @throws Exception IO 异样
*/
private static void cancelAsyncTask(String taskId) throws Exception {
// 设置申请 header
PostMethod postMethod = new PostMethod(requestUrl);
// 设置文本类型(String),例:"application/json;charset=utf-8"
postMethod.setRequestHeader("Content-Type", contentType);
// 设置申请 ID(String),例:"9af1aeda-531b-407a-80b4-65b40ef77bd6"
postMethod.setRequestHeader("X-Request-ID", requestId);
// 设置 App 包名(String),例:"com.huawei.demo"
postMethod.setRequestHeader("X-Package-Name", pacageName);
// 设置 App 所在国家(String),例:"cn"
postMethod.setRequestHeader("X-Country-Code", countryCode);
// 设置 App 标识(String),例:"9af1aeda-531b-407a-80b4-65b40ef77bd6"
postMethod.setRequestHeader("HMS-APPLICATION-ID", applicationId);
// 设置证书指纹(String),例:"xxxxxxxxxxxxxxx"
postMethod.setRequestHeader("certFingerprint", certFingerprint);
// 设置动静获取的 AccessToken(String)postMethod.setRequestHeader("Authorization","Bearer" + accessToken);
// 设置申请 body
Map<String, Object> bodyMap = new HashMap<>();
// taskId 对应的值是创立异步工作时返回的工作 ID(taskId)bodyMap.put("taskId", taskId);
RequestEntity requestEntity = new StringRequestEntity(JSONObject.toJSONString(bodyMap),"application/json" ,"UTF-8");
postMethod.setRequestEntity(requestEntity);
HttpClient httpClient = new HttpClient();
int ret = httpClient.executeMethod(postMethod);
String rpsContent = postMethod.getResponseBodyAsString();
if (ret == 200) {System.out.println(rpsContent);
} else {System.out.println("callApi failed: ret =" + ret + "rsp=" + rpsContent);
}
}
留神:
上述代码中 xxxxx 对应的值请依据理论状况填写,具体取值请参见勾销异步工作。
除了歌声合成能力,音频编辑服务还提供音频根底剪辑、AI 配音、音源拆散、空间渲染、变声降噪等音频解决能力,更多信息能够拜访官网取得。
理解更多详情 >>
拜访华为开发者联盟官网
获取开发领导文档
华为挪动服务开源仓库地址:GitHub、Gitee
关注咱们,第一工夫理解 HMS Core 最新技术资讯~