Video by Code Skill (코드 기반 비디오 제작 스킬)
인간-에이전트 팀이 코드로 결정론적 비디오를 만들기 위한 실행 가능한 툴킷 및 제작 워크플로우입니다. 모든 씬 코드는 리포지토리 또는 프로젝트 워크스페이스 내에 유지되며, 생성된 미디어, 오디오 테이크, 스틸 이미지, 검증 결과는 명시적인 외부 $PROD 디렉토리에 저장됩니다.
작업 순서: 브리프 → 오디오 및 타이밍 → 스타일 및 프롬프트 → 3개의 디자인 스틸 → 씬 코드 → 결정론 및 텍스트 경계 게이트 → 전체 렌더링 → 검증 및 콘택트 시트 → 전달 영수증
1. 환경 설정 및 스모크 테스트
새로운 영화를 만들기 전에, 필수 종속성이 설치되어 있고 4초 스모크 테스트가 리포지토리 루트에서 통과하는지 확인하세요:
cd starter && npm ci && cd ..
node tests/runtime-contract.mjs
2. 프로덕션 디렉토리 및 의도 (RUNBOOK.md §1–2)
- 코드 체크아웃 외부에 있는 절대 프로덕션 디렉토리를 선택하세요:
PROD="/absolute/path/to/video-outputs/<project-slug>" mkdir -p "$PROD"/{audio,analysis,stills,renders,checks} templates/brief.md를"$PROD/brief.md"로 복사하고 대상 청중, 핵심 요점, 종횡비(1920x1080가로 또는1080x1920세로), 길이, 음성/음악 소스, 안전 영역 여백을 입력하세요.
3. 오디오 식별 및 타이밍 (docs/04-music-audio-and-timing.md, docs/05-narration-and-captions.md)
추정된 타임스탬프로 애니메이션을 만들지 마세요. 먼저 실제 오디오 파일을 측정하고 SHA-256 해시를 기록하세요:
uv run tools/timing/audio-identity.py "$PROD/audio/source.wav" \
--out "$PROD/analysis/identity.json" --copy-wav "$PROD/analysis/analysis.wav"
- 음성 내레이션:
- 로컬 Kokoro ONNX TTS를 사용하여 합성합니다(
< 4단어 조각 병합 및--say say.json발음 사전 사용):uv run tools/timing/kokoro-narrate.py script.txt --out-dir "$PROD/audio" --voice af_heart --say say.json - 로컬
whisper-cli를 통해 합성된 오디오의 라운드트립을 검증합니다:uv run tools/verify/verify-narration.py "$PROD/audio/narration.wav" "$PROD/audio/timing.json" - 스크립트/가사가 참조 텍스트와 정확히 일치하는 n-gram 리프트를 확인합니다:
python3 tools/verify/check-lift.py candidate.txt reference.txt
- 로컬 Kokoro ONNX TTS를 사용하여 합성합니다(
- 음악 / 가사 / 스템 반응형 트랙:
- Demucs를 통해 6개 스템(
보컬, 드럼, 베이스, 기타, 피아노, 기타)을 분리하고 44.1kHz WAV로 정규화합니다:uv run --python 3.12 tools/timing/separate-stems.py "$PROD/audio/song.mp3" --out-dir "$PROD/analysis" - 120Hz 스템 엔벨로프, 단조 음악 시간
tau, 비트/마디 위상, 정지 구간,features.f32, 100fps 기타 피치/비브라토를 추출합니다:uv run --python 3.12 tools/timing/analyze-stems.py "$PROD/analysis" --fps 120 --stem-pitch - 단어 수준의 가사를 정렬합니다(
whisper-cli,mlx-whisper,faster-whisper또는acoustic보컬 밴드 에너지 워핑 사용):uv run tools/timing/align-words.py "$PROD/analysis/stems/vocals.wav" --script lyrics.txt --backend whisper-cli --out "$PROD/analysis/words.json" - 가벼운 단일 파일 큐 / 비트 그리드 / 비주얼라이저 엔벨로프:
uv run tools/timing/cue-extract.py "$PROD/audio/song.mp3" --out "$PROD/analysis/cues.json"uv run --python 3.12 tools/timing/beat-grid.py "$PROD/analysis/analysis.wav" --out "$PROD/analysis/beats.json"python3 tools/build-visualizer.py "$PROD/analysis/analysis.wav" --out "$PROD/analysis/features.js"
- Demucs를 통해 6개 스템(
4. 스타일 선택 및 프롬프트 조합 (prompts/README.md)
prompts/styles/INDEX.md (13개 패밀리, 86개의 작성된 시각 스타일 카드) 와 prompts/briefs/ (5개 포맷 브리프: explainer-voiceover, vertical-short, lyric-video, instrumental-visualizer, data-story) 를 살펴보세요.
선택한 스타일과 브리프에 대한 결합된 사양을 조합하세요:
python3 tools/build-prompt.py <style-id> --brief <brief-id> --out "$PROD/style-prompt.md"
5. 씬 작성 규약 (lib/API.md, docs/06-building-scenes.md, docs/12-advanced-engines-and-benchmarks.md)
모든 씬 HTML 페이지는 lib/harness.js (window.H) 를 로드하며, 선택적으로 다음을 로드합니다:
lib/sound.js(window.SOUND) — 절차적 Web Audio 합성lib/features.js(window.FEATURES) — 120Hz 바이너리features.f32스템 커서, 불응기 발병 펄스, 단조tau(t),words.json가사 조회lib/ink-doodle.js(window.INK) — 8fps 결정론적 라인 보일, 흔들리는 낙서 프리미티브, 왼쪽 정렬 ALL-CAPS 쓰기-온marker, Ken Burnsplate카메라lib/webgl-post.js(createPost) — 4단계 Three.js 후처리(FxOverShader,UnrealBloomPass,FinalGradeShader(ACES /paperMode), 휘도 전용 충격 반전, 글리치, 흔들림, 그레인, 깔끔한 UI 오버레이)
모든 페이지는 다음을 노출합니다:
<canvas id="c" width="1920" height="1080"></canvas>(또는 세로의 경우1080×1920)window.DURATION(초) 및window.FPS(기본값30)window.__ready(폰트와 캐시된 오프스크린 플레이트가 준비된 후 resolve되는 Promise)window.__renderFrame = (t) => { ... }—t(초)의 순수 함수.- 모든 프레임을
ctx.reset()(또는 균형 잡힌save()/restore()) 로 시작하세요. - 프레임 루프 외부에서
H.rng(seed)및H.noise(seed)를 사용하세요. 절대 프레임 간에 가변 상태를 변경하지 마세요. H.paperTexture(...)또는H.offscreen(key, w, h, fn)을 사용하여 종이/표면 텍스처를 한 번 캐시하세요.- 스토리에 중요한 텍스트에 대해
window.__textBounds = () => [...]를 노출하여({text, critical: true, left, right, top, bottom}) 자동 안전 영역 검사가 모든 프레임을 확인할 수 있도록 하세요.
- 모든 프레임을
window.scoreSound = (k) => { ... }— 고정 타임라인 타임스탬프에 절차적 사운드 이벤트를 예약합니다(--voice가 제공되면 배경/음악을 자동으로 억제합니다).
테스트에서 얻은 주요 제작 규칙
- 안전 영역 여백 및 글꼴 두께: macOS Chrome에서
Arial은 두께400과700만 제공합니다(600은700Bold로 스냅되어 줄 너비가 약 9% 넓어짐). 항상 모든 프레임에 대해measureText(s).actualBoundingBox*를 감사하세요(1080x1920세로 숏폼의 경우x: 80..960, y: 190..1640). - 연속 카메라 스타일 (
transit-map, pan-and-zoom): 카메라 보간을beat[i].start에서 시작하세요(i가beat[i].start에서 전환될 때beat[i].start - preRoll에서 시작하지 마세요. 1프레임 점프가 발생함). 비트-로컬 오버레이는0.20 s동안 페이드 아웃하고, 월드-공간 레이블은 클리핑된 지도 뷰포트 내부에 있을 때만 그려지도록 보호하세요.
6. 스틸 렌더링, 결정론 확인 및 마스터 렌더링 (docs/07-rendering.md)
- 시크 결정론 게이트:
node starter/determinism.mjs path/to/film.html - 디자인 스틸 게이트 (전체 렌더링 전에 시작, 중간, 끝 프레임 검사):
node starter/render.mjs path/to/film.html --stills 1.5,12.0,24.0 --outdir "$PROD/stills" - 전체 MP4 렌더링:
- 참조 단일 워커 Playwright 렌더러 (기본 30fps Canvas2D + 절차적 오디오):
node starter/render.mjs path/to/film.html \ --out "$PROD/renders/master.mp4" --fps 30 --audio page \ --voice "$PROD/audio/narration.wav" - 멀티 워커 GPU WebSocket 렌더러 (60fps Three.js / WebGL / 키네틱 타이포그래피):
node tools/render/parallel-ws-render.mjs \ --url "http://127.0.0.1:5173/?capture=1" --duration <DURATION> --fps 60 --workers 4 \ --audio "$PROD/analysis/analysis.wav" --out "$PROD/renders/master.mp4" - Browserless Python + Pillow
rawvideo렌더러 (캡션이 포함된 워크북 및 튜토리얼):uv run tools/render/workbook-render.py \ --spec workbook.json --audio "$PROD/audio/narration.wav" --out-dir "$PROD/renders"
- 참조 단일 워커 Playwright 렌더러 (기본 30fps Canvas2D + 절차적 오디오):
7. 필수 검증 게이트 (docs/08-verification.md)
모든 프로덕션은 전달 전에 다음 검사를 실행하고 그 결과를 "$PROD/checks/" 에 기록해야 합니다:
- 스트림, 디코드, 동기화 및 음량 게이트:
uv run tools/verify/verify-video.py "$PROD/renders/master.mp4" \ --expect-seconds <DURATION> --fps 30 --width <W> --height <H> \ --json "$PROD/checks/verify-video.json" - 콘택트 시트 시각적 검사:
uv run tools/verify/contact-sheet.py "$PROD/renders/master.mp4" \ "$PROD/checks/contact-sheet.jpg" --n 16 --cols 4 --tile-width 270contact-sheet.jpg와 씬 스틸을 시각적으로 검사하여 텍스트 잘림, 레이블 충돌, 의도치 않은 빈 프레임이나 정지 프레임이 없는지 확인하세요. - 전환 및 컷 강도 감사:
uv run tools/verify/cut-harshness.py "$PROD/renders/master.mp4" \ --top 15 --json "$PROD/checks/cut-harshness.json" - 룩 및 팔레트 진단:
uv run tools/verify/measure-look.py "$PROD/renders/master.mp4" \ --samples 16 --json "$PROD/checks/measure-look.json" - 전체 프레임 텍스트 경계 감사:
tests/layout.mjs의 패턴을 따라 모든 프레임0 .. frames-1에 대해fillText잉크 경계와window.__textBounds()를 검증하세요.
8. 패키징 및 전달 (RUNBOOK.md §12)
"$PROD/qa.md" (templates/qa.md 에서) 와 "$PROD/delivery.md" (templates/delivery.md 에서) 를 완성하세요. 머신 검증 결과(PASS/WARN 판정)는 인간의 창의적 시청 및 청취 승인과 별도로 보고하세요.
주요 참고 자료
README.md— 빠른 시작 및 챕터 인덱스RUNBOOK.md— 12단계 인간-에이전트 제작 체크리스트lib/API.md— 정확한H그래픽 및SOUND절차적 오디오 규약examples/README.md— 실제 가로, 세로 및 스타일 연구 예제docs/10-pitfalls.md— 증상 → 원인 → 수리 표