Files
video/scene_generate.py
T
2026-04-25 14:10:09 +08:00

136 lines
4.0 KiB
Python

"""
scene_generate.py - 场景图生成模块(简化版)
读取 scene_plan.json,对每个 pending 场景用文生图直接生成
不再需要角色元素图、Panel 拼图、img2img
支持断点续传:已生成的自动跳过,失败的可重试
"""
import json
import os
from datetime import datetime
# ========== 路径配置 ==========
WORKSPACE = "workspace/1" # 运行时会被 gui.py 覆盖
PLAN_PATH = os.path.join(WORKSPACE, "scene_plan.json")
SCENE_IMG_DIR = os.path.join(WORKSPACE, "scene")
def load_plan() -> dict:
with open(PLAN_PATH, encoding="utf-8") as f:
return json.load(f)
def save_plan(plan: dict):
with open(PLAN_PATH, "w", encoding="utf-8") as f:
json.dump(plan, f, ensure_ascii=False, indent=2)
def generate_single_scene(
scene: dict,
idx: int,
total: int,
model_name: str,
on_image_generated=None,
) -> dict:
"""
生成单个场景的图片
Args:
scene: 场景信息 dict
idx: 当前索引
total: 总场景数
model_name: 文生图模型名称
on_image_generated: 回调函数 (scene, filepath),用于 GUI 审查
Returns:
更新后的 scene dict
"""
scene_id = scene["scene_id"]
visual_prompt = scene["visual_prompt"]
print(f"\n[场景 {scene_id}] [{idx+1}/{total}]")
print(f" Prompt: {visual_prompt[:80]}...")
os.makedirs(SCENE_IMG_DIR, exist_ok=True)
scene_filename = f"scene_{scene_id:03d}.png"
filepath = os.path.join(SCENE_IMG_DIR, scene_filename)
try:
from image_gen import image_generate
result = image_generate(
prompt=visual_prompt,
save_dir=SCENE_IMG_DIR,
model_name=model_name,
filename=scene_filename,
)
filepath = result["filepath"]
scene["status"] = "generated"
scene["filepath"] = filepath
print(f" [完成] {os.path.basename(filepath)}")
# 如果有回调(GUI 审查),调用它
if on_image_generated:
on_image_generated(scene, filepath)
return scene
except Exception as e:
scene["status"] = "failed"
scene["error"] = str(e)
print(f" [失败] {e}")
return scene
def main(workspace: str = None, model_name: str = "Kolors (SiliconFlow)"):
"""主流程:生成所有 pending 场景"""
global WORKSPACE, PLAN_PATH, SCENE_IMG_DIR
if workspace:
WORKSPACE = workspace
PLAN_PATH = os.path.join(WORKSPACE, "scene_plan.json")
SCENE_IMG_DIR = os.path.join(WORKSPACE, "scene")
if not os.path.exists(PLAN_PATH):
raise FileNotFoundError(f"未找到 {PLAN_PATH},请先运行场景划分")
plan = load_plan()
scenes = plan["scenes"]
total = len(scenes)
done = [s for s in scenes if s.get("status") == "generated"]
failed = [s for s in scenes if s.get("status") == "failed"]
pending = [s for s in scenes if s.get("status") == "pending"]
print(f"总场景: {total} | 已完成: {len(done)} | 失败: {len(failed)} | 待生成: {len(pending)}")
for idx, scene in enumerate(scenes):
status = scene.get("status")
if status == "generated":
print(f"[{idx+1}/{total}] 场景 {scene['scene_id']} 已完成,跳过")
continue
updated = generate_single_scene(scene, idx, total, model_name)
scenes[idx] = updated
save_plan(plan)
if updated["status"] == "failed":
print(f"[停止] 场景 {scene['scene_id']} 生成失败,再次运行可续传")
break
print(f"进度: {sum(1 for s in scenes if s.get('status') == 'generated')}/{total}")
done_count = sum(1 for s in scenes if s.get("status") == "generated")
print(f"\n========== 完成 ==========")
print(f"已完成: {done_count}/{total}")
if done_count == total:
print("[全部完成] 所有场景图已生成!")
else:
remaining = [s["scene_id"] for s in scenes if s.get("status") != "generated"]
print(f"剩余: {remaining}")
if __name__ == "__main__":
main()