评论

收藏

[Android] 虚拟偶像的歌声原来是这样生成的!

移动开发 移动开发 发布于:2022-07-27 10:00 | 阅读数:547 | 评论:0

HMS Core音频编辑服务(Audio Editor Kit)6.6.0版本上线,新增歌声合成能力。通过歌词和曲调,结合不同的曲风让机器也能生成真实度极高的歌声。支持字级别输入歌词进行音素转换,生成对应歌词的歌声,可灵活调整音高、滑音、呼吸音、颤音等细节参数,让歌声更真实。
DSC0000.png

歌声合成服务可广泛应用于音视频创意制作、影音娱乐、音乐教育、虚拟偶像等领域。例如,在音乐创作或短视频创意编辑时,歌声合成服务可以助力用户自由创作合成歌曲,使创作更加丰富多彩。在虚拟偶像领域,通过歌声合成,可以让虚拟人拥有特定音色歌唱能力,使其形象更生动。在音乐游戏或者歌唱教育中,歌声合成可以迅速生成标准参考声音,提高音频制作效率节省人力成本。
歌声合成效果
听到了歌声合成媲美真人的歌唱效果,是否迫不及待想上手使用了呢,以下是歌声合成的具体集成方法。快来亲自集成试试吧!
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调用同步接口(流式)
通过以上步骤获取的access_token信息,发送HTTPS POST调用同步接口(流式)。
示例代码(Java)如下所示:
其中requestUrl = "https://audioeditor-api-drcn.cloud.huawei.com/v1/audioeditor/gateway/ai/ttsing/sync"。
/**
   * 调用同步接口(流式)
   * @param accessToken 根据clientId和密钥获取的token
   * @throws Exception IO异常
   */
  private static void syncTask(String accessToken) throws Exception {
    // 设置请求header
    PostMethod postMethod = new PostMethod(requestUrl);
    postMethod.setRequestHeader("Content-Type","application/json;charset=utf-8");
    postMethod.setRequestHeader("X-Request-ID","9af1aeda-531b-407a-80b4-65b40ef77bd6");
    postMethod.setRequestHeader("X-Package-Name","com.huawei.demo");
    postMethod.setRequestHeader("X-Country-Code","cn");
    postMethod.setRequestHeader("HMS-APPLICATION-ID","123456");
    postMethod.setRequestHeader("certFingerprint","xxxxx");
    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);
    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是要保存文件的路径(含文件名、后缀)
        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());
    }
  }
2.2异步接口
2.2.1创建异步任务
通过access_token信息,发送HTTPS POST创建歌声合成异步任务。
/**
   * 调用创建异步任务接口
   * @param accessToken 根据clientId和密钥获取的token
   * @throws Exception IO异常
   */
  private static void creatAsyncTask(String accessToken) throws Exception {
    // 设置请求header
    PostMethod postMethod = new PostMethod(requestUrl);
    postMethod.setRequestHeader("Content-Type","application/json;charset=utf-8");
    postMethod.setRequestHeader("X-Request-ID","9af1aeda-531b-407a-80b4-65b40ef77bd6");
    postMethod.setRequestHeader("X-Package-Name","com.huawei.demo");
    postMethod.setRequestHeader("X-Country-Code","cn");
    postMethod.setRequestHeader("HMS-APPLICATION-ID","123456");
    postMethod.setRequestHeader("certFingerprint","xxxxx");
    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);
    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);
    }
  }
2.2.2查询异步任务状态
通过access_token信息,发送HTTPS POST查询歌声合成异步任务状态。
/**
   * 调用查询异步任务状态接口
   * @param accessToken 根据clientId和密钥获取的token
   * @throws Exception IO异常
   */
  private static void queryAsyncTaskInfo(String accessToken) throws Exception {
    // 设置请求header
    PostMethod postMethod = new PostMethod(requestUrl);
    postMethod.setRequestHeader("Content-Type","application/json;charset=utf-8");
    postMethod.setRequestHeader("X-Request-ID","9af1aeda-531b-407a-80b4-65b40ef77bd6");
    postMethod.setRequestHeader("X-Package-Name","com.huawei.demo");
    postMethod.setRequestHeader("X-Country-Code","cn");
    postMethod.setRequestHeader("HMS-APPLICATION-ID","123456");
    postMethod.setRequestHeader("certFingerprint","xxxxx");
    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);
    }
  }
2.2.3取消异步任务
通过access_token信息,发送HTTPS POST取消异步任务。
/**
   * 调用取消异步任务接口
   * @param accessToken 根据clientId和密钥获取的token
   * @throws Exception IO异常
   */
  private static void cancelAsuncTask(String accessToken) throws Exception {
    // 设置请求header
    PostMethod postMethod = new PostMethod(requestUrl);
    postMethod.setRequestHeader("Content-Type","application/json;charset=utf-8");
    postMethod.setRequestHeader("X-Request-ID","9af1aeda-531b-407a-80b4-65b40ef77bd6");
    postMethod.setRequestHeader("X-Package-Name","com.huawei.demo");
    postMethod.setRequestHeader("X-Country-Code","cn");
    postMethod.setRequestHeader("HMS-APPLICATION-ID","123456");
    postMethod.setRequestHeader("certFingerprint","xxxxx");
    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);
    }
  }
除了歌声合成能力,音频编辑服务还提供音频基础编辑、AI配音伴奏提取、空间渲染、变声降噪等丰富的音频处理能力,为全球开发者提供性能优异、简单易用、开放性强的接口,帮助开发者轻松高效构建应用音频编辑能力。
了解更多详情>>
访问华为开发者联盟官网
获取开发指导文档
华为移动服务开源仓库地址:GitHub、Gitee
关注我们,第一时间了解 HMS Core 最新技术资讯~


   
   
   
                        

关注下面的标签,发现更多相似文章