feat: 功能优化

This commit is contained in:
2026-02-04 01:46:55 +08:00
parent 0e1b6fe643
commit b1bd711cea
6 changed files with 300 additions and 495 deletions

View File

@@ -365,86 +365,14 @@ public class LatentsyncPollingService {
}
/**
* 保存视频到OSS - 直接保存到 infra_file 避免重复
* 返回保存结果包含URL、文件大小和文件ID
* 保存远程视频URL
* 简化版直接保存Kling返回的URL不再下载上传到OSS
*/
private OssSaveResult saveVideoToOss(TikDigitalHumanTaskDO task, String remoteVideoUrl) throws Exception {
log.info("[saveVideoToOss][任务({})开始下载并保存视频到OSS][remoteUrl={}]", task.getId(), remoteVideoUrl);
log.info("[saveVideoToOss][任务({})直接保存Kling URL][url={}]", task.getId(), remoteVideoUrl);
try {
// 1. 下载远程视频文件
byte[] videoBytes = downloadRemoteFile(remoteVideoUrl);
// 2. 内存检查超过50MB记录警告
int sizeMB = videoBytes.length / 1024 / 1024;
if (sizeMB > 50) {
log.warn("[saveVideoToOss][任务({})视频文件较大][size={}MB]", task.getId(), sizeMB);
}
// 3. 获取OSS目录和文件名
Long userId = task.getUserId();
String baseDirectory = ossInitService.getOssDirectoryByCategory(userId, "generate");
String fileName = String.format("数字人视频_%d_%d.mp4", task.getId(), System.currentTimeMillis());
// 4. 获取FileClient并上传到OSS
FileClient client = fileConfigService.getMasterFileClient();
if (client == null) {
throw new Exception("获取FileClient失败");
}
// 5. 生成上传路径(包含日期前缀和时间戳后缀)
String filePath = generateUploadPath(fileName, baseDirectory);
// 6. 上传到OSS
String presignedUrl = client.upload(videoBytes, filePath, "video/mp4");
// 7. 移除预签名参数获取基础URL
String cleanUrl = HttpUtils.removeUrlQuery(presignedUrl);
// 8. 保存到 infra_file 表
FileDO infraFile = new FileDO()
.setConfigId(client.getId())
.setName(fileName)
.setPath(filePath)
.setUrl(cleanUrl)
.setType("video/mp4")
.setSize(videoBytes.length);
fileMapper.insert(infraFile);
Long infraFileId = infraFile.getId();
log.info("[saveVideoToOss][任务({})视频保存完成][infraFileId={}, size={}MB]",
task.getId(), infraFileId, sizeMB);
return new OssSaveResult(cleanUrl, videoBytes.length, filePath, infraFileId);
} catch (Exception e) {
log.error("[saveVideoToOss][任务({})保存视频失败][remoteUrl={}]", task.getId(), remoteVideoUrl, e);
return new OssSaveResult(remoteVideoUrl, 0, null, null);
}
}
/**
* 生成上传路径(与 FileService 保持一致)
*/
private String generateUploadPath(String name, String directory) {
String prefix = cn.hutool.core.date.LocalDateTimeUtil.format(
cn.hutool.core.date.LocalDateTimeUtil.now(),
cn.hutool.core.date.DatePattern.PURE_DATE_PATTERN);
String suffix = String.valueOf(System.currentTimeMillis());
String ext = cn.hutool.core.io.FileUtil.extName(name);
if (StrUtil.isNotEmpty(ext)) {
name = cn.hutool.core.io.FileUtil.mainName(name) + "_" + suffix + "." + ext;
} else {
name = name + "_" + suffix;
}
if (StrUtil.isNotEmpty(prefix)) {
name = prefix + "/" + name;
}
if (StrUtil.isNotEmpty(directory)) {
name = directory + "/" + name;
}
return name;
// 直接返回Kling URL不上传到OSS
return new OssSaveResult(remoteVideoUrl, 0, null, null);
}
/**
@@ -480,57 +408,39 @@ public class LatentsyncPollingService {
}
}
/**
* 下载远程文件 - 内存优化
*/
private byte[] downloadRemoteFile(String remoteUrl) throws Exception {
log.info("[downloadRemoteFile][下载文件][url={}]", remoteUrl);
try (HttpResponse response = HttpRequest.get(remoteUrl)
.execute()) {
if (!response.isOk()) {
throw new Exception("下载文件失败: HTTP " + response.getStatus());
}
// 流式读取分块处理避免大文件OOM
byte[] bytes = response.bodyBytes();
int sizeMB = bytes.length / 1024 / 1024;
log.info("[downloadRemoteFile][文件下载完成][size={} bytes, {}MB]", bytes.length, sizeMB);
return bytes;
}
}
/**
* 保存结果视频到用户文件表
* 如果 OSS 保存失败infraFileId 为 null直接保存外部 URL
*/
private void saveResultVideoToUserFiles(TikDigitalHumanTaskDO task, OssSaveResult saveResult) {
try {
Long userId = task.getUserId();
Long infraFileId = saveResult.getInfraFileId();
// 验证必要参数
if (userId == null || infraFileId == null) {
log.warn("[saveResultVideoToUserFiles][任务({})参数不完整,无法保存][userId={}, infraFileId={}]",
task.getId(), userId, infraFileId);
if (userId == null) {
log.warn("[saveResultVideoToUserFiles][任务({})userId为空无法保存]", task.getId());
return;
}
// 创建用户文件记录
// 创建用户文件记录(支持外部 URLfileId 可为空)
TikUserFileDO userFile = new TikUserFileDO();
userFile.setUserId(userId);
userFile.setFileId(infraFileId);
userFile.setFileName(String.format("数字人视频_%d_%d.mp4", task.getId(), System.currentTimeMillis()));
userFile.setFileId(saveResult.getInfraFileId()); // OSS保存失败时为null表示外部URL
userFile.setFileName(String.format("数字人视频_%d.mp4", task.getId()));
userFile.setFileType("video/mp4");
userFile.setFileCategory("generate");
userFile.setFileUrl(saveResult.getUrl());
userFile.setFilePath(saveResult.getFilePath());
userFile.setFileSize((long) saveResult.getFileSize());
userFile.setFileSize(saveResult.getInfraFileId() != null ? (long) saveResult.getFileSize() : null);
userFileMapper.insert(userFile);
log.info("[saveResultVideoToUserFiles][任务({})文件记录已保存][userFileId={}, infraFileId={}]",
task.getId(), userFile.getId(), infraFileId);
if (saveResult.getInfraFileId() != null) {
log.info("[saveResultVideoToUserFiles][任务({})已保存到OSS][userFileId={}, infraFileId={}]",
task.getId(), userFile.getId(), saveResult.getInfraFileId());
} else {
log.info("[saveResultVideoToUserFiles][任务({})已保存外部URL][userFileId={}, url={}]",
task.getId(), userFile.getId(), saveResult.getUrl());
}
} catch (Exception e) {
log.error("[saveResultVideoToUserFiles][任务({})保存失败]", task.getId(), e);
}