# task: 에반 스타일 영상에 TTS 음성 합성 + 싱크

## 레벨: Lv.2

## 목표
task-462.1에서 만든 에반 스타일 영상(`video/evan_dynamic.py`)에 한국어 나레이션 음성을 입혀 최종 영상을 생성한다.
**업로드 없이 영상 파일만 제작** (업로드 전단계).

## 핵심 요구사항: Audio-Video Sync
- 장면별 나레이션을 edge-tts로 생성 → 각 음성 길이 측정
- evan_dynamic 렌더러의 장면별 duration을 **음성 길이에 맞춰** 재조정
- 나레이션이 끝나는 타이밍 = 장면 전환 타이밍 (정확한 싱크)
- 최종: ffmpeg으로 영상 + 음성 mux

## 기존 인프라 (반드시 활용)
- `audio/edge_tts_dialogue.py` — edge-tts 기반 TTS 합성 모듈
  - 한국어 음성: `ko-KR-SunHiNeural` (여성), `ko-KR-InJoonNeural` (남성)
  - pydub으로 오디오 길이 측정 가능
- `video/evan_dynamic.py` — 에반 스타일 렌더러 (EvanDynamicRenderer)
  - 장면별 duration 파라미터 지원
- ffmpeg: `/home/jay/.local/bin/ffmpeg`
- pydub: 설치 완료

## 영상 5장면 내용 (task-462.1 보고서 참조)
1. **Hook (현재 5초)**: "보험료, 매달 새고 있진 않나요?" + 절약 뱃지
2. **통계 (현재 5초)**: "78%" 대형 숫자 + "가입 3년 안에 해지" 카드
3. **체크리스트 (현재 6초)**: 3개 카드 순차 등장 (특약정리, 중복확인, 갱신전환)
4. **비교 (현재 5초)**: 프로그레스 바 비교 (미활용 15% vs 풀활용 95%)
5. **CTA (현재 4초)**: "점검하세요" + @서울대보험쌤

## 나레이션 텍스트 (참고, 팀장 판단으로 조정 가능)
1. "매달 나가는 보험료, 혹시 새고 있진 않으신가요?"
2. "실제로 보험 가입자 78%가 3년 안에 해지합니다. 제대로 설계가 안 됐기 때문이죠."
3. "특약 정리, 중복 보장 확인, 갱신형에서 비갱신으로 전환. 이 세 가지만 점검해도 달라집니다."
4. "보장을 제대로 활용하면 실질 보장률이 15%에서 95%까지 올라갈 수 있습니다."
5. "지금 바로 내 보험 점검해보세요. 서울대보험쌤이 도와드리겠습니다."

## 구현 방향
1. `video/tts_sync.py` (신규) — TTS 생성 + 영상 재렌더링 + 합성 파이프라인
   - `generate_narration(scenes_text: list[str]) -> list[Path]` — 장면별 MP3 생성
   - `measure_durations(audio_files: list[Path]) -> list[float]` — 각 MP3 길이(초) 측정
   - `render_with_audio(scene_config, audio_durations) -> Path` — duration 맞춰 재렌더링
   - `mux_audio_video(video: Path, audio: Path) -> Path` — ffmpeg 합치기
2. 음성: 남성(ko-KR-InJoonNeural) 사용. 속도 +5~10% (에반 영상 느낌에 맞게)
3. 장면 간 0.3~0.5초 여백 추가 (나레이션 끝~다음 장면 시작 사이 숨 쉴 틈)

## 산출물
- `/home/jay/projects/ThreadAuto/output/videos/threads_evan_with_voice.mp4` — 최종 영상
- `/home/jay/projects/ThreadAuto/output/videos/threads_evan_with_voice_thumb.png` — 썸네일

## 테스트
- TTS 생성 확인 (MP3 파일 존재 + 길이 > 0)
- 재렌더링 영상 길이 = sum(음성 길이 + 여백)
- 최종 영상에 오디오 트랙 존재 확인 (ffprobe)
- 기존 테스트 깨지지 않음

## 프로젝트 경로
- ThreadAuto: `/home/jay/projects/ThreadAuto/`