59 lines
2.3 KiB
Python
59 lines
2.3 KiB
Python
"""bgm 수동 확인용. **Suno는 실제 과금이 나간다.**
|
|
|
|
사용: uv run python -m tests.poster_alive.test_bgm <포스터경로>
|
|
test_result/<이름>.narration.txt(bgm_style)와 <이름>.tts.txt(total)를 재사용한다.
|
|
없으면 앞 단계부터 돌린다. 결과는 <이름>.bgm.mp3 와 <이름>.bgm.txt.
|
|
"""
|
|
import asyncio
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from models.tts import NarrationTimeline
|
|
from services.bgm import generate_bgm
|
|
from services.tts import synthesize
|
|
from tests.poster_alive.test_tts import load_narration
|
|
|
|
TEST_RESULT_DIR = Path(__file__).parent.parent / "test_result" / "poster_alive"
|
|
|
|
|
|
async def load_timeline(sentences: list[str], voice: str, timeline_path: Path
|
|
) -> NarrationTimeline:
|
|
if timeline_path.exists():
|
|
return NarrationTimeline.model_validate_json(timeline_path.read_text(encoding="utf-8"))
|
|
audio = await synthesize(sentences, voice)
|
|
timeline_path.write_text(audio.timeline.model_dump_json(indent=2), encoding="utf-8")
|
|
return audio.timeline
|
|
|
|
|
|
async def main() -> None:
|
|
poster_path = Path(sys.argv[1])
|
|
TEST_RESULT_DIR.mkdir(exist_ok=True)
|
|
output_base = TEST_RESULT_DIR / poster_path.stem
|
|
|
|
answer = await load_narration(poster_path, output_base)
|
|
timeline = await load_timeline(answer.narration, answer.voice,
|
|
output_base.with_suffix(".tts.txt"))
|
|
|
|
print(f"나레이션 {timeline.total}s → BGM 요청")
|
|
print(f" style : {answer.bgm_style.style}")
|
|
print(f" prompt: {answer.bgm_style.prompt}")
|
|
print("Suno 생성 시작 — 최대 5분 폴링, 과금됩니다.")
|
|
|
|
audio = await generate_bgm(answer.bgm_style, timeline.total, title=poster_path.stem)
|
|
|
|
mp3_path = output_base.with_suffix(".bgm.mp3")
|
|
meta_path = output_base.with_suffix(".bgm.txt")
|
|
mp3_path.write_bytes(audio.mp3)
|
|
meta_path.write_text(json.dumps(
|
|
{"task_id": audio.task_id, "seconds": audio.seconds, "duration": audio.duration,
|
|
"style": answer.bgm_style.style, "prompt": answer.bgm_style.prompt},
|
|
ensure_ascii=False, indent=2), encoding="utf-8")
|
|
|
|
print(f"\n목표 {audio.seconds}s → 실제 {audio.duration}s (taskId={audio.task_id})")
|
|
print(f"{mp3_path}\n{meta_path}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|