playreel/backend/test_i2v.py

55 lines
2.1 KiB
Python

"""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())