版本变更
版本 | 描述 | 时间 |
v0.4 | 数字人视频合成支持自研数字人,新增素材音量调节字段,声音模板新增声音模板版本出参 SDK版本升级 | 2024-09-09 |
v0.3 | 新增批量查询数字人视频合成信息接口, sdk升级到2.3.0 | 2024-08-20 |
v0.2 | 提交数字人视频合成接口,新增透明背景 | 2024-07-31 |
v0.1 | 功能发布 | 2024-07-01 |
概览
交互示例
接入准备
需要接入方提前准备阿里云账号,并利用阿里云子账号生成对应的AK/SK;
阿里云主账号需要对生成AK/SK的子账号进行RAM授权;
使用阿里云主账号登录平台,签署相关法务协议。
API详情
1. 提交数字人视频合成任务
SubmitProjectTask
1.1. 入参
参数名 | 类型 | 是否必填 | 说明 |
scaleType | string | 是 | 画面比例(9:16,16:9) 9:16 - 画面宽度:1080,高度:1920 16:9 - 画面宽度:1920,高度:1080 |
subtitleTag | int | 是 | 是否开启字幕:1 - 是, 0 - 否, 自研数字人不支持字幕 |
transparentBackground | int | 否 | 透明背景开关:1-开启 0-关闭, 默认0 开启透明背景不允许添加素材,自研数字人不支持透明背景, 开启透明背景主播的坐标位置默认居中,不支持调整 |
frames | List<OpenFrame> | 是 | 视频画面(最多50个画面) |
OpenFrame
参数名 | 类型 | 是否必填 | 说明 |
index | int | 是 | 画面顺序,最小值为1。单次提交中每个画面顺序不可相同 |
layers | List<OpenLayer> | 是 | 图层(一个画面最多10个图层) |
videoScript | OpenVideoScript | 是 | 脚本信息 |
subtitle | OpenSubtitle | 开启字幕时必填 | 字幕设置 |
OpenVideoScript
参数名 | 类型 | 是否必填 | 说明 |
type | string | 是 | 文本/音频:TEXT/AUDIO |
audioUrl | string | 音频类型必填 | 音频文件地址(最长十分钟) |
textContent | string | 文本类型必填 | 音频文本 |
voiceTemplateId | long | 文本类型必填 | 声音模型id(需要跟主播匹配) |
volume | int | 文本类型必填 | 音量: 范围[0 到 100],推荐值50 |
speedRate | string | 文本类型必填 | 语速倍数:范围[0.8 到 2.0] 正常语速1,仅支持一位小数 |
OpenLayer
参数名 | 类型 | 是否必填 | 说明 |
type | string | 是 | ANCHOR - 主播 BACKGROUND - 背景,透明背景开启时可不传背景 MATERIAL - 素材 |
material | OpenMaterial | 是 | 图层素材 |
index | int | 非背景必填 | 图层顺序 最小1,单次提交中每个画面中图层顺序不可相同,背景不填 |
positionX | int | 非背景必填 | 图层X坐标,背景不填(详见坐标说明) |
positionY | int | 非背景必填 | 图层Y坐标,背景不填(详见坐标说明) |
width | int | 非背景必填 | 图层宽度,背景不填(不能超过画面高度) |
height | int | 非背景必填 | 图层高度,背景不填(不能超过画面宽度) |
背景图层必须铺满整个画面,默认最底层
背景图层的width,height默认等于画面的width,height
背景图层的positionX,positionY默认等于0
OpenMaterial 主播/素材
参数名 | 类型 | 是否必填 | 说明 |
id | string | 主播图层必填 | 主播id |
url | string | 非主播图层必填 | 素材url(http地址) |
format | string | 非主播图层必填 | 素材格式:video/mp4,image/png image/jpg,image/jpeg |
volume | int | 否 | 视频音量: 范围[0 到 100],推荐值50 ,仅video/mp4格式支持 |
OpenSubtitle 字幕
参数名 | 类型 | 是否必填 | 说明 |
positionX | int | 是 | X坐标:详见字幕说明 |
positionY | int | 是 | Y坐标:详见字幕说明 |
font | string | 是 | 字体,例如:SimSun ,详细见字体说明 |
fontSize | int | 是 | 字号: 允许范围[32 - 160] |
fontColor | string | 是 | 文字的颜色,格式为#后跟16进制值。例如:#ffffff |
alignment | string | 是 | 对齐方式:
|
backgroundColor | string | 否 | 背景色,RGB颜色,格式为#后跟16进制值。例如:#ffffff。 |
maxCharLength | int | 是 | 一行可显示最大字数,建议文本宽度/字体宽度 |
textWidth | int | 是 | 文本宽度:详见字幕说明 |
textHeight | int | 是 | 文本高度:详见字幕说明 |
1.1.1. 字体说明
Alibaba PuHuiTi - 阿里巴巴普惠体
FZKai-Z03S - 方正楷体简体
FZHei-B01S - 方正黑体简体
FZShuSong-Z01S - 方正书宋简体
FZFangSong-Z02S - 方正仿宋简体
SimSun - 宋体
WenQuanYi MicroHei - 文泉驿微米黑
WenQuanYi Zen Hei Mono - 文泉驿等宽正黑
WenQuanYi Zen Hei Sharp - 文泉驿点阵正黑
Microsoft YaHei - 微软雅黑
Yuanti SC - 圆体-简常规体
Roboto Bold - Google Robota字体,不支持中文
Roboto - Google Robota字体,不支持中文
KaiTi - 楷体
SiYuan Heiti - 思源黑体
SiYuan SimSun - 思源宋体
HappyZcool-2016 - 站酷快乐体
1.1.2. 坐标说明
主播、素材、水印坐标参数均为画面左上角对接图片左上角的距离
坐标如果存在小数,舍弃小数, 如下图:X=470, Y=700
1.1.3. 图层超出画面外
超出画面的图片需要进行裁剪
图片的宽高使用裁剪后的图片宽高
X,Y轴的坐标超出部分为0
原图:
裁剪后图片:
画面内的效果:
1.1.4. 字幕说明
下图参数示例:
{
"positionX": 68, // 字幕不允许超出画面外,最小0,最大不超过画面宽度
"positionY": 392,// 字幕不允许超出画面外,最小0,最大不超过画面高度
"maxCharLength": 7, // 一行可显示最大字数,建议文本宽度/字体宽度
"textWidth": 800, // 文本宽度,文本框不能超出画面外
"textHeight": 110, // 文本高度,必须大于字体大小
"fontSize": 100, // 字体大小
"font": "SiYuan SimSun",
"fontColor": "#090707",
"alignment": "BottomRight", // 右对齐
"backgroundColor": "#fefefe"
}
1.1.5. 背景示例
背景图层提供的图片需要充满整个画布,无需传递坐标值,系统默认X=0, Y=0
1.2. 出参
参数名 | 类型 | 说明 |
success | boolean | true 成功, false 失败 |
errorMessage | string | 错误信息 |
errorCode | string | 异常code |
taskId | string | 任务id |
2. 查询数字人视频合成信息
GetProjectTask
2.1. 入参
参数名称 | 类型 | 是否必填 | 说明 |
taskId | String | 是 | 任务id |
2.2. 出参
参数名称 | 类型 | 说明 |
status | String | 合成状态:IN_PROGRESS - 合成中, FAIL - 失败 SUCCESS - 成功, CANCEL - 已取消 |
errorMsg | String | 合成失败原因 |
videoDuration | String | 视频时长 |
videoUrl | String | 视频地址 |
3. 批量查询数字人视频合成信息
BatchGetProjectTask
3.1. 入参
参数名称 | 类型 | 是否必填 | 说明 |
taskIdList | List<String> | 是 | 任务id集合 |
3.2. 出参
参数名 | 类型 | 说明 |
resultList | List<Object> | 视频信息 |
Object说明
status | String | 合成状态:IN_PROGRESS - 合成中, FAIL - 失败 SUCCESS - 成功, CANCEL - 已取消 |
errorMsg | String | 合成失败原因 |
videoDuration | String | 视频时长 |
videoUrl | String | 视频地址 |
4. 合成任务停止
StopProjectTask
4.1. 入参
参数名称 | 类型 | 是否必填 | 说明 |
taskId | String | 是 | 任务id |
4.2. 出参
参数名称 | 类型 | 说明 |
success | boolean | true-成功,false-失败(仅表示提交结果,任务是否真正停止需调用“查询数字人视频合成信息”接口根据任务状态判断) |
errorCode | String | 错误码 |
errorMsg | String | 失败原因 |
5. 查询资源信息
5.1. 入参
无
5.2. 出参
参数名称 | 类型 | 说明 |
resourceInfoList | List<ResourceInfo> | 资源剩余量信息 |
ResourceInfo
参数名称 | 类型 | 说明 |
resourceType | Integer | 资源类型:2 - AI视频生成时长 |
remainCount | Integer | 资源剩余量 |
unit | String | 资源剩余量单位: second - 秒 |
lastExpire | Integer | 资源过期剩余天数 |
6. 数字人形象模型查询
ListAnchor
6.1. 入参
参数名称 | 参数类型 | 是否必填 | 说明 |
coverRate | string | N | 主播形象比例 9:16 竖版 16:9 横版 |
anchorType | string | N | 主播类型: PUBLIC_MODEL:公模 PRIVATE_MODEL:私模 |
digitalHumanType | string | N | 主播类别: dynamicReality 动态实景数字人(暂时不可使用);staticTransparency 静态数字人 |
useScene | string | Y | 使用场景 offlineSynthesis 离线数字人; |
pageSize | int | Y | 每页大小 |
pageNumber | int | Y | 页码 |
6.2. 出参
参数名 | 参数类型 | 参数说明 |
total | int | 总数 |
list | array:AnchorResponse | 主播形象obj array |
success | Boolean | 是否成功 |
errorMessage | String | 异常信息 |
errorCode | String | 异常错误码 |
AnchorResponse
参数名 | 参数类型 | 参数说明 |
anchoId | String | 主播id |
anchorMaterialName | String | 主播名称 |
anchorType | String | 主播类型: PUBLIC_MODEL 公模 PRIVATE_MODEL 私模 |
coverUrl | String | 模特封面图 |
coverThumbnailUrl | String | 模特封面缩略图 |
coverWeight | int | 封面图宽:像素值 |
coverHeight | int | 封面图高:像素值 |
coverRate | String | 封面比例 |
status | String | 状态: Usable 已上线 |
digitalHumanType | String | 主播类别: dynamicReality 动态实景数字人(暂时不可用);staticTransparency 静态数字人 |
useScene | String | 使用场景 offlineSynthesis 离线数字人; |
resourceTypeDesc | String | 资源规格描述 |
gender | String | 性别F/M(需要与声音模板性别保持一致) |
7. 声音模板查询
ListVoiceModels
7.1. 入参
参数名 | 参数类型 | 是否必填 | 参数说明 |
voiceType | String | N | 声音类型 PRIVATE_VOICE 私模声音; PUBLIC_VOICE 公模声音; |
useScene | string | Y | 使用场景 offlineSynthesis 离线数字人 |
pageSize | int | Y | 每页大小 |
pageNumber | int | Y | 页码 |
7.2. 出参
参数名 | 参数类型 | 参数描述 |
total | int | 总数 |
list | array:VoiceModelResult | 音频脚本模板集合 |
success | Boolean | 是否成功 |
errorMessage | String | 异常信息 |
errorCode | String | 异常错误码 |
VoiceModelResponse
参数名 | 参数类型 | 参数描述 |
voiceId | bigInt | 声音模板id |
voiceName | String | 声音名称 |
voiceModel | String | 声音模型(参数值) |
voiceGender | String | 男声M/女声F((需要与形象性别保持一致)) |
voiceUrl | String | 试听音频url |
voiceLanguage | String | zh/en |
voiceDesc | String | 声音模型描述 |
useScene | String | 使用场景 offlineSynthesis 离线数字人 |
resourceTypeDesc | String | 资源规格描述 |
ttsVersion | Integer | tts版本0,1,2 v0.4 |
对接详情
PHP
对接示例
require 'vendor/autoload.php';
use AlibabaCloud\SDK\Imarketing\V20220704\Models\GetOssUploadSignatureRequest;
use AlibabaCloud\SDK\IntelligentCreation\V20240313\IntelligentCreation;
use Darabonba\OpenApi\Models\Config as AlibabaConfig;
$config = new AlibabaConfig();
$config->accessKeyId = '****';
$config->accessKeySecret = '****';
$config->endpoint = "intelligentcreation.cn-zhangjiakou.aliyuncs.com";
$intelligentCreationClient = new IntelligentCreation($config);
$request = new GetProjectTaskRequest();
$request->taskId = '1111';
try {
$response = $intelligentCreationClient->getProjectTask($request);
var_dump($response->toMap());
} catch (TeaError $e) {
Log::error($e);
}
2.4.0
u-17374653-852f-4536-9c8f-61f96b9890ef-composer-tea.zip
composer require alibabacloud/intelligentcreation-20240313 2.4.0
Java
对接示例
package com.aliyun.intelligentcreation20240313;
import com.aliyun.intelligentcreation20240313.models.*;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.util.HashMap;
import java.util.Map;
/**
* @author fangming.yu
* @since 2024/7/5
*/
public class TestProjectTest {
public static void main(String[] args) throws Exception {
TestProjectTest testProjectTest = new TestProjectTest();
try {
String taskId = testProjectTest.submitProjectTaskRequest();
testProjectTest.stopProjectTaskRequest(taskId);
testProjectTest.getProjectTaskRequest(taskId);
testProjectTest.selectResourceRequest(null);
testProjectTest.listVoiceModelsRequest();
System.out.println(taskId);
} catch (TeaException e) {
Gson gson = new Gson();
System.out.println(e.getMessage());
System.out.println(gson.toJson(e.getData()));
} catch (Exception e) {
e.printStackTrace();
}
}
String url = "intelligentcreation.cn-zhangjiakou.aliyuncs.com";
//初始化配置
Config config = new Config().setAccessKeyId("**")
.setAccessKeySecret("**")
.setEndpoint(url);
// 创建客户端
Client client = new Client(config);
public TestProjectTest() throws Exception {
}
String submitProjectTaskRequest() throws Exception {
Gson gson = new Gson();
String para = "{\"scaleType\":\"16:9\",\"subtitleTag\":1,\"frames\":[{\"index\":1,\"layers\":[{\"type\":\"BACKGROUND\",\"material\":{\"format\":\"image/png\",\"url\":\"https://yic-pre.oss-cn-hangzhou.aliyuncs.com/common/image/backgroundImage/shu/1.png\"}},{\"type\":\"MATERIAL\",\"material\":{\"format\":\"image/png\",\"url\":\"https://yic-pre.oss-cn-hangzhou.aliyuncs.com/1539704706413278/image/material/1716348615967-%E5%86%B0%E6%B7%87%E6%B7%8B.png\"},\"index\":2,\"positionX\":76,\"positionY\":1169,\"width\":549,\"height\":750},{\"type\":\"ANCHOR\",\"material\":{\"id\":\"759459670880206851\",\"url\":\"https://yic-pre.oss-cn-hangzhou.aliyuncs.com/1539704706413278/image/anchor/1715148681933-55254f81420c4c82954042414136e52d.png\"},\"index\":3,\"positionX\":0,\"positionY\":0,\"width\":1080,\"height\":1920},{\"type\":\"WATERMARK\",\"material\":{\"type\":\"WATERMARK\",\"format\":\"image/png\",\"url\":\"https://yic-pre.oss-cn-hangzhou.aliyuncs.com/common/image/material/%E6%B0%B4%E5%8D%B003%403x.png"},\"index\":4,\"positionX\":248,\"positionY\":280,\"width\":191,\"height\":195}],\"videoScript\":{\"textContent\":\"让我们一同投身于这场激动人心的呼吸之旅,共同见证科技与医学的完美融合,携手共进\",\"type\":\"TEXT\",\"voiceTemplateId\":82,\"volume\":50,\"speedRate\":1.5},\"subtitle\":{\"positionX\":0,\"positionY\":545,\"maxCharLength\":6,\"textWidth\":1080,\"fontSize\":60,\"font\":\"Microsoft YaHei\",\"fontColor\":\"#2a313d\",\"textHeight\":70,\"alignment\":\"BottomCenter\"}}]}";
Map<String, Object> map = gson.fromJson(para, new TypeToken<Map<String, Object>>() {
}.getType());
SubmitProjectTaskRequest request = SubmitProjectTaskRequest.build(map);
// 请求接口
SubmitProjectTaskResponse response = client.submitProjectTask(request);
System.out.println(gson.toJson(response));
if (response.getStatusCode().equals(200)) {
System.out.println("submitProjectTaskRequest 请求成功");
return response.getBody().getTaskId();
}
return null;
}
void getProjectTaskRequest(String taskId) throws Exception {
Gson gson = new Gson();
Map<String, Object> map = new HashMap<>();
map.put("taskId", taskId);
GetProjectTaskRequest request = GetProjectTaskRequest.build(map);
// 请求接口
GetProjectTaskResponse response = client.getProjectTask(request);
System.out.println(gson.toJson(response));
if (response.getStatusCode().equals(200)) {
System.out.println("getProjectTaskRequest 请求成功");
}
}
void stopProjectTaskRequest(String taskId) throws Exception {
Gson gson = new Gson();
Map<String, Object> map = new HashMap<>();
map.put("taskId", taskId);
StopProjectTaskRequest request = StopProjectTaskRequest.build(map);
// 请求接口
StopProjectTaskResponse response = client.stopProjectTask(request);
System.out.println(gson.toJson(response));
if (response.getStatusCode().equals(200)) {
System.out.println("stopProjectTaskRequest 请求成功");
}
}
void selectResourceRequest(String projectId) throws Exception {
Gson gson = new Gson();
Map<String, Object> map = new HashMap<>();
SelectResourceRequest request = SelectResourceRequest.build(map);
SelectResourceResponse response = client.selectResource(request);
System.out.println(gson.toJson(response));
if (response.getStatusCode().equals(200)) {
System.out.println("selectResourceRequest 请求成功");
}
}
void listVoiceModelsRequest() throws Exception {
Gson gson = new Gson();
Map<String, Object> map = new HashMap<>();
map.put("useScene", "offlineSynthesis");
map.put("pageSize", 1);
map.put("pageNumber", 10);
ListVoiceModelsRequest request = ListVoiceModelsRequest.build(map);
ListVoiceModelsResponse response = client.listVoiceModels(request);
System.out.println(gson.toJson(response));
if (response.getStatusCode().equals(200)) {
System.out.println("listVoiceModelsRequest 请求成功");
}
}
}
2.4.0
u-17374653-852f-4536-9c8f-61f96b9890ef-java-tea.zip
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>intelligentcreation20240313</artifactId>
<version>2.4.0</version>
</dependency>
2.1.0
u-ce29b5c7-8a37-4590-98f4-71a02e5366f9-java-tea.zip
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>intelligentcreation20240313</artifactId>
<version>2.1.0</version>
</dependency>