diff --git a/apps/worker/video_processing/render_adapter.py b/apps/worker/video_processing/render_adapter.py index 4f5cb5444..c52f3b2d0 100755 --- a/apps/worker/video_processing/render_adapter.py +++ b/apps/worker/video_processing/render_adapter.py @@ -575,12 +575,13 @@ class RenderAdapter: self._report_progress(progress_cb, 90.0, "生成封面缩略图") - # 6. 生成封面缩略图 + # 6. 生成封面缩略图(结果通过 RenderAdapterResult.thumbnail_url 返回给调用方) thumbnail_url = "" try: from video_processing.thumbnail_generator import generate_and_upload_thumbnail - thumb_storage_key = f"rendered/{plan_id}/thumbnail.jpg" + # job_id 是 _do_render 方法的参数(参见方法签名) + thumb_storage_key = f"rendered/{plan_id}/thumbnails/{job_id}.jpg" thumbnail_url = generate_and_upload_thumbnail(str(result.output_path), thumb_storage_key) except Exception as thumb_err: logger.warning( diff --git a/apps/worker/worker_app/tasks/generation.py b/apps/worker/worker_app/tasks/generation.py index 8dbbde32b..7915bd075 100644 --- a/apps/worker/worker_app/tasks/generation.py +++ b/apps/worker/worker_app/tasks/generation.py @@ -389,6 +389,7 @@ def _upload_and_record( editing_mode, user_id: str = "", video_name: str = "", + thumbnail_url: str = "", ) -> tuple[str, float, int, int]: """上传 OSS、创建视频记录并查重。 @@ -447,6 +448,7 @@ def _upload_and_record( mode=editing_mode.value, session=dedup_session, name=video_name, + thumbnail_url=thumbnail_url, ) finally: dedup_session.close() @@ -535,11 +537,11 @@ def _render_from_edit_plan( task_id: str, source_edit_plan_id: str, task_info: dict, -) -> tuple[Path, float, list[dict] | None, str | None, str | None]: +) -> tuple[Path, float, list[dict] | None, str | None, str | None, str]: """从 EditPlan 数据库记录直接渲染(不再内存重建clips)。 Returns: - (output_path, render_duration, cover_candidates, voiceover_path, temp_dir) + (output_path, render_duration, cover_candidates, voiceover_path, temp_dir, thumbnail_url) """ from video_processing.render_adapter import RenderAdapter from worker_app.db import SessionLocal @@ -580,7 +582,14 @@ def _render_from_edit_plan( cover_candidates = getattr(result, "cover_candidates", None) render_temp_dir = getattr(result, "temp_dir", None) - return output_path, result.duration, cover_candidates, voiceover_path, render_temp_dir + return ( + output_path, + result.duration, + cover_candidates, + voiceover_path, + render_temp_dir, + result.thumbnail_url or "", + ) finally: db.close() @@ -692,7 +701,7 @@ def generate_video(self, task_id: str) -> dict: gen_task.append_log("渲染模式", "从草稿数据渲染(与预览一致)") _flush_logs(task_id, gen_task) - output_path, render_duration, cover_candidates, voiceover_tmp_path, render_temp_dir = ( + output_path, render_duration, cover_candidates, voiceover_tmp_path, render_temp_dir, thumbnail_url = ( _render_from_edit_plan( task_id=task_id, source_edit_plan_id=source_edit_plan_id, @@ -717,6 +726,7 @@ def generate_video(self, task_id: str) -> dict: editing_mode=editing_mode, user_id=user_id, video_name=task_info.get("video_title", ""), + thumbnail_url=thumbnail_url, ) if gen_task: