Jelajahi Sumber

视频转码回调接口的开发

yfh 1 hari lalu
induk
melakukan
8bd5804fba

+ 111 - 17
fs-admin/src/main/java/com/fs/course/controller/FsUserVideoController.java

@@ -1,35 +1,38 @@
 package com.fs.course.controller;
 
-import java.io.*;
-import java.util.Date;
-import java.util.List;
-import java.util.UUID;
-
+import com.alibaba.fastjson.JSON;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
-import com.fs.course.param.FsUserVideoAddParam;
-import com.fs.course.param.FsUserVideoAuditParam;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.StringUtils;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.course.domain.FsUserVideo;
+import com.fs.course.domain.FsVideoResource;
+import com.fs.course.param.*;
+import com.fs.course.service.IFsUserVideoService;
+import com.fs.course.service.IFsVideoResourceService;
+import com.fs.course.service.impl.TencentCloudCosService;
 import com.fs.course.vo.FsUserVideoListPVO;
 import com.fs.course.vo.FsUserVideoPVO;
-import com.fs.course.param.FsUserVideoParam;
 import com.fs.his.service.IFsPackageService;
 import com.fs.his.vo.FsPackageVO;
 import com.fs.system.oss.CloudStorageService;
 import com.fs.system.oss.OSSFactory;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.io.FilenameUtils;
-import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
-import com.fs.common.annotation.Log;
-import com.fs.common.core.controller.BaseController;
-import com.fs.common.core.domain.AjaxResult;
-import com.fs.common.enums.BusinessType;
-import com.fs.course.domain.FsUserVideo;
-import com.fs.course.service.IFsUserVideoService;
-import com.fs.common.utils.poi.ExcelUtil;
-import com.fs.common.core.page.TableDataInfo;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.io.*;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
 /**
  * 课堂视频Controller
  *
@@ -43,9 +46,15 @@ public class FsUserVideoController extends BaseController
 {
     @Autowired
     private IFsUserVideoService fsUserVideoService;
+
+    @Autowired
+    private TencentCloudCosService tencentCloudCosService;
     @Autowired
     private IFsPackageService fsPackageService;
 
+    @Autowired
+    private IFsVideoResourceService iFsVideoResourceService;
+
     /**
      * 查询课堂视频列表
      */
@@ -265,4 +274,89 @@ public class FsUserVideoController extends BaseController
         }
         return R.ok();
     }
+
+    /**
+     * 点播编排转码
+     * @return
+     */
+    @PostMapping("/videoTranscode")
+    public R videoTranscode(@RequestBody String rawBody) {
+        try {
+            // 解析输入JSON
+            VideoTranscodeParam videoTranscodeParam = JSON.parseObject(rawBody, VideoTranscodeParam.class);
+            if (videoTranscodeParam == null || videoTranscodeParam.getScheduleTaskEvent() == null) {
+                log.error("请求体格式无效或缺少scheduleTaskEvent信息");
+                return R.error("请求格式无效");
+            }
+
+            // 检查错误码
+            VideoScheduleTaskEventParam event = videoTranscodeParam.getScheduleTaskEvent();
+            if (!Integer.valueOf(0).equals(event.getErrCode())) {
+                log.warn("收到转码事件非零错误码: {}", event.getErrCode());
+                return R.ok(); // 仍然返回ok确认已处理通知
+            }
+
+            // 验证输入路径
+            if (event.getInputInfo() == null || event.getInputInfo().getCosInputInfo() == null) {
+                log.error("转码事件中缺少输入信息");
+                return R.error("缺少输入信息");
+            }
+
+            String inputPaths = event.getInputInfo().getCosInputInfo().getObject();
+            if (StringUtils.isBlank(inputPaths)) {
+                log.error("转码事件中的输入路径为空");
+                return R.error("输入路径为空");
+            }
+
+            // 移除可能的前导斜杠
+            String inputPath = inputPaths.startsWith("/") ? inputPaths.substring(1) : inputPaths;
+
+            // 查找视频资源
+            FsVideoResource video = iFsVideoResourceService.selectByFileKey(inputPath);
+            if (video == null) {
+                log.warn("未找到文件键对应的视频资源: {}", inputPath);
+                return R.ok();
+            }
+
+            // 验证输出路径
+            if (event.getActivityResultSet() == null || event.getActivityResultSet().isEmpty()) {
+                log.error("转码事件中缺少活动结果集");
+                return R.error("缺少活动结果");
+            }
+
+            VideoActivityResItemParam activityResItem = event.getActivityResultSet().get(0).getActivityResItem();
+            if (activityResItem == null || activityResItem.getTranscodeTask() == null ||
+                    activityResItem.getTranscodeTask().getOutput() == null) {
+                log.error("转码任务信息不完整");
+                return R.error("转码任务不完整");
+            }
+
+            String outputPath = activityResItem.getTranscodeTask().getOutput().getPath();
+            if (StringUtils.isBlank(outputPath)) {
+                log.error("转码事件中的输出路径为空");
+                return R.error("输出路径为空");
+            }
+
+            // 移除可能的前导斜杠
+            String transcodeFileKey = outputPath.startsWith("/") ? outputPath.substring(1) : outputPath;
+
+            // 提交转码作业
+            log.info("开始提交转码作业,输入路径: {}, 输出路径: {}", inputPaths, outputPath);
+            tencentCloudCosService.submitTranscodeJob(inputPaths, outputPath);
+
+            // 更新视频资源
+            FsVideoResource videoMap = new FsVideoResource();
+            videoMap.setId(video.getId());
+            videoMap.setIsTranscode(1);
+            videoMap.setLine1(video.getLine1().replace(inputPath,transcodeFileKey));
+            videoMap.setTranscodeFileKey(transcodeFileKey);
+            iFsVideoResourceService.updateById(videoMap);
+            log.info("成功更新视频转码状态,视频ID: {}", video.getId());
+
+            return R.ok();
+        } catch (Exception e) {
+            log.error("处理视频转码请求时发生异常", e);
+            return R.error("服务器内部错误");
+        }
+    }
 }

+ 1 - 0
fs-framework/src/main/java/com/fs/framework/config/SecurityConfig.java

@@ -142,6 +142,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 .antMatchers("/webjars/**").anonymous()
                 .antMatchers("/*/api-docs").anonymous()
                 .antMatchers("/druid/**").anonymous()
+                .antMatchers("/course/userVideo/videoTranscode").anonymous()
                 // 除上面外的所有请求全部需要鉴权认证
                 .anyRequest().authenticated()
                 .and()

+ 10 - 0
fs-service/src/main/java/com/fs/course/param/VideoActivityResItemParam.java

@@ -0,0 +1,10 @@
+package com.fs.course.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class VideoActivityResItemParam implements Serializable {
+    private VideoTranscodeTaskParam TranscodeTask;
+}

+ 12 - 0
fs-service/src/main/java/com/fs/course/param/VideoActivityResultSetParam.java

@@ -0,0 +1,12 @@
+package com.fs.course.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class VideoActivityResultSetParam implements Serializable {
+    private String ActivityType;
+    private VideoActivityResItemParam ActivityResItem;
+
+}

+ 10 - 0
fs-service/src/main/java/com/fs/course/param/VideoCosInputInfoParam.java

@@ -0,0 +1,10 @@
+package com.fs.course.param;
+
+import lombok.Data;
+
+@Data
+public class VideoCosInputInfoParam {
+    private String bucket;
+    private String region;
+    private String object;
+}

+ 9 - 0
fs-service/src/main/java/com/fs/course/param/VideoInputInfoParam.java

@@ -0,0 +1,9 @@
+package com.fs.course.param;
+
+import lombok.Data;
+@Data
+public class VideoInputInfoParam {
+    private String type;
+    private VideoCosInputInfoParam cosInputInfo;
+
+}

+ 8 - 0
fs-service/src/main/java/com/fs/course/param/VideoOutputParam.java

@@ -0,0 +1,8 @@
+package com.fs.course.param;
+
+import lombok.Data;
+
+@Data
+public class VideoOutputParam {
+    private String path;
+}

+ 16 - 0
fs-service/src/main/java/com/fs/course/param/VideoScheduleTaskEventParam.java

@@ -0,0 +1,16 @@
+package com.fs.course.param;
+
+import lombok.Data;
+
+import java.util.List;
+@Data
+public class VideoScheduleTaskEventParam {
+    private String TaskId;
+    private String Status;
+    private Integer ErrCode;
+    private String Message;
+    private VideoInputInfoParam InputInfo;
+    private List<VideoActivityResultSetParam> ActivityResultSet;
+
+
+}

+ 10 - 0
fs-service/src/main/java/com/fs/course/param/VideoTranscodeParam.java

@@ -0,0 +1,10 @@
+package com.fs.course.param;
+
+import lombok.Data;
+
+@Data
+public class VideoTranscodeParam {
+    private String EventType;
+    private VideoScheduleTaskEventParam ScheduleTaskEvent;
+
+}

+ 18 - 0
fs-service/src/main/java/com/fs/course/param/VideoTranscodeTaskParam.java

@@ -0,0 +1,18 @@
+package com.fs.course.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class VideoTranscodeTaskParam implements Serializable {
+    private String Status;
+    private Integer ErrCode;
+    private String ErrCodeExt;
+    private String Message;
+    private String BeginProcessTime;
+    private String FinishTime;
+    private VideoOutputParam Output;
+    private Integer Progress;
+
+}

+ 8 - 0
fs-service/src/main/java/com/fs/course/service/IFsVideoResourceService.java

@@ -16,4 +16,12 @@ public interface IFsVideoResourceService extends IService<FsVideoResource> {
      * @return  list
      */
     List<FsVideoResourceVO> selectVideoResourceListByMap(Map<String, Object> params);
+
+    /**
+     * 通过filekey查询数据信息
+     *
+     * @param fileKey
+     * @return
+     */
+    FsVideoResource selectByFileKey(String fileKey);
 }

+ 13 - 0
fs-service/src/main/java/com/fs/course/service/impl/FsVideoResourceServiceImpl.java

@@ -1,5 +1,6 @@
 package com.fs.course.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fs.course.domain.FsVideoResource;
 import com.fs.course.mapper.FsVideoResourceMapper;
@@ -23,4 +24,16 @@ public class FsVideoResourceServiceImpl extends ServiceImpl<FsVideoResourceMappe
     public List<FsVideoResourceVO> selectVideoResourceListByMap(Map<String, Object> params) {
         return baseMapper.selectVideoResourceListByMap(params);
     }
+
+    /**
+     * 通过fileKey查询数据信息
+     *
+     * @param fileKey
+     * @return
+     */
+    @Override
+    public FsVideoResource selectByFileKey(String fileKey) {
+        FsVideoResource fsVideoResource = baseMapper.selectOne(new LambdaQueryWrapper<FsVideoResource>().eq(FsVideoResource::getFileKey, fileKey));
+        return fsVideoResource;
+    }
 }