From 2bded11a03475c40500439433dfeb6e0fb8030cd Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Wed, 14 Jan 2026 09:30:09 +0800 Subject: [PATCH] =?UTF-8?q?feat(task):=20=E6=B7=BB=E5=8A=A0=E8=BD=AC?= =?UTF-8?q?=E5=9C=BA=E6=95=88=E6=9E=9C=E7=9B=B8=E5=85=B3=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E5=92=8C=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 get_transition_type、get_transition_ms、has_transition 方法用于处理转场类型和时长 - 新增 get_overlap_tail_ms、get_transition_in_type、get_transition_in_ms 等方法处理入场转场 - 新增 get_transition_out_type、get_transition_out_ms、has_transition_out 等方法处理出场转场 - 新增 get_overlap_head_ms、get_overlap_tail_ms_v2 方法计算头部和尾部重叠时长 - 更新渲染视频处理器中使用新的转场相关方法计算 overlap 时长 --- domain/task.py | 63 ++++++++++++++++++++++++++++++++++++++++ handlers/render_video.py | 8 +++-- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/domain/task.py b/domain/task.py index 2fed94f..b23134c 100644 --- a/domain/task.py +++ b/domain/task.py @@ -361,6 +361,69 @@ class Task: """获取输出规格""" return OutputSpec.from_dict(self.payload.get('output')) + def get_transition_type(self) -> Optional[str]: + """获取转场类型(来自 TaskPayload 顶层)""" + return self.payload.get('transitionType') + + def get_transition_ms(self) -> int: + """获取转场时长(毫秒,来自 TaskPayload 顶层)""" + return int(self.payload.get('transitionMs', 0)) + + def has_transition(self) -> bool: + """是否有转场效果""" + return self.get_transition_ms() > 0 + + def get_overlap_tail_ms(self) -> int: + """ + 获取尾部 overlap 时长(毫秒) + + 转场发生在当前片段与下一片段之间,当前片段需要在尾部多渲染 overlap 帧。 + overlap = transitionMs / 2 + """ + return self.get_transition_ms() // 2 + + def get_transition_in_type(self) -> Optional[str]: + """获取入场转场类型(来自前一片段的出场转场)""" + return self.payload.get('transitionInType') + + def get_transition_in_ms(self) -> int: + """获取入场转场时长(毫秒)""" + return int(self.payload.get('transitionInMs', 0)) + + def get_transition_out_type(self) -> Optional[str]: + """获取出场转场类型(当前片段的转场配置)""" + return self.payload.get('transitionOutType') + + def get_transition_out_ms(self) -> int: + """获取出场转场时长(毫秒)""" + return int(self.payload.get('transitionOutMs', 0)) + + def has_transition_in(self) -> bool: + """是否有入场转场""" + return self.get_transition_in_ms() > 0 + + def has_transition_out(self) -> bool: + """是否有出场转场""" + return self.get_transition_out_ms() > 0 + + def get_overlap_head_ms(self) -> int: + """ + 获取头部 overlap 时长(毫秒) + + 入场转场来自前一个片段,当前片段需要在头部多渲染 overlap 帧。 + overlap = transitionInMs / 2 + """ + return self.get_transition_in_ms() // 2 + + def get_overlap_tail_ms_v2(self) -> int: + """ + 获取尾部 overlap 时长(毫秒)- 使用新的字段名 + + 出场转场用于当前片段与下一片段之间,当前片段需要在尾部多渲染 overlap 帧。 + overlap = transitionOutMs / 2 + """ + return self.get_transition_out_ms() // 2 + def get_bgm_url(self) -> Optional[str]: """获取 BGM URL""" return self.payload.get('bgmUrl') diff --git a/handlers/render_video.py b/handlers/render_video.py index b9158a0..acc4e98 100644 --- a/handlers/render_video.py +++ b/handlers/render_video.py @@ -78,9 +78,11 @@ class RenderSegmentVideoHandler(BaseHandler): logger.warning(f"[task:{task.task_id}] Failed to download overlay, continuing without it") overlay_file = None - # 4. 计算 overlap 时长 - overlap_head_ms = render_spec.get_overlap_head_ms() - overlap_tail_ms = render_spec.get_overlap_tail_ms() + # 4. 计算 overlap 时长(用于转场帧冻结) + # 头部 overlap: 来自前一片段的出场转场 + overlap_head_ms = task.get_overlap_head_ms() + # 尾部 overlap: 当前片段的出场转场 + overlap_tail_ms = task.get_overlap_tail_ms_v2() # 5. 构建 FFmpeg 命令 output_file = os.path.join(work_dir, 'output.mp4')