Browse Source

修改视频回调接口

glx
glx 2 weeks ago
parent
commit
65fc5f0a81
  1. 1
      src/main/java/com/youlai/boot/mini/controller/AiGenerationController.java
  2. 60
      src/main/java/com/youlai/boot/mini/model/vo/AiVideoCallbackVO.java
  3. 2
      src/main/java/com/youlai/boot/mini/model/vo/VideoCallbackContent.java
  4. 61
      src/main/java/com/youlai/boot/mini/model/vo/VideoCallbackData.java
  5. 6
      src/main/java/com/youlai/boot/mini/model/vo/VideoCallbackUsage.java
  6. 52
      src/main/java/com/youlai/boot/mini/service/impl/AiGenerationServiceImpl.java
  7. 2
      src/main/resources/application-dev.yml

1
src/main/java/com/youlai/boot/mini/controller/AiGenerationController.java

@ -101,5 +101,4 @@ public class AiGenerationController {
}
//TODO: 后续在回调中 增加用户小程序订阅通知
}

60
src/main/java/com/youlai/boot/mini/model/vo/AiVideoCallbackVO.java

@ -1,5 +1,6 @@
package com.youlai.boot.mini.model.vo;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@ -10,19 +11,60 @@ import lombok.Data;
* @author youlai
*/
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "AI视频生成任务回调请求")
public class AiVideoCallbackVO {
@Schema(description = "响应消息")
private String msg;
@Schema(description = "第三方视频任务唯一ID")
private String id;
@Schema(description = "响应码,0表示成功")
private Integer code;
@Schema(description = "使用的模型ID")
private String model;
@Schema(description = "回调数据")
private VideoCallbackData data;
@Schema(description = "任务状态:queued排队中/running处理中/succeeded成功/failed失败")
private String status;
@JsonProperty("request_id")
@Schema(description = "请求ID")
private String requestId;
@JsonProperty("created_at")
@Schema(description = "创建时间戳")
private Long createdAt;
@JsonProperty("updated_at")
@Schema(description = "更新时间戳")
private Long updatedAt;
@JsonProperty("service_tier")
@Schema(description = "服务等级")
private String serviceTier;
@JsonProperty("execution_expires_after")
@Schema(description = "执行过期时间")
private Long executionExpiresAfter;
@JsonProperty("generate_audio")
@Schema(description = "是否生成音频")
private Boolean generateAudio;
@Schema(description = "是否为草稿")
private Boolean draft;
@Schema(description = "生成结果,status=succeeded时返回")
private VideoCallbackContent content;
@Schema(description = "资源消耗统计")
private VideoCallbackUsage usage;
@Schema(description = "随机种子")
private Long seed;
@Schema(description = "分辨率,比如720p")
private String resolution;
@Schema(description = "比例,比如16:9")
private String ratio;
@Schema(description = "视频时长,单位秒")
private Integer duration;
@Schema(description = "帧率")
private Integer framespersecond;
}

2
src/main/java/com/youlai/boot/mini/model/vo/VideoCallbackContent.java

@ -1,5 +1,6 @@
package com.youlai.boot.mini.model.vo;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@ -10,6 +11,7 @@ import lombok.Data;
* @author youlai
*/
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "AI视频生成回调结果内容")
public class VideoCallbackContent {

61
src/main/java/com/youlai/boot/mini/model/vo/VideoCallbackData.java

@ -1,61 +0,0 @@
package com.youlai.boot.mini.model.vo;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* AI视频生成回调数据
*
* @author youlai
*/
@Data
@Schema(description = "AI视频生成回调数据")
public class VideoCallbackData {
@Schema(description = "任务ID")
private String id;
@Schema(description = "使用的模型ID")
private String model;
@Schema(description = "任务状态: pending/running/succeeded/failed")
private String status;
@Schema(description = "生成的结果内容")
private VideoCallbackContent content;
@Schema(description = "资源消耗统计")
private VideoCallbackUsage usage;
@JsonProperty("created_at")
@Schema(description = "创建时间戳")
private Long createdAt;
@JsonProperty("updated_at")
@Schema(description = "更新时间戳")
private Long updatedAt;
@Schema(description = "随机种子")
private Long seed;
@Schema(description = "分辨率")
private String resolution;
@Schema(description = "比例")
private String ratio;
@Schema(description = "视频时长,单位秒")
private Integer duration;
@Schema(description = "帧率")
private Integer framespersecond;
@JsonProperty("service_tier")
@Schema(description = "服务等级")
private String serviceTier;
@JsonProperty("execution_expires_after")
@Schema(description = "执行过期时间")
private Long executionExpiresAfter;
}

6
src/main/java/com/youlai/boot/mini/model/vo/VideoCallbackUsage.java

@ -1,16 +1,18 @@
package com.youlai.boot.mini.model.vo;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* AI视频生成资源消耗统计
* 视频生成资源消耗统计
*
* @author youlai
*/
@Data
@Schema(description = "AI视频生成资源消耗统计")
@JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "视频生成资源消耗统计")
public class VideoCallbackUsage {
@JsonProperty("completion_tokens")

52
src/main/java/com/youlai/boot/mini/service/impl/AiGenerationServiceImpl.java

@ -32,13 +32,10 @@ import com.youlai.boot.mini.model.form.MiniDeductPointForm;
import com.youlai.boot.mini.model.vo.AiVideoCallbackVO;
import com.youlai.boot.mini.model.form.AiCallbackImage;
import com.youlai.boot.mini.model.form.AiFourPanelCallbackForm;
import com.youlai.boot.mini.model.vo.VideoCallbackData;
import com.youlai.boot.common.exception.BusinessException;
import com.youlai.boot.mini.service.AiGenerationService;
import com.youlai.boot.mini.service.MiniPointRecordService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -49,9 +46,7 @@ import java.awt.image.BufferedImage;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
@Slf4j
@Service
@ -480,23 +475,11 @@ public class AiGenerationServiceImpl implements AiGenerationService {
log.info("处理AI视频生成任务回调,请求参数:{}", JSONUtil.toJsonStr(vo));
boolean success = false;
try {
// 校验回调响应是否成功
if (!Integer.valueOf(0).equals(vo.getCode())) {
log.error("视频生成任务回调失败,错误信息:{}", vo.getMsg());
return false;
}
VideoCallbackData data = vo.getData();
if (data == null) {
log.error("视频回调数据为空");
return false;
}
String videoTaskUuid = data.getId();
String videoTaskUuid = vo.getId();
// 根据第三方返回的视频任务uuid查询对应的任务
MiniAiGenerationTask task = aiGenerationTaskMapper.selectOne(new LambdaQueryWrapper<MiniAiGenerationTask>()
.eq(MiniAiGenerationTask::getVideoTaskUuid, videoTaskUuid)
.eq(MiniAiGenerationTask::getDeleted, false));
.eq(MiniAiGenerationTask::getVideoTaskUuid, videoTaskUuid)
.eq(MiniAiGenerationTask::getDeleted, false));
if (task == null) {
log.error("视频回调任务不存在,第三方视频任务UUID:{}", videoTaskUuid);
return false;
@ -504,13 +487,14 @@ public class AiGenerationServiceImpl implements AiGenerationService {
// 转换任务状态
Integer status;
if ("succeeded".equals(data.getStatus())) {
if ("succeeded".equals(vo.getStatus())) {
status = 1; // 成功
} else if ("failed".equals(data.getStatus())) {
} else if ("failed".equals(vo.getStatus())) {
status = 2; // 失败
} else {
log.info("视频任务{}处于中间状态:{},不处理", task.getUuid(), data.getStatus());
return true; // 中间状态直接返回成功,不更新任务
// queued/running中间状态直接返回成功,不更新任务
log.info("视频任务{}处于中间状态:{},不处理", task.getUuid(), vo.getStatus());
return true;
}
// 更新任务状态
@ -520,9 +504,9 @@ public class AiGenerationServiceImpl implements AiGenerationService {
aiGenerationTaskMapper.updateById(task);
// 如果生成成功,下载外部视频到OSS
if (status == 1 && data.getContent() != null && data.getContent().getVideoUrl() != null) {
String externalVideoUrl = data.getContent().getVideoUrl();
// 调用下载方法,和图片下载逻辑一致,存储到视频目录
if (status == 1 && vo.getContent() != null && vo.getContent().getVideoUrl() != null) {
String externalVideoUrl = vo.getContent().getVideoUrl();
// 调用下载方法,存储到视频目录
String ossUrl = downloadExternalUrlToOss(externalVideoUrl, OSS_VIDEO_DIR);
task.setResultResourceUrl(ossUrl);
aiGenerationTaskMapper.updateById(task);
@ -536,11 +520,23 @@ public class AiGenerationServiceImpl implements AiGenerationService {
.setFileSource("ai_generate")
.setMediaType("video")
.setSourceUrl(ossUrl)
.setDuration(data.getDuration())
.setDuration(vo.getDuration())
.setCreateBy(task.getCreateBy())
.setCreateTimestamp(System.currentTimeMillis())
.setCreateTime(new Date());
aiTaskMediaMapper.insert(media);
// 更新用户上传的参考文件:关联当前任务ID并软删除
LambdaUpdateWrapper<MiniAiTaskMedia> updateMediaWrapper = new LambdaUpdateWrapper<>();
updateMediaWrapper.eq(MiniAiTaskMedia::getMiniUserId, task.getMiniUserId())
.isNull(MiniAiTaskMedia::getTaskId)
.eq(MiniAiTaskMedia::getFileSource, "user_upload")
.eq(MiniAiTaskMedia::getDeleted, false)
.set(MiniAiTaskMedia::getTaskId, task.getId())
.set(MiniAiTaskMedia::getDeleted, true)
.set(MiniAiTaskMedia::getUpdateTime, new Date())
.set(MiniAiTaskMedia::getUpdateTimestamp, System.currentTimeMillis());
aiTaskMediaMapper.update(null, updateMediaWrapper);
}
success = true;

2
src/main/resources/application-dev.yml

@ -239,7 +239,7 @@ ai:
single-image-callback-url: http://192.168.31.197:30101/backend/api/v1/mini/ai/generation/single-image/task/callback
four-panel-callback-url: http://192.168.31.197:30101/backend/api/v1/mini/ai/generation/four-panel/task/callback
#需要内网穿透工具 由火山方舟 api 回调,ngrok http 30101 替换为内网穿透工具地址
video-url: http://192.168.31.197:30101/backend/api/v1/mini/ai/generation/video/task/callback
video-url: https://2dd0-153-34-180-144.ngrok-free.app/backend/api/v1/mini/ai/generation/video/task/callback
default:
image-model: doubao-seedream-5-0-260128
video-model: doubao-seedance-2-0-260128

Loading…
Cancel
Save