Prechádzať zdrojové kódy

1、上传视频文件、切片分离,异步切片并修改视频路径

liyanbo 8 mesiacov pred
rodič
commit
819a3d9cb3

+ 13 - 3
byzs-course/src/main/java/cn/iocoder/byzs/module/bjdx/service/course/CourseServiceImpl.java

@@ -10,6 +10,7 @@ import cn.iocoder.byzs.module.bjdx.controller.admin.course.vo.CourseRespVO;
 import cn.iocoder.byzs.module.bjdx.controller.admin.course.vo.CourseSaveReqVO;
 import cn.iocoder.byzs.module.bjdx.dal.dataobject.course.CourseDO;
 import cn.iocoder.byzs.module.bjdx.dal.mysql.course.CourseMapper;
+import cn.iocoder.byzs.module.infra.dal.dataobject.file.FileDO;
 import cn.iocoder.byzs.module.infra.framework.file.core.client.FileClient;
 import cn.iocoder.byzs.module.infra.service.file.FileConfigService;
 import cn.iocoder.byzs.module.infra.service.file.FileServiceImpl;
@@ -76,16 +77,25 @@ public class CourseServiceImpl implements CourseService {
         }
 
         //获取相对文件路径
-        String filePath= fileService.getFilePathByUrl(course.getCourseVideoPath());
-        if (StrUtil.isBlank(filePath)) {
+        FileDO fileDO= fileService.getFilePathByUrl(course.getCourseVideoPath());
+        if (fileDO == null || fileDO.getPath() == null) {
             return;
         }
 
         //切片
         FileClient client = fileConfigService.getMasterFileClient();
-        String m3u8Path = client.ffmpegHts(filePath);
+        String m3u8Path = client.ffmpegHts(fileDO.getPath());
         if(StrUtil.isNotEmpty(m3u8Path)){
             courseMapper.updateById(new CourseDO().setId(course.getId()).setCourseVideoPath(m3u8Path));
+            fileDO.setUrl(m3u8Path);
+            fileService.updateFileById(fileDO);
+
+            // 从文件存储器中删除【暂时不删除mp4文件,删除时需要同步更改fileDo中path的相对路径更改成m3u8文件】
+//            try {
+//                client.delete(courseVideoPath);
+//            } catch (Exception e) {
+//                throw new RuntimeException(e);
+//            }
         }
     }
 

+ 8 - 6
byzs-module-infra/src/main/java/cn/iocoder/byzs/module/infra/framework/file/core/client/local/LocalFileClient.java

@@ -26,12 +26,13 @@ public class LocalFileClient extends AbstractFileClient<LocalFileClientConfig> {
     }
 
     @Override
-    public String ffmpegHts(String pathMp4) {
-        pathMp4= getFilePath(pathMp4);
+    public String ffmpegHts(String path) {
+        String pathMp4= getFilePath(path);
         String filePathName = pathMp4.substring(0, pathMp4.lastIndexOf("."));
         String fileName = filePathName.substring(filePathName.lastIndexOf("/"));
         String pathM3u8 = filePathName + fileName;
         String pathM3u8Name = pathM3u8 + ".m3u8";
+        new File(filePathName).mkdirs();
         try {
             System.out.println("PATH环境变量: " + System.getenv("PATH"));
             // 构建FFmpeg命令进行HLS切片
@@ -39,7 +40,7 @@ public class LocalFileClient extends AbstractFileClient<LocalFileClientConfig> {
                     "ffmpeg", "-i", pathMp4,
                     "-c:v", "h264", "-c:a", "aac",
                     "-hls_time", "10", "-hls_list_size", "0",
-                    "-hls_segment_filename",  filePathName + "_%03d.ts",
+                    "-hls_segment_filename",  pathM3u8 + "_%03d.ts",
                     pathM3u8Name
             );
 
@@ -61,9 +62,10 @@ public class LocalFileClient extends AbstractFileClient<LocalFileClientConfig> {
             // 等待进程执行完成
             int exitCode = process.waitFor();
             if (exitCode == 0) {
-                pathM3u8 = pathM3u8.substring(pathM3u8.lastIndexOf(File.separator)+1);
-                System.out.println("视频切片成功,m3u8路径: " + pathM3u8);
-                return super.formatFileUrl(config.getDomain(), pathM3u8);
+                String dateStr = path.substring(0, 8);
+                pathM3u8Name = pathM3u8Name.substring(pathM3u8Name.lastIndexOf(dateStr));
+                System.out.println("视频切片成功,m3u8路径: " + pathM3u8Name);
+                return super.formatFileUrl(config.getDomain(), pathM3u8Name);
             } else {
                 System.err.println("FFmpeg执行失败,退出码: " + exitCode);
                 return null;

+ 9 - 1
byzs-module-infra/src/main/java/cn/iocoder/byzs/module/infra/service/file/FileService.java

@@ -74,6 +74,14 @@ public interface FileService {
      * @param url 文件url
      * @return 文件相对路径
      */
-    String getFilePathByUrl(String url);
+    FileDO getFilePathByUrl(String url);
+
+    /**
+     * 根据id修改文件路径
+     *
+     * @param fileDO 文件信息
+     * @return 影响行数
+     */
+    Integer updateFileById(FileDO fileDO);
 
 }

+ 7 - 12
byzs-module-infra/src/main/java/cn/iocoder/byzs/module/infra/service/file/FileServiceImpl.java

@@ -2,7 +2,6 @@ package cn.iocoder.byzs.module.infra.service.file;
 
 import cn.hutool.core.date.LocalDateTimeUtil;
 import cn.hutool.core.io.FileUtil;
-import cn.hutool.core.io.IoUtil;
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.crypto.digest.DigestUtil;
@@ -22,15 +21,6 @@ import jakarta.annotation.Resource;
 import lombok.SneakyThrows;
 import org.springframework.stereotype.Service;
 
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.Arrays;
-import java.util.List;
-import java.util.UUID;
-import java.util.stream.Collectors;
-
 import static cn.hutool.core.date.DatePattern.PURE_DATE_PATTERN;
 import static cn.iocoder.byzs.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.byzs.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS;
@@ -191,12 +181,17 @@ public class FileServiceImpl implements FileService {
     }
 
     @Override
-    public String getFilePathByUrl(String url) {
+    public FileDO getFilePathByUrl(String url) {
         FileDO fileDO = fileMapper.selectOne(new LambdaQueryWrapperX<FileDO>().eq(FileDO::getUrl, url));
         if (fileDO == null) {
             return null;
         }
-        return fileDO.getPath();
+        return fileDO;
+    }
+
+    @Override
+    public Integer updateFileById(FileDO fileDO) {
+        return fileMapper.updateById(fileDO);
     }
 
 }