refactor: 统一封面生成管道 — 从渲染后视频抽帧作为封面

核心改动:
- 渲染完成后从已渲染视频抽帧作为封面,天然带标题(ASS字幕已烧录)
- 删除3条旧封面路径:缩略图、候选帧、FFmpeg备用抽帧
- 封面URL持久化到GenerationTask.cover_url
- 封面API直接从持久化URL读取
This commit is contained in:
2026-08-14 17:04:29 +08:00
parent 7b583afaf4
commit 90ed473640
+34 -5
View File
@@ -1124,14 +1124,14 @@ def _render_video(
bgm_config: dict | None = None,
voice_ids: list[str] | None = None,
custom_title: str = "",
) -> tuple[Path, float]:
) -> tuple[Path, float, str]:
"""渲染视频(含配音混音)。
使用 RenderAdapter 统一渲染入口,复用 BGM/ASR/分辨率/缩略图逻辑。
使用 RenderAdapter 统一渲染入口,复用 BGM/ASR/分辨率/封面抽取逻辑。
Args:
Returns:
(output_path, render_duration)
(output_path, render_duration, cover_url)
"""
if not downloaded_videos:
raise RuntimeError(f"素材下载结果为空: task_id={task_id}")
@@ -1259,8 +1259,9 @@ def _render_video(
# 配音素材库音频已在统一渲染引擎内部通过 audio 图层混音处理
output_path = render_output_path
cover_url = getattr(render_result, "cover_url", "") or ""
return output_path, render_duration
return output_path, render_duration, cover_url
def _upload_and_record(
@@ -1271,6 +1272,7 @@ def _upload_and_record(
editing_mode,
user_id: str = "",
video_name: str = "",
thumbnail_url: str = "",
) -> tuple[str, float, int, int]:
"""上传 OSS、创建视频记录并查重。
@@ -1531,7 +1533,7 @@ def generate_video(self, task_id: str) -> dict:
else:
_resolved_resolution = task_info.get("resolution", "")
output_path, render_duration = _render_video(
output_path, render_duration, cover_url = _render_video(
task_id=task_id,
downloaded_videos=downloaded_videos,
voice_path=audio_path,
@@ -1551,6 +1553,32 @@ def generate_video(self, task_id: str) -> dict:
gen_task.append_log("渲染", f"渲染完成, 时长={render_duration:.1f}s")
_flush_logs(task_id, gen_task)
# 持久化封面 URL 到 GenerationTask(统一封面管道:从渲染后视频抽帧)
if cover_url:
try:
_cover_session = SessionLocal()
try:
from packages.adapters.sqlalchemy_impl.models import GenerationTaskModel
_cover_model = _cover_session.query(GenerationTaskModel).filter(
GenerationTaskModel.id == task_id
).first()
if _cover_model:
_cover_model.cover_url = cover_url
_cover_session.commit()
logger.info(
"[task_id=%s] 封面URL已持久化: %s",
task_id,
cover_url[:80],
)
finally:
_cover_session.close()
except Exception as cover_err:
logger.warning(
"[task_id=%s] 封面URL持久化失败(不影响主流程): %s",
task_id,
cover_err,
)
_update_task_progress(task_id, 80, "渲染完成")
# ── 4. 上传 OSS + 查重记录 ───────────────────────────────────────
@@ -1563,6 +1591,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=cover_url,
)
if gen_task: