데모 내레이션 스킬
데모 비디오에 AI 음성 내레이션을 생성하고 동기화합니다.
파이프라인 내 위치
이 스킬은 데모 비디오 파이프라인의 세 번째 단계입니다:
/demo-script → /record-demo → /demo-voiceover
(계획) (캡처) (내레이션 및 전달)
기존 비디오와 타임스탬프 로그에 내레이션을 추가하는 독립 실행형으로도 사용할 수 있습니다.
입력
이 스킬에는 다음이 필요합니다:
- 데모 스크립트 JSON —
/demo-script에서 생성 (workspace/<날짜>/demo-script-<이름>.json) - 원본 비디오 파일 —
/record-demo에서 생성 (workspace/<날짜>/<이름>_raw.mp4) - 타임스탬프 로그 —
/record-demo에서 생성 (workspace/<날짜>/<이름>_timestamps.json)
타임스탬프 로그 형식 (/record-demo에서 생성):
{
"video_file": "demo_raw.mp4",
"start_epoch": 1739545200.0,
"steps": [
{
"scene_id": "intro",
"step_index": 0,
"action": "navigate",
"narration": "OneTest에 오신 것을 환영합니다. 첫 번째 테스트 케이스를 만들어 보겠습니다.",
"timestamp_sec": 0.0,
"completed_sec": 1.2
},
{
"scene_id": "navigate-to-test-cases",
"step_index": 0,
"action": "click",
"narration": "사이드바에서 테스트 케이스 섹션을 엽니다.",
"timestamp_sec": 3.2,
"completed_sec": 3.8
}
]
}
파이프라인
1단계: 내레이션 계획
각 내레이션 세그먼트가 비디오와 관련하여 재생되어야 할 시점을 결정합니다:
타이밍 전략 옵션:
| 전략 | 내레이션 시작 시점 | 최적 사용 사례 |
|---|---|---|
on_action | 액션이 시작되는 순간 (timestamp_sec) | 곧 일어날 일을 설명할 때 |
after_action | 액션이 완료된 후 (completed_sec) | 방금 일어난 일을 설명할 때 |
before_action | 액션이 시작되기 0.5초 전 | 기대감을 조성할 때 |
fill_pause | pause_after_ms 윈도우 동안 | 의도적인 일시 정지 동안 내레이션할 때 |
기본값: fill_pause — 각 액션 후 일시 정지 중에 내레이션이 재생되므로, 시청자는 액션이 일어나는 것을 보고 화면이 안정된 후 설명을 듣게 됩니다. 이것이 가장 자연스럽게 느껴집니다.
계획 출력:
{
"segments": [
{
"index": 0,
"text": "OneTest에 오신 것을 환영합니다. 첫 번째 테스트 케이스를 만들어 보겠습니다.",
"video_start_sec": 1.2,
"max_duration_sec": 2.0
},
{
"index": 1,
"text": "사이드바에서 테스트 케이스 섹션을 엽니다.",
"video_start_sec": 3.8,
"max_duration_sec": 1.5
}
]
}
2단계: 오디오 생성 (ElevenLabs)
각 내레이션 세그먼트를 ElevenLabs with-timestamps 엔드포인트를 사용하여 생성합니다:
- 문자 수준 정렬 반환 (밀리초 단위의 정확한 지속 시간)
- 무료로 자막 생성 가능
previous_request_ids를 통한 연속성 체이닝 지원 (최대 3개)
python scripts/generate_narration.py --plan voiceover_plan.json --voice rachel --output-dir . 실행
API 세부 정보는 references/elevenlabs-api.md를 참조하세요.
3단계: 타이밍 조정
오디오 생성 후, 계획된 지속 시간과 실제 지속 시간을 조정합니다:
- 오디오가 사용 가능한 윈도우에 맞는 경우 -> 계획된 시작 시간에 배치
- 오디오가 더 짧은 경우 -> 추가 무음은 괜찮음 (데모는 여유를 둠)
- 오디오가 더 긴 경우 -> 속도 증가 (최대 1.15x,
atempo사용) 또는 텍스트를 줄이고 다시 생성
속도 조정은 1.15x로 제한합니다 — 그 이상은 급하게 들립니다.
4단계: 오디오 병합
내레이션 세그먼트를 도우미 스크립트를 사용하여 비디오와 병합합니다:
bash scripts/merge_audio_video.sh demo_raw.mp4 narration_results.json final_demo.mp4
이 스크립트는 세그먼트당 adelay와 속도 조정을 위한 atempo가 포함된 ffmpeg filter_complex를 빌드합니다.
5단계: 자막 생성
ElevenLabs의 문자 수준 타임스탬프를 통해 무료 SRT 생성이 가능합니다:
- 문자를 단어로, 단어를 자막 줄로 그룹화 (최대 8단어)
- 각 세그먼트의
video_start_sec만큼 오프셋 - 표준 SRT 형식으로 출력
비디오에 자막을 포함하려면:
ffmpeg -i final_demo.mp4 -vf subtitles=demo.srt \
-c:v libx264 -crf 18 -c:a copy \
final_demo_subtitled.mp4
음성 설정
청중에 따라 음성을 선택하고, 초안에는 eleven_turbo_v2를, 최종본에는 eleven_multilingual_v2를 사용하세요.
음성 ID, 설정 가이드, 모델 비교, 연속성 체이닝 세부 정보는 references/elevenlabs-api.md를 참조하세요.
페이싱 조정
| 문제 | 해결책 | 제한 |
|---|---|---|
| 오디오가 약간 김 | atempo 필터로 속도 증가 | 최대 1.15x |
| 오디오가 매우 김 | 내레이션 텍스트 단축, 재생성 | 해당 세그먼트만 재생성 |
| 오디오가 짧음 | 무음 패딩 추가 (자연스러움) | 데모 중 무음은 괜찮음 |
| 세그먼트 사이 간격이 어색함 | 일시 정지 연장 또는 전환 문구 추가 | 일시 정지는 3초 미만으로 유지 |
출력 파일
| 파일 | 설명 |
|---|---|
<이름>_final.mp4 | 비디오 + 내레이션 병합 |
<이름>_final_subtitled.mp4 | 비디오 + 내레이션 + 포함된 자막 |
<이름>.srt | 자막 파일 (별도) |
<이름>_narration_full.mp3 | 전체 내레이션 오디오 트랙 (재사용용) |
narration_NNN.mp3 | 개별 세그먼트 (재생성용) |
<이름>_voiceover_plan.json | 타이밍 계획 (디버깅/반복용) |
모든 파일은 workspace/<날짜>/에 저장됩니다.
반복 워크플로우
이 스킬은 모든 것을 재생성하지 않고 개별 세그먼트를 다시 수행할 수 있도록 지원합니다:
- 사용자가 비디오 검토: "장면 3의 내레이션이 너무 빠릅니다"
- 에이전트가 조정: 텍스트 단축, 세그먼트 3만 재생성
- 연속성을 위해 세그먼트 1-2의
previous_request_ids사용 - ffmpeg로 다시 병합 (오디오 트랙만 변경, 비디오는 그대로)
이 방식은 다음 이유로 빠릅니다:
- 비디오를 다시 녹화할 필요 없음
- 변경된 세그먼트당 ElevenLabs API 호출 한 번만 필요
- ffmpeg 병합은 몇 초면 완료