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

核心改动:
- 渲染完成后从已渲染视频抽帧作为封面,天然带标题(ASS字幕已烧录)
- 删除3条旧封面路径:缩略图、候选帧、FFmpeg备用抽帧
- 封面URL持久化到GenerationTask.cover_url
- 封面API直接从持久化URL读取
This commit is contained in:
2026-08-14 17:04:29 +08:00
parent 90ed473640
commit 421cff544b
+33 -21
View File
@@ -185,27 +185,39 @@ def generate_cover(
detail=f"获取预览视频URL失败: {e}",
) from e
# 优先使用渲染时预抽的封面候选帧(跳过 MediaKit,秒级返回)
cover_candidates = (plan.config or {}).get("cover_candidates", [])
if cover_candidates and body.cover_type in ("ai_frame", "ai_regenerate"):
logger.info(
"[封面生成] 使用预存封面候选帧: plan_id=%s count=%d",
plan_id,
len(cover_candidates),
)
first_frame = cover_candidates[0]
cover_data = {
"type": "ai_frame",
"image_url": first_frame.get("image_url", ""),
"frame_time": first_frame.get("frame_time", 0.0),
"confidence": 0.9,
}
if cover_data["image_url"]:
current_config = dict(plan.config) if plan.config else {}
current_config["cover"] = cover_data
normalized = normalize_plan_config(current_config)
plan_svc.update_plan_config(plan_id, {"cover": normalized["cover"]})
return GenerateCoverResponse(plan_id=plan_id, cover=cover_data)
# 统一封面管道:优先从 GenerationTask.cover_url 读取渲染后视频抽帧的封面
if body.cover_type in ("ai_frame", "ai_regenerate"):
# 尝试从 GenerationTask 读取已持久化的封面 URL
generation_task_id = (plan.config or {}).get("generation_task_id", "")
if generation_task_id:
try:
gen_task_repo = SQLAlchemyGenerationTaskRepository(db)
task = gen_task_repo.get(generation_task_id)
if task and getattr(task, "cover_url", ""):
cover_data = {
"type": "ai_frame",
"image_url": task.cover_url,
"frame_time": 0.0,
"confidence": 0.95,
}
logger.info(
"[封面生成] 使用统一管道封面: plan_id=%s task_id=%s url=%s",
plan_id,
generation_task_id,
task.cover_url[:80],
)
current_config = dict(plan.config) if plan.config else {}
current_config["cover"] = cover_data
normalized = normalize_plan_config(current_config)
plan_svc.update_plan_config(plan_id, {"cover": normalized["cover"]})
return GenerateCoverResponse(plan_id=plan_id, cover=cover_data)
except Exception:
logger.warning(
"[封面生成] 读取 GenerationTask.cover_url 失败: plan_id=%s task_id=%s",
plan_id,
generation_task_id,
exc_info=True,
)
from packages.shared.ai_service import run_generate_cover