Compare commits

...

1 Commits

Author SHA1 Message Date
xiaoxia 98b9e15879 fix: ensure cover title matches current video title
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2m52s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 4m2s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 4m3s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 4m5s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 1m19s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 4m17s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 2m12s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 5m52s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 4m59s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 8m46s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
AI Code Review / AI Code Review (pull_request) Successful in 9m23s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 3m20s
CI/CD Pipeline / CI Gate (pull_request) Successful in 29s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 3m19s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 3m31s
- Add task_id parameter to extract_and_upload_cover_frames
- Change storage key from covers/{plan_id}/frame_{i}.jpg to covers/{plan_id}/{task_id}/frame_{i}.jpg
- Clear cover field in plan.config when title changes in _writeback_edit_plan_config
- Pass job_id as task_id in render_adapter.py

This fixes the issue where modifying the title and generating a new video
would still show the old title on the cover.
2026-08-27 14:30:30 +08:00
3 changed files with 19 additions and 3 deletions
@@ -169,8 +169,22 @@ def _writeback_edit_plan_config(
current_config = plan_model.config if isinstance(plan_model.config, dict) else {}
merged = dict(current_config)
merged["generation_task_id"] = task_id
# 检查标题是否发生变化,如果变化则清除 cover 字段强制重新生成封面
if title_config:
old_title_config = merged.get("title_config", {}) or {}
old_title_text = (old_title_config.get("text") or "").strip()
new_title_text = (title_config.get("text") or "").strip()
if old_title_text != new_title_text:
# 标题变化,清除旧封面
if "cover" in merged:
del merged["cover"]
logger.info(
"[生成任务] 标题变化,清除旧封面: plan_id=%s old_title=%s new_title=%s",
plan_id, old_title_text, new_title_text,
)
merged["title_config"] = title_config
plan_model.config = merged
db.commit()
logger.info(
@@ -598,7 +598,7 @@ class RenderAdapter:
# 抽帧天然带标题,因此这里传空字符串,避免 Pillow 二次叠加导致重影。
# Pillow 叠加仅用于 API 从源素材抽帧(源素材本身无标题)的兜底场景。
cover_candidates = extract_and_upload_cover_frames(
str(result.output_path), plan_id, num_frames=3, title_text=""
str(result.output_path), plan_id, task_id=job_id, num_frames=3, title_text=""
)
if cover_candidates:
logger.info(
@@ -278,6 +278,7 @@ def extract_and_upload_cover_frames(
video_path: str,
plan_id: str,
*,
task_id: str = "",
num_frames: int = 3,
title_text: str = "",
title_color: str = "#ffffff",
@@ -291,6 +292,7 @@ def extract_and_upload_cover_frames(
Args:
video_path: 视频文件路径
plan_id: 编辑计划 ID(用于生成 storage key
task_id: 任务 ID(用于生成独立的 storage key,避免标题变更时封面冲突)
num_frames: 抽取帧数(默认 3
title_text: 标题文字;非空时用 Pillow 叠加到每帧。
从已渲染视频抽帧时通常传空(标题已烧录);从源素材抽帧时传标题。
@@ -338,7 +340,7 @@ def extract_and_upload_cover_frames(
font_size=title_font_size,
)
storage_key = f"covers/{plan_id}/mediakit_frame_{i}.jpg"
storage_key = f"covers/{plan_id}/{task_id}/mediakit_frame_{i}.jpg"
url = upload_to_oss(tmp.name, storage_key)
if url:
seek_time = frame.get("timestamp", 0.0)
@@ -377,7 +379,7 @@ def extract_and_upload_cover_frames(
position=title_position,
font_size=title_font_size,
)
storage_key = f"covers/{plan_id}/frame_{i}.jpg"
storage_key = f"covers/{plan_id}/{task_id}/frame_{i}.jpg"
url = upload_to_oss(frame_path, storage_key)
if url:
seek_time = max(0.5, duration * ratio) if duration > 0 else 0.0