文档详细描述了通过API创建图片训练数字人全流程,包括素材上传、任务创建、状态轮询及结果确认。
重要
图片训练数字人可用于实时对话和播报视频合成,不可用于直播。
操作流程
使用获取上传凭证API获取图片素材上传凭证并上传图片素材。
通过创建图片训练数字人API设置变量值,提交图片训练数字人创建任务。
通过查询图片训练数字人状态API轮询数字人训练状态,获取训练结果。
针对待结果确认状态的数字人,通过结果确认API进行结果确认。
1 上传图片素材
使用获取上传凭证API获取素材上传凭证。
上传图片素材文件,图片素材文件要求如下:
格式: jpg、jpeg、png。
分辨率:最小分辨率:400px,最大分辨率:7000px。
文件大小:不超过10M。
宽高比:9:16。
1.1 获取素材上传凭证
private static GetUploadPolicyResponseBody.GetUploadPolicyResponseBodyData upload(Client client, String type, File file) throws Exception {
//获取上传凭证
GetUploadPolicyRequest getUploadPolicyRequest = new GetUploadPolicyRequest();
getUploadPolicyRequest.setType("INPUT_TRAIN_PIC");
GetUploadPolicyResponse uploadPolicy = client.getUploadPolicy(getUploadPolicyRequest);
GetUploadPolicyResponseBody.GetUploadPolicyResponseBodyData data = uploadPolicy.getBody().getData();
System.out.println("获取上传凭证:" + JSON.toJSONString(data));
return data;
}1.2 上传训练图片素材
private static void uploadFile(GetUploadPolicyResponseBody.GetUploadPolicyResponseBodyData data, File file) throws IOException {
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
HttpPost uploadFile = new HttpPost("https://" + data.getOssPolicy().getHost());
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
ContentType contentType = ContentType.create("multipart/form-data", Consts.UTF_8);
// 添加OSS所需的表单字段
builder.addTextBody("key", data.getOssKey() + "/" + file.getName(), contentType);
builder.addTextBody("policy", data.getOssPolicy().getPolicy(), contentType);
builder.addTextBody("OSSAccessKeyId", data.getOssPolicy().getAccessId(), contentType);
builder.addTextBody("signature", data.getOssPolicy().getSignature(), contentType);
// 添加文件
builder.addBinaryBody("file", Files.newInputStream(file.toPath()), ContentType.IMAGE_PNG, file.getName());
HttpEntity multipart = builder.build();
uploadFile.setEntity(multipart);
CloseableHttpResponse response = httpClient.execute(uploadFile);
try {
HttpEntity responseEntity = response.getEntity();
System.out.println("Upload result: " + response.getStatusLine());
if (responseEntity != null) {
String responseString = EntityUtils.toString(responseEntity);
System.out.println("Response content: " + responseString);
}
EntityUtils.consume(responseEntity);
} finally {
response.close();
}
} finally {
httpClient.close();
}
}2 创建图片训练数字人
说明
如果图片素材存在内容安全问题,创建图片训练数字人会失败。
private static CreateTrainPicAvatarResponse createTrainPicAvatar(GetUploadPolicyResponseBody.GetUploadPolicyResponseBodyData imageData,
File imageFile,
ListTemplateMaterialResponse listTemplateMaterialResponse,
Client client) throws Exception {
CreateTrainPicAvatarRequest trainPicAvatarRequest = new CreateTrainPicAvatarRequest();
trainPicAvatarRequest.setName("2D图片训练数字人测试");
//设置性别
trainPicAvatarRequest.setGender("FEMALE");// FEMALE 或 MALE
trainPicAvatarRequest.setImageOssPath(imageData.getOssKey() + "/" + imageFile.getName());
//设置业务域,
// 取值范围:BROADCAST-播报、CHAT-对话
// 不传值默认为 BROADCAST
// 适用版本:1.5.4 及以上
trainPicAvatarRequest.setBizType("BROADCAST");
//设置形象背景为透明(true)或不透明(false)默认为不透明
trainPicAvatarRequest.setTransparent(true);
CreateTrainPicAvatarResponse trainPicAvatar = client.createTrainPicAvatar(trainPicAvatarRequest);
System.out.println("创建图片训练数字人:" + JSON.toJSONString(trainPicAvatar.body.getData()));
return trainPicAvatar;
}3 获取图片训练数字人任务状态
根据上一步获取到的数字人ID通过查询图片训练数字人的状态API轮询查询图片训练数字人任务状态。由于数字人创建需要一定的时间,所以该接口需要定时轮询调用,建议轮询间隔3s,轮询过于频繁可能会导致查询失败。查询图片训练数字人状态直到状态显示为成功或者失败,状态为待确认的时候,使用结果确认API进行结果确认,针对失败的创建任务可以根据对应的失败原因进行修改重新提交。
private static GetTrainPicAvatarStatusResponse getTrainPicAvatarStatus(Client client,
CreateTrainPicAvatarResponse trainPicAvatar) throws Exception {
GetTrainPicAvatarStatusRequest getTrainPicAvatarStatusRequest = new GetTrainPicAvatarStatusRequest();
getTrainPicAvatarStatusRequest.setAvatarId(trainPicAvatar.body.data.avatarId);
GetTrainPicAvatarStatusResponse trainPicAvatarStatus = client.getTrainPicAvatarStatus(getTrainPicAvatarStatusRequest);
//状态返回:训练中(TRAINING) 训练失败(TRAIN_FAILED)待结果确认(PENDING_CONFIRM) 已完成(COMPLETED)已过期 (EXPIRED)
System.out.println("数字人状态查询:" + JSON.toJSONString(trainPicAvatarStatus.body.getData()));
return trainPicAvatarStatus;
}4 针对待确认状态数字人进行结果确认
待确认状态 PENDING_CONFIRM
结果确认 CUSTOMER_CONFIRMED
private static ConfirmTrainPicAvatarResponse confirmTrainPicAvatar(Client client,
CreateTrainPicAvatarResponse trainPicAvatar) throws Exception {
ConfirmTrainPicAvatarRequest confirmTrainPicAvatarRequest = new ConfirmTrainPicAvatarRequest();
confirmTrainPicAvatarRequest.setAvatarId(trainPicAvatar.body.data.avatarId);
confirmTrainPicAvatarRequest.setStatus("CUSTOMER_CONFIRMED");
return client.confirmTrainPicAvatar(confirmTrainPicAvatarRequest);
}图片训练数字人完整调用示例代码
引入SDK
说明
代码适用版本:1.5.4及以上。
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>lingmou20250527</artifactId>
<version>1.5.4</version>
</dependency>示例代码
import com.alibaba.fastjson.JSON;
import com.aliyun.lingmou20250527.Client;
import com.aliyun.lingmou20250527.models.*;
import com.aliyun.teaopenapi.models.Config;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
public class Demo {
public static void main(String[] args) throws Exception {
Client client = Demo.getInstance();
//1.上传图片素材
File imageFile = new File("D:\\images\\girl.jpg");
GetUploadPolicyResponseBody.GetUploadPolicyResponseBodyData imageData = upload(client, "INPUT_TRAIN_PIC", imageFile);
// 2.创建图片训练数字人,如图片存在内容安全问题或人不符合形象要求会失败.
CreateTrainPicAvatarRequest trainPicAvatarRequest = new CreateTrainPicAvatarRequest();
trainPicAvatarRequest.setName("2D图片训练数字人测试");
//设置性别
trainPicAvatarRequest.setGender("FEMALE");// FEMALE 或 MALE
trainPicAvatarRequest.setImageOssPath(imageData.getOssKey() + "/" + imageFile.getName());
//设置业务域,
// 取值范围:BROADCAST-播报、CHAT-对话
// 不传值默认为 BROADCAST
// 适用版本:1.5.4 及以上
trainPicAvatarRequest.setBizType("BROADCAST");
//设置形象背景为透明(true)或不透明(false)默认为不透明
trainPicAvatarRequest.setTransparent(true);
CreateTrainPicAvatarResponse trainPicAvatar = client.createTrainPicAvatar(trainPicAvatarRequest);
System.out.println("创建图片训练数字人:" + JSON.toJSONString(trainPicAvatar.body.getData()));
//返回avatarId:数字人ID,pass:是否通过,预期训练完成时间(单位秒): expectedCompletionTime
//4.数字人状态查询 (需要获取创建图片训练数字人返回的数字人形象id)
GetTrainPicAvatarStatusRequest getTrainPicAvatarStatusRequest = new GetTrainPicAvatarStatusRequest();
getTrainPicAvatarStatusRequest.setAvatarId(trainPicAvatar.body.data.avatarId);
GetTrainPicAvatarStatusResponse trainPicAvatarStatus = client.getTrainPicAvatarStatus(getTrainPicAvatarStatusRequest);
//状态返回:训练中(TRAINING) 训练失败(TRAIN_FAILED)待结果确认(PENDING_CONFIRM) 已完成(COMPLETED)已过期 (EXPIRED)
System.out.println("数字人状态查询:" + JSON.toJSONString(trainPicAvatarStatus.body.getData()));
//用户确认 (当数字人的状态为待结果确认 (PENDING_CONFIRM)
if (trainPicAvatarStatus.body.data.status.equals("PENDING_CONFIRM")) {
ConfirmTrainPicAvatarRequest confirmTrainPicAvatarRequest = new ConfirmTrainPicAvatarRequest();
confirmTrainPicAvatarRequest.setAvatarId(trainPicAvatar.body.data.avatarId);
confirmTrainPicAvatarRequest.setStatus("CUSTOMER_CONFIRMED");
client.confirmTrainPicAvatar(confirmTrainPicAvatarRequest);
}
}
private static GetUploadPolicyResponseBody.GetUploadPolicyResponseBodyData upload(Client client, String type, File file) throws Exception {
//获取上传凭证
GetUploadPolicyRequest getUploadPolicyRequest = new GetUploadPolicyRequest();
getUploadPolicyRequest.setType(type);
GetUploadPolicyResponse uploadPolicy = client.getUploadPolicy(getUploadPolicyRequest);
GetUploadPolicyResponseBody.GetUploadPolicyResponseBodyData data = uploadPolicy.getBody().getData();
System.out.println("获取上传凭证:" + JSON.toJSONString(data));
// HttpClient上传文件
uploadFile(data, file);
return data;
}
private static void uploadFile(GetUploadPolicyResponseBody.GetUploadPolicyResponseBodyData data, File file) throws IOException {
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
HttpPost uploadFile = new HttpPost("https://" + data.getOssPolicy().getHost());
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
ContentType contentType = ContentType.create("multipart/form-data", Consts.UTF_8);
// 添加OSS所需的表单字段
builder.addTextBody("key", data.getOssKey() + "/" + file.getName(), contentType);
builder.addTextBody("policy", data.getOssPolicy().getPolicy(), contentType);
builder.addTextBody("OSSAccessKeyId", data.getOssPolicy().getAccessId(), contentType);
builder.addTextBody("signature", data.getOssPolicy().getSignature(), contentType);
// 添加文件
builder.addBinaryBody("file", Files.newInputStream(file.toPath()), ContentType.IMAGE_PNG, file.getName());
HttpEntity multipart = builder.build();
uploadFile.setEntity(multipart);
CloseableHttpResponse response = httpClient.execute(uploadFile);
try {
HttpEntity responseEntity = response.getEntity();
System.out.println("Upload result: " + response.getStatusLine());
if (responseEntity != null) {
String responseString = EntityUtils.toString(responseEntity);
System.out.println("Response content: " + responseString);
}
EntityUtils.consume(responseEntity);
} finally {
response.close();
}
} finally {
httpClient.close();
}
}
public static Client getInstance() throws Exception {
String accessKeyId = "xxx";
String accessKeySecret = "yyy";
String endpoint = "lingmou.cn-beijing.aliyuncs.com";
//或者lingmou-share.cn-beijing.aliyuncs.com
Config config = new Config();
// noinspection AklessInspection
config.setAccessKeyId(accessKeyId);
// noinspection AklessInspection
config.setAccessKeySecret(accessKeySecret);
config.setEndpoint(endpoint);
return new Client(config);
}
}形象创建错误码
DETECT_FAILED("图像检测失败"),
DETECT_NOT_PASS("图像检测不通过"),
CONTENT_RISK("您的图片涉及平台限制内容,请重新上传"),
NO_HUMAN_BODY("未检测到人脸"),
MULTI_HUMAN_BODY("请上传单个形象图片"),
INVALID_HUMAN_PROPORTION("形象在照片中比例过大/过小"),
INVALID_IMAGE_SIZE("图片大小不符合要求"),
INVALID_PERSON_VAGUE("请上传更清晰的照片"),
INVALID_BODY_ORIENTATION("请确保身体朝向正面"),
FACE_INCOMPLETE("请确保脸部完整"),
INVALID_FACE_ORIENTATION("请确保脸部朝向正面"),该文章对您有帮助吗?