|
|
@@ -90,6 +90,68 @@ public class TbFileServiceImpl extends ServiceImpl<TbFileMapper, TbFile> impleme
|
|
|
return DigestUtil.md5Hex(bytes);
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public AjaxResult uploadVideoFile(MultipartFile file) {
|
|
|
+ AjaxResult ajax = AjaxResult.success();
|
|
|
+ try {
|
|
|
+ // 计算文件 MD5 值
|
|
|
+ String md5 = calculateMD5(file);
|
|
|
+ // 检查是否已存在相同文件(通过 MD5 去重)
|
|
|
+ TbFile dbFile = this.getByMd5(md5);
|
|
|
+ if (null != dbFile) {
|
|
|
+ // 文件已存在,直接返回已有文件的访问信息(秒传)
|
|
|
+ ajax.put("url", dbFile.getFileUrl());
|
|
|
+ ajax.put("fileName", dbFile.getFileUrl());
|
|
|
+ ajax.put("newFileName", FileUtils.getName(dbFile.getFileUrl()));
|
|
|
+ ajax.put("originalFilename", dbFile.getFileName());
|
|
|
+ // 封面图URL路径(针对视频文件)
|
|
|
+ ajax.put("coverUrl", dbFile.getCoverUrl());
|
|
|
+ return ajax;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 文件不存在,上传新文件
|
|
|
+ // 获取上传文件路径配置
|
|
|
+ String filePath = RuoYiConfig.getUploadPath();
|
|
|
+ // 上传文件到服务器并返回新的文件名称
|
|
|
+ String fileName = FileUploadUtils.upload(filePath, file);
|
|
|
+ log.info("上传文件到服务器并返回新的文件名称:{}", fileName);
|
|
|
+ //获取新的文件子路径
|
|
|
+ String subFileName= fileName.substring(fileName.indexOf("/upload") + 7);
|
|
|
+ // 构建完整的文件访问路径
|
|
|
+ subFileName = filePath + subFileName;
|
|
|
+ log.info("上传文件的路径:{},返回的新文件路径:{}", filePath, subFileName);
|
|
|
+
|
|
|
+ //生成视频的封面图片文件(该方法内部会执行 FFmpeg 命令并验证)
|
|
|
+ String thumbnailFilePath = generateThumbnailFilePath(subFileName, file.getOriginalFilename());
|
|
|
+ String substring = thumbnailFilePath.substring(thumbnailFilePath.lastIndexOf("\\upload"));
|
|
|
+
|
|
|
+ substring = "/profile" + substring;
|
|
|
+ log.info("生成视频的封面图片文件路径:{}", substring);
|
|
|
+ substring = substring.replace("\\", "/");
|
|
|
+
|
|
|
+ // 构建文件访问的完整 URL
|
|
|
+ //String url = serverConfig.getUrl() + fileName;
|
|
|
+ ajax.put("url", fileName);
|
|
|
+ ajax.put("fileName", fileName);
|
|
|
+ ajax.put("newFileName", FileUtils.getName(fileName));
|
|
|
+ ajax.put("originalFilename", file.getOriginalFilename());
|
|
|
+ // 封面图URL路径(针对视频文件)
|
|
|
+ ajax.put("coverUrl", substring);
|
|
|
+
|
|
|
+ // 保存文件记录到数据库
|
|
|
+ TbFile tbFile = new TbFile();
|
|
|
+ tbFile.setMd5(md5);
|
|
|
+ tbFile.setFileName(file.getOriginalFilename());
|
|
|
+ tbFile.setFileUrl(fileName);
|
|
|
+ tbFile.setCoverUrl(substring);
|
|
|
+ this.save(tbFile);
|
|
|
+ return ajax;
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 上传失败,返回错误信息
|
|
|
+ return AjaxResult.error(e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 上传文件并返回文件访问信息
|
|
|
* <p>
|
|
|
@@ -122,8 +184,6 @@ public class TbFileServiceImpl extends ServiceImpl<TbFileMapper, TbFile> impleme
|
|
|
ajax.put("fileName", dbFile.getFileUrl());
|
|
|
ajax.put("newFileName", FileUtils.getName(dbFile.getFileUrl()));
|
|
|
ajax.put("originalFilename", dbFile.getFileName());
|
|
|
- // 封面图URL路径(针对视频文件)
|
|
|
- ajax.put("coverUrl", dbFile.getCoverUrl());
|
|
|
return ajax;
|
|
|
}
|
|
|
|
|
|
@@ -138,30 +198,17 @@ public class TbFileServiceImpl extends ServiceImpl<TbFileMapper, TbFile> impleme
|
|
|
// 构建完整的文件访问路径
|
|
|
subFileName = filePath + subFileName;
|
|
|
log.info("上传文件路径:{},返回的新文件路径:{}", filePath, subFileName);
|
|
|
-
|
|
|
- //生成视频的封面图片文件(该方法内部会执行 FFmpeg 命令并验证)
|
|
|
- String thumbnailFilePath = generateThumbnailFilePath(subFileName, file.getOriginalFilename());
|
|
|
- String substring = thumbnailFilePath.substring(thumbnailFilePath.lastIndexOf("\\upload"));
|
|
|
-
|
|
|
- substring = "/profile" + substring;
|
|
|
- log.info("生成视频的封面图片文件路径:{}", substring);
|
|
|
- substring = substring.replace("\\", "/");
|
|
|
-
|
|
|
// 构建文件访问的完整 URL
|
|
|
- //String url = serverConfig.getUrl() + fileName;
|
|
|
ajax.put("url", fileName);
|
|
|
ajax.put("fileName", fileName);
|
|
|
ajax.put("newFileName", FileUtils.getName(fileName));
|
|
|
ajax.put("originalFilename", file.getOriginalFilename());
|
|
|
- // 封面图URL路径(针对视频文件)
|
|
|
- ajax.put("coverUrl", substring);
|
|
|
|
|
|
// 保存文件记录到数据库
|
|
|
TbFile tbFile = new TbFile();
|
|
|
tbFile.setMd5(md5);
|
|
|
tbFile.setFileName(file.getOriginalFilename());
|
|
|
tbFile.setFileUrl(fileName);
|
|
|
- tbFile.setCoverUrl(substring);
|
|
|
this.save(tbFile);
|
|
|
return ajax;
|
|
|
} catch (Exception e) {
|
|
|
@@ -182,7 +229,7 @@ public class TbFileServiceImpl extends ServiceImpl<TbFileMapper, TbFile> impleme
|
|
|
*
|
|
|
* @param videoPath 视频文件路径
|
|
|
* @param originalFilename 原始视频文件名(用于生成缩略图文件名)
|
|
|
- * @return 生成的封面图片文件绝对路径
|
|
|
+ * @return String 生成的封面图片文件绝对路径
|
|
|
* @throws IOException 如果目录创建失败
|
|
|
* @throws VideoThumbnailService.VideoProcessException 如果封面生成失败或验证失败
|
|
|
*/
|
|
|
@@ -202,7 +249,8 @@ public class TbFileServiceImpl extends ServiceImpl<TbFileMapper, TbFile> impleme
|
|
|
try {
|
|
|
executeFfmpegCommand(videoPath, thumbnailPathStr);
|
|
|
log.info("FFmpeg 命令执行成功");
|
|
|
- } catch (InterruptedException e) {
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
Thread.currentThread().interrupt();
|
|
|
throw new VideoThumbnailService.VideoProcessException("封面生成过程被中断", e);
|
|
|
}
|
|
|
@@ -215,6 +263,9 @@ public class TbFileServiceImpl extends ServiceImpl<TbFileMapper, TbFile> impleme
|
|
|
|
|
|
/**
|
|
|
* 获取不带扩展名的文件名
|
|
|
+ *
|
|
|
+ * @param filename 文件名(包含扩展名)
|
|
|
+ * @return String 不带扩展名的文件名
|
|
|
*/
|
|
|
private String getFileNameWithoutExtension(String filename) {
|
|
|
if (filename == null || filename.isEmpty()) {
|
|
|
@@ -227,6 +278,9 @@ public class TbFileServiceImpl extends ServiceImpl<TbFileMapper, TbFile> impleme
|
|
|
|
|
|
/**
|
|
|
* 执行 FFmpeg 命令截取封面
|
|
|
+ *
|
|
|
+ * @param videoPath 视频文件路径
|
|
|
+ * @param thumbnailPath 封面图片保存路径
|
|
|
*/
|
|
|
private void executeFfmpegCommand(String videoPath, String thumbnailPath) throws IOException, InterruptedException, VideoThumbnailService.VideoProcessException {
|
|
|
// 构建 FFmpeg 命令
|
|
|
@@ -295,7 +349,8 @@ public class TbFileServiceImpl extends ServiceImpl<TbFileMapper, TbFile> impleme
|
|
|
throw new VideoThumbnailService.VideoProcessException("生成的文件不是有效的图片");
|
|
|
}
|
|
|
} catch (IOException e) {
|
|
|
- log.warn("无法验证文件 MIME 类型", e);
|
|
|
+ e.printStackTrace();
|
|
|
+ log.info("无法验证文件 MIME 类型", e);
|
|
|
}
|
|
|
}
|
|
|
}
|