Bläddra i källkod

Merge branch 'dev-volcengine' into develop

cmy 1 månad sedan
förälder
incheckning
3e0c8e5510

+ 15 - 9
src/main/java/com/backendsys/modules/ai/volcengine/controller/VolcengineVideoController.java

@@ -1,11 +1,9 @@
 package com.backendsys.modules.ai.volcengine.controller;
 
-import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoCollect;
-import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTask;
-import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskDTO;
-import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskDetail;
+import com.backendsys.modules.ai.volcengine.entity.*;
 import com.backendsys.modules.ai.volcengine.service.VolcengineVideoCollectService;
 import com.backendsys.modules.ai.volcengine.service.VolcengineVideoTaskService;
+import com.backendsys.modules.common.config.security.annotations.Anonymous;
 import com.backendsys.modules.common.config.security.utils.SecurityUtil;
 import com.backendsys.modules.common.utils.Result;
 import io.swagger.v3.oas.annotations.Operation;
@@ -28,7 +26,7 @@ public class VolcengineVideoController {
 
     @Operation(summary = "创建图生视频任务")
     @PreAuthorize("@sr.hasPermission('37.1.1')")
-    @PostMapping("/api/ai/volcegine/generateVideo")
+    @PostMapping("/api/ai/volcengine/generateVideo")
     public Result generateVideo(@Validated(VolcengineVideoTask.Generate.class) @RequestBody VolcengineVideoTask volcengineVideoTask) {
         volcengineVideoTask.setUser_id(SecurityUtil.getUserId());
         return Result.success().put("data", volcengineVideoTaskService.generateVideo(volcengineVideoTask));
@@ -36,7 +34,7 @@ public class VolcengineVideoController {
 
     @Operation(summary = "查询图生视频任务状态")
     @PreAuthorize("@sr.hasPermission('37.1.2')")
-    @GetMapping("/api/ai/volcegine/video/getTaskStatus/{volcengineTaskId}")
+    @GetMapping("/api/ai/volcengine/video/getTaskStatus/{volcengineTaskId}")
     public Result getTaskStatus(@PathVariable String volcengineTaskId) {
         return Result.success().put("data", volcengineVideoTaskService.selectTaskStatus(volcengineTaskId));
     }
@@ -44,7 +42,7 @@ public class VolcengineVideoController {
 
     @Operation(summary = "分页获取图生视频任务记录")
     @PreAuthorize("@sr.hasPermission('37.1.3')")
-    @GetMapping("/api/ai/volcegine/video/getTaskList")
+    @GetMapping("/api/ai/volcengine/video/getTaskList")
     public Result getTaskList(VolcengineVideoTaskDTO dto) {
         dto.setUser_id(SecurityUtil.getUserId());
         return Result.success().put("data", volcengineVideoTaskService.selectTaskList(dto));
@@ -52,7 +50,7 @@ public class VolcengineVideoController {
 
     @Operation(summary = "视频收藏/取消收藏")
     @PreAuthorize("@sr.hasPermission('37.1.4')")
-    @PutMapping("/api/ai/volcegine/video/setCollect")
+    @PutMapping("/api/ai/volcengine/video/setCollect")
     public Result setCollect(@Validated(VolcengineVideoCollect.Collect.class) @RequestBody VolcengineVideoCollect volcengineVideoCollect) {
         volcengineVideoCollect.setUser_id(SecurityUtil.getUserId());
         return Result.success().put("data", volcengineVideoCollectService.setCollect(volcengineVideoCollect));
@@ -60,10 +58,18 @@ public class VolcengineVideoController {
 
     @Operation(summary = "重新生成视频")
     @PreAuthorize("@sr.hasPermission('37.1.5')")
-    @PostMapping("/api/ai/volcegine/video/regenerate")
+    @PostMapping("/api/ai/volcengine/video/regenerate")
     public Result regenerate(@Validated(VolcengineVideoTaskDetail.Regenerate.class) @RequestBody VolcengineVideoTaskDetail volcengineVideoTaskDetail) {
         volcengineVideoTaskDetail.setUser_id(SecurityUtil.getUserId());
         return Result.success().put("data", volcengineVideoTaskService.regenerate(volcengineVideoTaskDetail));
     }
 
+    @Anonymous
+    @Operation(summary = "图生视频状态通知")
+    @PostMapping("/api/ai/volcengine/video/notify")
+    public Result notify(@Validated @RequestBody VolcengineVideoTaskNotify volcengineVideoTaskNotify) {
+        volcengineVideoTaskService.notify(volcengineVideoTaskNotify);
+        return Result.success();
+    }
+
 }

+ 1 - 1
src/main/java/com/backendsys/modules/ai/volcengine/entity/VolcengineVideoTaskDetail.java

@@ -16,7 +16,7 @@ import java.time.LocalDateTime;
 @Data
 public class VolcengineVideoTaskDetail {
 
-    public static interface Regenerate{}
+    public interface Regenerate{}
 
     @NotNull(message = "id不能为空", groups = { VolcengineVideoTaskDetail.Regenerate.class })
     @TableId(type = IdType.AUTO)

+ 71 - 0
src/main/java/com/backendsys/modules/ai/volcengine/entity/VolcengineVideoTaskNotify.java

@@ -0,0 +1,71 @@
+package com.backendsys.modules.ai.volcengine.entity;
+
+import com.volcengine.ark.runtime.model.content.generation.GetContentGenerationTaskResponse;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * 火山大模型图生视频状态通知
+ */
+@Data
+public class VolcengineVideoTaskNotify {
+    /**
+     * 任务id
+     */
+    @NotBlank(message = "任务id不能为空")
+    private String id;
+    /**
+     * 模型名称
+     */
+    private String model;
+
+    /**
+     * 任务状态
+     * queued:排队中。
+     * running:任务运行中。
+     * cancelled:取消任务,取消状态24h自动删除(只支持排队中状态的任务被取消)。
+     * succeeded: 任务成功。
+     * failed:任务失败。
+     */
+    private String status;
+    /**
+     * 错误提示信息,任务成功返回null,任务失败时返回错误数据
+     */
+    private GetContentGenerationTaskResponse.ContentGenerationError error;
+
+    /**
+     * 任务创建时间的 Unix 时间戳(秒)
+     */
+    private Long created_at;
+    /**
+     * 任务当前状态更新时间的 Unix 时间戳(秒)
+     */
+    private Long updated_at;
+
+    /**
+     * 当视频生成任务完成,会输出该字段,包含生成视频下载的 URL
+     * content.video_url
+     */
+    private GetContentGenerationTaskResponse.Content content;
+    /**
+     * 种子
+     */
+    private Integer seed;
+    /**
+     * 分辨率
+     */
+    private String resolution;
+    /**
+     * 生成视频的宽高比
+     */
+    private String ratio;
+    /**
+     * 视频时长 秒
+     */
+    private Integer duration;
+    /**
+     * 生成视频的帧率
+     */
+    private Integer framespersecond;
+}

+ 3 - 0
src/main/java/com/backendsys/modules/ai/volcengine/service/VolcengineVideoTaskService.java

@@ -3,6 +3,7 @@ package com.backendsys.modules.ai.volcengine.service;
 import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTask;
 import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskDTO;
 import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskDetail;
+import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskNotify;
 import com.backendsys.utils.response.PageEntity;
 import com.baomidou.mybatisplus.extension.service.IService;
 
@@ -15,4 +16,6 @@ public interface VolcengineVideoTaskService extends IService<VolcengineVideoTask
     PageEntity selectTaskList(VolcengineVideoTaskDTO dto);
 
     VolcengineVideoTaskDetail regenerate(VolcengineVideoTaskDetail volcengineVideoTaskDetail);
+
+    void notify(VolcengineVideoTaskNotify volcengineVideoTaskNotify);
 }

+ 49 - 2
src/main/java/com/backendsys/modules/ai/volcengine/service/impl/VolcengineVideoTaskServiceImpl.java

@@ -5,6 +5,7 @@ import com.backendsys.modules.ai.volcengine.dao.VolcengineVideoTaskDao;
 import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTask;
 import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskDTO;
 import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskDetail;
+import com.backendsys.modules.ai.volcengine.entity.VolcengineVideoTaskNotify;
 import com.backendsys.modules.ai.volcengine.service.VolcengineVideoTaskDetailService;
 import com.backendsys.modules.ai.volcengine.service.VolcengineVideoTaskService;
 import com.backendsys.modules.common.config.security.utils.SecurityUtil;
@@ -47,6 +48,9 @@ public class VolcengineVideoTaskServiceImpl extends ServiceImpl<VolcengineVideoT
     @Value("${volcengine.api-key}")
     private String apiKey;
 
+    @Value("${domain}")
+    private String domain;
+
     private final ConnectionPool connectionPool = new ConnectionPool(20, 5, TimeUnit.MINUTES);
     private final Dispatcher dispatcher = new Dispatcher();
     private ArkService service;
@@ -99,12 +103,13 @@ public class VolcengineVideoTaskServiceImpl extends ServiceImpl<VolcengineVideoT
                         .url(volcengineVideoTask.getImg_url())
                         .build())
                 .build());
+        String notifyUrl = domain+ "/api/ai/volcengine/video/notify";
         // 创建视频生成任务
         CreateContentGenerationTaskRequest createRequest = CreateContentGenerationTaskRequest.builder()
                 .model(volcengineVideoTask.getModel())
                 .content(contents)
-                // todo callback_url 回调地址
-//                .callbackUrl()
+                // 回调地址
+                .callbackUrl(notifyUrl)
                 .build();
 
         //根据数量生成任务,记录明细
@@ -296,4 +301,46 @@ public class VolcengineVideoTaskServiceImpl extends ServiceImpl<VolcengineVideoT
         return dataBean;
 
     }
+
+    @Override
+    public void notify(VolcengineVideoTaskNotify notify) {
+
+        VolcengineVideoTaskDetail dataBean = volcengineVideoTaskDetailService.getOne(Wrappers.<VolcengineVideoTaskDetail>lambdaQuery()
+                .eq(VolcengineVideoTaskDetail::getVolcengine_task_id, notify.getId()));
+        if (dataBean == null) {
+            log.error("图生视频通知异常,找不到任务明细,通知内容:" + notify);
+            throw new CustException("图生视频通知异常,找不到任务明细");
+        }
+
+        if("succeeded".equals(dataBean.getStatus()) || "failed".equals(dataBean.getStatus())) {
+            // 任务已经完成,不再处理
+            return;
+        }
+
+        // 任务状态
+        dataBean.setStatus(notify.getStatus());
+
+        if(notify.getSeed() != null) {
+            dataBean.setSeed(notify.getSeed());
+        }
+
+        if("succeeded".equals(notify.getStatus())) {
+            // 成功
+            String videoOriginUrl = notify.getContent().getVideoUrl();
+            dataBean.setVideo_origin_url(videoOriginUrl);
+
+            // URL转存文件
+            SysFileResult sysFileResult = sysFileService.urlToUploadFile(videoOriginUrl, SecurityUtil.getUserId());
+            String objectKey = sysFileResult.getKey();
+            String videoUrl = sysFileResult.getDomain() + "/" + sysFileResult.getKey();
+            dataBean.setVideo_url(videoUrl);
+            dataBean.setObject_key(objectKey);
+        } else {
+            if(notify.getError() !=null) {
+                dataBean.setError_msg(notify.getError().toString());
+            }
+        }
+        // 更新任务信息
+        volcengineVideoTaskDetailService.updateById(dataBean);
+    }
 }

+ 4 - 1
src/main/resources/application-dev.yml

@@ -220,4 +220,7 @@ comfyui:
 
 # 火山大模型
 volcengine:
-  api-key: ea19ba93-41fa-4bd9-90ec-6b203be84e33
+  api-key: ea19ba93-41fa-4bd9-90ec-6b203be84e33
+
+# 接口域名(用于通知)
+domain: https://dev.manage.daogu.ai

+ 4 - 1
src/main/resources/application-local.yml

@@ -230,4 +230,7 @@ comfyui:
 
 # 火山大模型
 volcengine:
-  api-key: ea19ba93-41fa-4bd9-90ec-6b203be84e33
+  api-key: ea19ba93-41fa-4bd9-90ec-6b203be84e33
+
+# 接口域名(用于通知)
+domain: https://dev.manage.daogu.ai

+ 4 - 1
src/main/resources/application-prod.yml

@@ -221,4 +221,7 @@ comfyui:
 
 # 火山大模型
 volcengine:
-  api-key: ea19ba93-41fa-4bd9-90ec-6b203be84e33
+  api-key: ea19ba93-41fa-4bd9-90ec-6b203be84e33
+
+# 接口域名(用于通知)
+domain: https://manage.daogu.ai