"""i2v 수동 확인용. 사용: uv run python test_i2v.py <포스터경로> test_result/<이름>.i2v.txt(프롬프트)와 <이름>.detect.txt(영역)를 쓴다. 결과는 <이름>.clip.mp4 와 <이름>.title_gate.txt. """ import asyncio import sys from pathlib import Path from models.detect import Regions from services.i2v import DEFAULT_MODEL, animate, cli_args from utils.higgsfield import run_cli TEST_RESULT_DIR = Path(__file__).parent / "test_result" async def main() -> None: poster_path = Path(sys.argv[1]) output_base = TEST_RESULT_DIR / poster_path.stem prompt_path = output_base.with_suffix(".i2v.txt") detect_path = output_base.with_suffix(".detect.txt") for required in (prompt_path, detect_path): if not required.exists(): raise SystemExit(f"{required} 없음 — 앞 단계를 먼저 돌릴 것") prompt = prompt_path.read_text(encoding="utf-8").strip() regions = Regions.model_validate_json(detect_path.read_text(encoding="utf-8")) raw = await run_cli("generate", "cost", DEFAULT_MODEL, *cli_args(prompt, poster_path, DEFAULT_MODEL), "--json", timeout=300) print(f"=== generate cost 원본 출력 ({len(raw)}자) ===\n{raw}\n=== 끝 ===\n") result = await animate(prompt, poster_path, regions) clip_path = output_base.with_suffix(".clip.mp4") verdict_path = output_base.with_suffix(".title_gate.txt") clip_path.write_bytes(result.clip) verdict_path.write_text(result.title_gate.model_dump_json(indent=2), encoding="utf-8") verdict = result.title_gate print(f"{result.model} · {result.credits} 크레딧 · {len(result.clip) / 1e6:.1f}MB") print(f"제목 게이트 {'통과' if verdict.passed else '실패'} 픽셀 A={verdict.pixel_score}" f"{' (하드컷 초과)' if verdict.pixel_hard else ''}") if verdict.skip: print(f" 판정 생략: {verdict.skip}") for frame in verdict.frames: print(f" {'✓' if frame.legible else '✗'} t={frame.time}s {frame.broken}") print(f"\n{clip_path}\n{verdict_path}") if __name__ == "__main__": asyncio.run(main())