From af0b0c5070aaa84ebb54278b84d5bf2ebb8dacf6 Mon Sep 17 00:00:00 2001 From: sion123 <450702724@qq.com> Date: Wed, 4 Mar 2026 04:01:48 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tik/media/BatchProduceAlignment.java | 23 ++++++++++++------- .../tik/mix/service/MixTaskServiceImpl.java | 22 +++++++++++++----- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/yudao-module-tik/src/main/java/cn/iocoder/yudao/module/tik/media/BatchProduceAlignment.java b/yudao-module-tik/src/main/java/cn/iocoder/yudao/module/tik/media/BatchProduceAlignment.java index 14abc1f9e3..4cf95ae3b3 100644 --- a/yudao-module-tik/src/main/java/cn/iocoder/yudao/module/tik/media/BatchProduceAlignment.java +++ b/yudao-module-tik/src/main/java/cn/iocoder/yudao/module/tik/media/BatchProduceAlignment.java @@ -283,8 +283,9 @@ public class BatchProduceAlignment { Integer fileDuration = material.getFileDuration(); int startOffset = 0; int endOffset = duration; + int actualDuration = duration; // 实际截取时长 - if (fileDuration != null && fileDuration > duration) { + if (fileDuration != null && fileDuration >= duration) { // 有实际时长且足够:随机起点范围 0 到 (实际时长 - 截取时长) long randomSeed = ((material.getFileId() != null ? material.getFileId() : i) * 1000000L) + (videoIndex * 10000L) + (material.getFileUrl().hashCode() % 1000); @@ -294,14 +295,20 @@ public class BatchProduceAlignment { endOffset = startOffset + duration; log.debug("[ICE][随机截取] fileId={}, fileDuration={}s, In={}, Out={}", material.getFileId(), fileDuration, startOffset, endOffset); + } else if (fileDuration != null && fileDuration < duration) { + // 素材时长不足:使用素材全部时长,避免超出范围 + actualDuration = fileDuration; + endOffset = fileDuration; + log.warn("[ICE][素材时长不足] fileId={}, 请求{}s, 实际{}s, 将使用全部时长", + material.getFileId(), duration, fileDuration); } else { - // 无时长或时长不足:从0开始截取(兜底) - log.debug("[ICE][兜底截取] fileId={}, fileDuration={}, In=0, Out={}", - material.getFileId(), fileDuration, duration); + // 无时长信息:从0开始截取(兜底,ICE可能会失败) + log.warn("[ICE][无时长信息] fileId={}, In=0, Out={}, ICE可能会失败", + material.getFileId(), duration); } log.debug("[ICE][添加视频片段][视频{}: {}, In={}, Out={}, TimelineIn={}, TimelineOut={}]", - videoIndex + 1, videoUrl, startOffset, endOffset, timelinePos, timelinePos + duration); + videoIndex + 1, videoUrl, startOffset, endOffset, timelinePos, timelinePos + actualDuration); // 构建视频片段(带 In/Out 参数) JSONObject videoClip = new JSONObject(); @@ -309,7 +316,7 @@ public class BatchProduceAlignment { videoClip.put("In", startOffset); videoClip.put("Out", endOffset); videoClip.put("TimelineIn", timelinePos); - videoClip.put("TimelineOut", timelinePos + duration); + videoClip.put("TimelineOut", timelinePos + actualDuration); // 添加裁剪效果(9:16竖屏输出) // 假设源素材为1920x1080(16:9),可根据实际情况调整 @@ -341,7 +348,7 @@ public class BatchProduceAlignment { audioClip.put("In", startOffset); audioClip.put("Out", endOffset); audioClip.put("TimelineIn", timelinePos); - audioClip.put("TimelineOut", timelinePos + duration); + audioClip.put("TimelineOut", timelinePos + actualDuration); audioClip.put("Effects", new JSONArray() {{ add(new JSONObject() {{ put("Type", "Volume"); @@ -350,7 +357,7 @@ public class BatchProduceAlignment { }}); audioClipArray.add(audioClip); - timelinePos += duration; + timelinePos += actualDuration; } // 构建时间线 diff --git a/yudao-module-tik/src/main/java/cn/iocoder/yudao/module/tik/mix/service/MixTaskServiceImpl.java b/yudao-module-tik/src/main/java/cn/iocoder/yudao/module/tik/mix/service/MixTaskServiceImpl.java index a63a095ff1..094a86d272 100644 --- a/yudao-module-tik/src/main/java/cn/iocoder/yudao/module/tik/mix/service/MixTaskServiceImpl.java +++ b/yudao-module-tik/src/main/java/cn/iocoder/yudao/module/tik/mix/service/MixTaskServiceImpl.java @@ -318,20 +318,30 @@ public class MixTaskServiceImpl implements MixTaskService { for (String jobId : jobIds) { try { String status = iceClient.getMediaProducingJobStatus(jobId); + log.debug("[MixTask][jobId状态] taskId={}, jobId={}, status={}", taskId, jobId, status); if ("Success".equalsIgnoreCase(status)) { successJobIds.add(jobId); } else if ("Failed".equalsIgnoreCase(status) || "Failure".equalsIgnoreCase(status)) { failedJobIds.add(jobId); - } else if ("Running".equalsIgnoreCase(status) || "Processing".equalsIgnoreCase(status)) { + } else if ("Running".equalsIgnoreCase(status) || "Processing".equalsIgnoreCase(status) + || "Producing".equalsIgnoreCase(status) || "Analyzing".equalsIgnoreCase(status)) { + // 阿里云ICE状态:Running, Processing, Producing, Analyzing 都算运行中 runningJobIds.add(jobId); - } else if ("Pending".equalsIgnoreCase(status)) { + } else if ("Pending".equalsIgnoreCase(status) || "Init".equalsIgnoreCase(status)) { + // Init 是初始化状态,也属于待处理 pendingJobIds.add(jobId); + } else if ("Canceled".equalsIgnoreCase(status)) { + // 取消的任务算失败 + failedJobIds.add(jobId); } else { + // 未知状态,继续等待,不直接算失败 + log.warn("[MixTask][未知状态] taskId={}, jobId={}, status={}", taskId, jobId, status); unknownJobIds.add(jobId); } } catch (Exception e) { - log.error("[MixTask][查询jobId状态失败] taskId={}, jobId={}", taskId, jobId, e); - failedJobIds.add(jobId); + log.error("[MixTask][查询jobId状态异常] taskId={}, jobId={}", taskId, jobId, e); + // 查询异常不应该直接当作失败,可能是临时网络问题,放入unknown等待下次检查 + unknownJobIds.add(jobId); } } @@ -340,8 +350,8 @@ public class MixTaskServiceImpl implements MixTaskService { taskId, total, successJobIds.size(), failedJobIds.size(), runningJobIds.size(), pendingJobIds.size(), unknownJobIds.size()); // 综合判断任务状态 - if (!runningJobIds.isEmpty() || !pendingJobIds.isEmpty()) { - // 任一运行中或待处理 → 更新进度,继续等待 + if (!runningJobIds.isEmpty() || !pendingJobIds.isEmpty() || !unknownJobIds.isEmpty()) { + // 任一运行中、待处理或未知状态 → 更新进度,继续等待 int currentProgress = task.getProgress() != null ? task.getProgress() : 0; int newProgress; if (currentProgress < 50) {