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. 48
      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: 后续在回调中 增加用户小程序订阅通知 //TODO: 后续在回调中 增加用户小程序订阅通知
} }

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

@ -1,5 +1,6 @@
package com.youlai.boot.mini.model.vo; package com.youlai.boot.mini.model.vo;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
@ -10,19 +11,60 @@ import lombok.Data;
* @author youlai * @author youlai
*/ */
@Data @Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "AI视频生成任务回调请求") @Schema(description = "AI视频生成任务回调请求")
public class AiVideoCallbackVO { public class AiVideoCallbackVO {
@Schema(description = "响应消息") @Schema(description = "第三方视频任务唯一ID")
private String msg; private String id;
@Schema(description = "响应码,0表示成功") @Schema(description = "使用的模型ID")
private Integer code; private String model;
@Schema(description = "回调数据") @Schema(description = "任务状态:queued排队中/running处理中/succeeded成功/failed失败")
private VideoCallbackData data; private String status;
@JsonProperty("request_id") @JsonProperty("created_at")
@Schema(description = "请求ID") @Schema(description = "创建时间戳")
private String requestId; 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; package com.youlai.boot.mini.model.vo;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
@ -10,6 +11,7 @@ import lombok.Data;
* @author youlai * @author youlai
*/ */
@Data @Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "AI视频生成回调结果内容") @Schema(description = "AI视频生成回调结果内容")
public class VideoCallbackContent { 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; package com.youlai.boot.mini.model.vo;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
/** /**
* AI视频生成资源消耗统计 * 视频生成资源消耗统计
* *
* @author youlai * @author youlai
*/ */
@Data @Data
@Schema(description = "AI视频生成资源消耗统计") @JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "视频生成资源消耗统计")
public class VideoCallbackUsage { public class VideoCallbackUsage {
@JsonProperty("completion_tokens") @JsonProperty("completion_tokens")

48
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.vo.AiVideoCallbackVO;
import com.youlai.boot.mini.model.form.AiCallbackImage; import com.youlai.boot.mini.model.form.AiCallbackImage;
import com.youlai.boot.mini.model.form.AiFourPanelCallbackForm; 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.AiGenerationService;
import com.youlai.boot.mini.service.MiniPointRecordService; import com.youlai.boot.mini.service.MiniPointRecordService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -49,9 +46,7 @@ import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture;
@Slf4j @Slf4j
@Service @Service
@ -480,19 +475,7 @@ public class AiGenerationServiceImpl implements AiGenerationService {
log.info("处理AI视频生成任务回调,请求参数:{}", JSONUtil.toJsonStr(vo)); log.info("处理AI视频生成任务回调,请求参数:{}", JSONUtil.toJsonStr(vo));
boolean success = false; boolean success = false;
try { try {
// 校验回调响应是否成功 String videoTaskUuid = vo.getId();
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();
// 根据第三方返回的视频任务uuid查询对应的任务 // 根据第三方返回的视频任务uuid查询对应的任务
MiniAiGenerationTask task = aiGenerationTaskMapper.selectOne(new LambdaQueryWrapper<MiniAiGenerationTask>() MiniAiGenerationTask task = aiGenerationTaskMapper.selectOne(new LambdaQueryWrapper<MiniAiGenerationTask>()
.eq(MiniAiGenerationTask::getVideoTaskUuid, videoTaskUuid) .eq(MiniAiGenerationTask::getVideoTaskUuid, videoTaskUuid)
@ -504,13 +487,14 @@ public class AiGenerationServiceImpl implements AiGenerationService {
// 转换任务状态 // 转换任务状态
Integer status; Integer status;
if ("succeeded".equals(data.getStatus())) { if ("succeeded".equals(vo.getStatus())) {
status = 1; // 成功 status = 1; // 成功
} else if ("failed".equals(data.getStatus())) { } else if ("failed".equals(vo.getStatus())) {
status = 2; // 失败 status = 2; // 失败
} else { } else {
log.info("视频任务{}处于中间状态:{},不处理", task.getUuid(), data.getStatus()); // queued/running中间状态直接返回成功,不更新任务
return true; // 中间状态直接返回成功,不更新任务 log.info("视频任务{}处于中间状态:{},不处理", task.getUuid(), vo.getStatus());
return true;
} }
// 更新任务状态 // 更新任务状态
@ -520,9 +504,9 @@ public class AiGenerationServiceImpl implements AiGenerationService {
aiGenerationTaskMapper.updateById(task); aiGenerationTaskMapper.updateById(task);
// 如果生成成功,下载外部视频到OSS // 如果生成成功,下载外部视频到OSS
if (status == 1 && data.getContent() != null && data.getContent().getVideoUrl() != null) { if (status == 1 && vo.getContent() != null && vo.getContent().getVideoUrl() != null) {
String externalVideoUrl = data.getContent().getVideoUrl(); String externalVideoUrl = vo.getContent().getVideoUrl();
// 调用下载方法,和图片下载逻辑一致,存储到视频目录 // 调用下载方法,存储到视频目录
String ossUrl = downloadExternalUrlToOss(externalVideoUrl, OSS_VIDEO_DIR); String ossUrl = downloadExternalUrlToOss(externalVideoUrl, OSS_VIDEO_DIR);
task.setResultResourceUrl(ossUrl); task.setResultResourceUrl(ossUrl);
aiGenerationTaskMapper.updateById(task); aiGenerationTaskMapper.updateById(task);
@ -536,11 +520,23 @@ public class AiGenerationServiceImpl implements AiGenerationService {
.setFileSource("ai_generate") .setFileSource("ai_generate")
.setMediaType("video") .setMediaType("video")
.setSourceUrl(ossUrl) .setSourceUrl(ossUrl)
.setDuration(data.getDuration()) .setDuration(vo.getDuration())
.setCreateBy(task.getCreateBy()) .setCreateBy(task.getCreateBy())
.setCreateTimestamp(System.currentTimeMillis()) .setCreateTimestamp(System.currentTimeMillis())
.setCreateTime(new Date()); .setCreateTime(new Date());
aiTaskMediaMapper.insert(media); 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; 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 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 four-panel-callback-url: http://192.168.31.197:30101/backend/api/v1/mini/ai/generation/four-panel/task/callback
#需要内网穿透工具 由火山方舟 api 回调,ngrok http 30101 替换为内网穿透工具地址 #需要内网穿透工具 由火山方舟 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: default:
image-model: doubao-seedream-5-0-260128 image-model: doubao-seedream-5-0-260128
video-model: doubao-seedance-2-0-260128 video-model: doubao-seedance-2-0-260128

Loading…
Cancel
Save