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..a89b9e3e9 100644 --- a/apps/worker/worker_app/tasks/edit_plan_generation.py +++ b/apps/worker/worker_app/tasks/edit_plan_generation.py @@ -116,6 +116,15 @@ 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 +138,22 @@ 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], ) )