fix(8502): 重生图片自动作废旧视频;记录来源图片签名并提示stale;组图/重生视频路径唯一化
This commit is contained in:
43
app.py
43
app.py
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user