From 9784aed60568bb405e10b6b4dc664a466566b609 Mon Sep 17 00:00:00 2001 From: CI Bot Date: Mon, 13 Jul 2026 00:36:23 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix(worker):=20=E4=BF=AE=E5=A4=8D=20render?= =?UTF-8?q?=5Fedit=5Fplan=20=E7=B4=A0=E6=9D=90=E4=B8=8B=E8=BD=BD=20+=20?= =?UTF-8?q?=E6=80=BB=E6=97=B6=E9=95=BF=E6=97=A5=E5=BF=97=20+=20video=5Fpro?= =?UTF-8?q?cessing=20=E5=AF=BC=E5=85=A5=E9=93=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 3 个修复: 1. render_edit_plan 素材下载路径错误:直接传 asset_id 给 download_asset, 改为先查 assets 表拿 file_url(storage_key) 再下载 2. 总时长=0.0s 日志误导:_build_plan_and_clips_from_task 中 _VirtualClip 的 duration 未赋值导致日志永远显示 0s,改为用 probe_duration 预探测 3. video_processing/__init__.py 导入链副作用:顶层导入 render_adapter 等 重依赖模块,导致只想用 oss_helpers/ffmpeg_utils 等轻量工具的地方也 被迫拉进 packages/DB 全量依赖。改为只导出轻量工具模块,渲染组件 按需从子模块导入 --- apps/worker/video_processing/__init__.py | 19 +++++--------- .../worker_app/tasks/edit_plan_generation.py | 25 +++++++++++++++++-- apps/worker/worker_app/tasks/generation.py | 8 +++++- 3 files changed, 36 insertions(+), 16 deletions(-) mode change 100755 => 100644 apps/worker/video_processing/__init__.py diff --git a/apps/worker/video_processing/__init__.py b/apps/worker/video_processing/__init__.py old mode 100755 new mode 100644 index 7a9bf8a2a..e84d30c6c --- a/apps/worker/video_processing/__init__.py +++ b/apps/worker/video_processing/__init__.py @@ -1,24 +1,17 @@ """ 视频处理模块 + +轻量工具(ffmpeg_utils / oss_helpers / dedup_helpers)顶层直接导出, +无额外依赖。渲染相关组件(UnifiedRenderService / RenderAdapter / +VideoProcessor 等)按需从子模块导入,避免 __init__ 阶段引入 +packages / DB 等重依赖。 """ -# 共享工具模块(供 editing_modes / generation / edit_plan_generation 等复用) +# 共享工具模块(零外部依赖,供 editing_modes / generation / edit_plan_generation 等复用) from . import dedup_helpers, ffmpeg_utils, oss_helpers -from .processor import VideoProcessor, VideoResult -from .render_adapter import RenderAdapter, RenderAdapterResult -from .render_engine_resolver import RenderEngineResolver, get_render_engine_resolver -from .unified_render_service import RenderResult, UnifiedRenderService __all__ = [ - "VideoProcessor", - "VideoResult", "ffmpeg_utils", "oss_helpers", "dedup_helpers", - "UnifiedRenderService", - "RenderResult", - "RenderAdapter", - "RenderAdapterResult", - "RenderEngineResolver", - "get_render_engine_resolver", ] diff --git a/apps/worker/worker_app/tasks/edit_plan_generation.py b/apps/worker/worker_app/tasks/edit_plan_generation.py index 320be17e7..9e2d21539 100644 --- a/apps/worker/worker_app/tasks/edit_plan_generation.py +++ b/apps/worker/worker_app/tasks/edit_plan_generation.py @@ -116,6 +116,16 @@ def render_edit_plan(self, plan_id: str) -> dict: rendered_clip_ids: list[str] = [] failed_clip_ids: list[str] = [] + # 预先批量查询所有素材的 storage_key(file_url) + from packages.adapters.sqlalchemy_impl.models import AssetModel + clip_asset_ids = [c.asset_id for c in clips if c.asset_id] + asset_storage_map: dict[str, str] = {} + if clip_asset_ids: + assets = db.query(AssetModel).filter( + AssetModel.id.in_(clip_asset_ids) + ).all() + asset_storage_map = {a.id: a.file_url for a in assets if a.file_url} + for clip in clips: if not clip.asset_id: # 没有素材的片段跳过,标记为失败 @@ -129,10 +139,21 @@ def render_edit_plan(self, plan_id: str) -> dict: rendered_clip_ids.append(clip.id) continue + storage_key = asset_storage_map.get(clip.asset_id) + if not storage_key: + logger.warning( + "片段素材无 storage_key,跳过: clip_id=%s asset_id=%s", + clip.id, clip.asset_id, + ) + clip.mark_failed() + clip_repo.update(clip) + failed_clip_ids.append(clip.id) + continue + # 下载素材 - ext = Path(clip.asset_id).suffix or ".mp4" + ext = Path(storage_key).suffix or ".mp4" local_path = tmpdir_path / f"clip_{clip.order:04d}{ext}" - if download_asset(clip.asset_id, local_path): + if download_asset(storage_key, local_path): asset_path_map[clip.asset_id] = local_path rendered_clip_ids.append(clip.id) else: diff --git a/apps/worker/worker_app/tasks/generation.py b/apps/worker/worker_app/tasks/generation.py index 7c0824d24..df6fdea30 100755 --- a/apps/worker/worker_app/tasks/generation.py +++ b/apps/worker/worker_app/tasks/generation.py @@ -162,13 +162,15 @@ def _build_plan_and_clips_from_task( """ plan = _VirtualPlan(id=task_id, name=f"Generated-{task_id[:8]}") - # 为每个下载路径生成合成 asset_id + # 为每个下载路径生成合成 asset_id,并预探测素材时长 asset_path_map: dict[str, Path] = {} path_to_asset_id: dict[Path, str] = {} + path_duration: dict[Path, float] = {} for i, p in enumerate(downloaded_paths): asset_id = f"gen_{task_id[:8]}_{i:03d}{p.suffix or '.mp4'}" asset_path_map[asset_id] = p path_to_asset_id[p] = asset_id + path_duration[p] = probe_duration(p) clips: list[_VirtualClip] = [] n = len(downloaded_paths) @@ -184,6 +186,7 @@ def _build_plan_and_clips_from_task( clip_type=clip_type, order=i, asset_id=path_to_asset_id[p], + duration=path_duration[p], ) ) elif mode == "voice_over": @@ -196,6 +199,7 @@ def _build_plan_and_clips_from_task( clip_type="main", order=i, asset_id=path_to_asset_id[p], + duration=path_duration[p], config={"role": "b_roll"}, ) ) @@ -215,6 +219,7 @@ def _build_plan_and_clips_from_task( clip_type=clip_type, order=i, asset_id=path_to_asset_id[p], + duration=path_duration[p], ) ) else: @@ -227,6 +232,7 @@ def _build_plan_and_clips_from_task( clip_type="main", order=i, asset_id=path_to_asset_id[p], + duration=path_duration[p], ) ) -- 2.54.0 From 63b0bde41a07d1b155fcbe1646a96365dc32e861 Mon Sep 17 00:00:00 2001 From: CI Bot Date: Mon, 13 Jul 2026 01:17:47 +0800 Subject: [PATCH 2/2] style: black format edit_plan_generation.py --- apps/worker/worker_app/tasks/edit_plan_generation.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/worker/worker_app/tasks/edit_plan_generation.py b/apps/worker/worker_app/tasks/edit_plan_generation.py index 9e2d21539..a89b9e3e9 100644 --- a/apps/worker/worker_app/tasks/edit_plan_generation.py +++ b/apps/worker/worker_app/tasks/edit_plan_generation.py @@ -118,12 +118,11 @@ def render_edit_plan(self, plan_id: str) -> dict: # 预先批量查询所有素材的 storage_key(file_url) from packages.adapters.sqlalchemy_impl.models import AssetModel + clip_asset_ids = [c.asset_id for c in clips if c.asset_id] asset_storage_map: dict[str, str] = {} if clip_asset_ids: - assets = db.query(AssetModel).filter( - AssetModel.id.in_(clip_asset_ids) - ).all() + assets = db.query(AssetModel).filter(AssetModel.id.in_(clip_asset_ids)).all() asset_storage_map = {a.id: a.file_url for a in assets if a.file_url} for clip in clips: @@ -143,7 +142,8 @@ def render_edit_plan(self, plan_id: str) -> dict: if not storage_key: logger.warning( "片段素材无 storage_key,跳过: clip_id=%s asset_id=%s", - clip.id, clip.asset_id, + clip.id, + clip.asset_id, ) clip.mark_failed() clip_repo.update(clip) -- 2.54.0