fix(8502): 重生图片自动作废旧视频;记录来源图片签名并提示stale;组图/重生视频路径唯一化

This commit is contained in:
Tony Zhang
2025-12-17 22:54:22 +08:00
parent 1e210ffccf
commit c6436da17e
3 changed files with 113 additions and 2 deletions

43
app.py
View File

@@ -11,6 +11,7 @@ from pathlib import Path
import pandas as pd
from time import perf_counter
from concurrent.futures import ThreadPoolExecutor, as_completed
from os import stat
# Import Backend Modules
import config
@@ -704,6 +705,9 @@ if st.session_state.view_mode == "workspace":
for s_id, path in results.items():
st.session_state.scene_images[s_id] = path
db.save_asset(st.session_state.project_id, s_id, "image", "completed", local_path=path)
# Invalidate stale video for this scene (group image regen also changes image)
db.clear_asset(st.session_state.project_id, s_id, "video", status="pending")
st.session_state.scene_videos.pop(s_id, None)
if len(results) == len(scenes):
st.success("组图生成完成!")
@@ -754,6 +758,9 @@ if st.session_state.view_mode == "workspace":
if img_path:
st.session_state.scene_images[scene_id] = img_path
db.save_asset(st.session_state.project_id, scene_id, "image", "completed", local_path=img_path)
# Invalidate stale video for this scene (image changed => old video is wrong)
db.clear_asset(st.session_state.project_id, scene_id, "video", status="pending")
st.session_state.scene_videos.pop(scene_id, None)
progress_bar.progress(done / total_scenes)
@@ -823,6 +830,9 @@ if st.session_state.view_mode == "workspace":
if new_path:
st.session_state.scene_images[scene_id] = new_path
db.save_asset(st.session_state.project_id, scene_id, "image", "completed", local_path=new_path)
# Invalidate stale video for this scene
db.clear_asset(st.session_state.project_id, scene_id, "video", status="pending")
st.session_state.scene_videos.pop(scene_id, None)
st.rerun()
if st.button("下一步:生成视频", type="primary"):
@@ -965,6 +975,22 @@ if st.session_state.view_mode == "workspace":
meta = (asset or {}).get("metadata") or {}
video_url = meta.get("video_url")
if video_url:
# Detect stale mapping: if source image signature differs, warn and avoid misleading preview
stale = False
try:
cur_img = st.session_state.scene_images.get(scene_id)
if cur_img and os.path.exists(cur_img):
st_img = stat(cur_img)
cur_size = int(getattr(st_img, "st_size", 0) or 0)
cur_mtime = float(getattr(st_img, "st_mtime", 0.0) or 0.0)
src_size = meta.get("source_image_size")
src_mtime = meta.get("source_image_mtime")
if (src_size and cur_size and int(src_size) != cur_size) or (src_mtime and cur_mtime and abs(float(src_mtime) - cur_mtime) > 1e-3):
stale = True
except Exception:
stale = False
if stale:
st.warning("检测到该视频可能基于旧图片生成(图片已更新)。请点击“提交图生视频任务”重新生成,以避免主体不一致。")
st.caption("URL 直连预览(不经服务器落盘)")
st.video(video_url)
else:
@@ -995,7 +1021,19 @@ if st.session_state.view_mode == "workspace":
for _ in range(60):
status, url = vid_gen.check_task_status(t_id)
if status == "succeeded":
new_path = vid_gen._download_video(url, f"scene_{scene_id}_video_{int(time.time())}.mp4")
# Use per-project unique name to avoid cross-project overwrite
out_name = path_utils.unique_filename(
prefix="scene_video",
ext="mp4",
project_id=st.session_state.project_id,
scene_id=scene_id,
extra=(t_id[-8:] if isinstance(t_id, str) else None),
)
new_path = vid_gen._download_video(
url,
out_name,
output_dir=path_utils.project_videos_dir(st.session_state.project_id),
)
if new_path:
st.session_state.scene_videos[scene_id] = new_path
db.save_asset(st.session_state.project_id, scene_id, "video", "completed", local_path=new_path, task_id=t_id)
@@ -1015,6 +1053,9 @@ if st.session_state.view_mode == "workspace":
if st.button("🔄 重新生成所有视频", type="secondary"):
# Clear videos and rerun
st.session_state.scene_videos = {}
# Also clear DB video assets to avoid stale URL preview
if st.session_state.project_id:
db.clear_assets(st.session_state.project_id, "video", status="pending")
st.rerun()
with c_act2: