코드로 프로모션 비디오 만들기
개요
코드(Remotion: React 컴포넌트를 프레임 단위로 렌더링)로 만든 프로모션 필름입니다. 다음 네 가지 원칙에 따라 작동합니다.
- 하나의 싱크 맵이 모든 것을 제어합니다. 화면, 카메라, 음악, 효과음 모두 명명된 히트(named hits)를 참조하므로, 하나의 타이밍을 변경하면 모든 것이 함께 변경됩니다.
- 편집 전에 캐스팅합니다. 감독은 필름이 변경되기 전에 옵션을 듣고 봅니다.
- 최종본 전에 프리뷰를 진행합니다.
- 모든 주장은 제품에 충실합니다.
먼저 기본 규칙을 확인하세요: 비디오 저장소 자체의 규칙(README, CLAUDE.md, 또는 저장소 루트에 있는 house-rules.md)을 다른 모든 것보다 먼저 읽으십시오. 이 규칙들은 아래의 기본값을 재정의합니다. 이 폴더에 있는 house-rules.example.md는 작성 템플릿입니다.
새 필름 설정하기
- 각 필름은 하나의 브랜치 또는 워크트리(worktree)를 사용하며, 제품 앱 내부가 아닌 비디오 전용 저장소에 저장됩니다. 각 필름은
src/videos/<name>/폴더에 위치합니다. - 이 스킬의
templates/폴더를 해당 폴더에 복사하세요:sections.ts: 싱크 맵,HITS,TRACK_BPMfilm-camera.tsx: 2.5D 카메라shots.ts: 샷 목록Film.tsx: 컴포지션 뼈대, 헤더에Root.tsx등록 포함
templates/render.sh와scripts/*.py를 저장소의scripts/폴더에 복사하세요.- 정확히 동일한 하나의 버전으로 고정된 종속성:
remotion,@remotion/cli,@remotion/motion-blur. 오디오 스크립트용:ffmpeg,numpy,soundfile. - 하나의 컴포지션이
formatprop(가로 1920x1080, 세로 1080x1920)을 통해 두 포맷을 모두 렌더링합니다. 각 포맷은 독립적으로 레이아웃되며 레터박스 처리되지 않습니다.
워크플로우
- 스토리보드 명세 (설치된 경우 superpowers:brainstorming 스킬 사용).
docs/.../YYYY-MM-DD-<name>-design.md에 작성하세요. 화면의 모든 주장을 제품 코드와 실시간 플래그와 비교하여 확인하고, 제품이 사용하는 방식으로 표현하세요. - 영화 편집 전에 캐스팅 보드를 먼저 진행합니다. 음성(라인을 소리 내어 읽음), 타이핑 소리, 여러 음악 옵션, 룩 또는 캐릭터 초안을 각각 코드(A1, B4, M1…)와 함께 표시하세요. 시각적 초안을 작은 보드 컴포지션으로 렌더링하고, 페이지를 비공개로 게시한 후 감독의 선택을 기다리세요. 음성, 음악 트랙 또는 룩을 무단으로 선택하지 마세요.
- 빌드.
- 카피와 타이밍은 config에서 관리합니다.
- 장면, 샷 및 사운드는
HITS이름을 참조하며, 원시 숫자를 사용하지 않습니다. - 카메라 작업:
camera.md를 읽으세요.
- 720p 프리뷰 (
scripts/render.sh <Comp> <format> preview <name>-preview-vN-720p). 검증한 내용, 테스트할 수 없었던 내용, 요청 외에 변경한 사항을 보고합니다. - 최종본은 승인 후에만: 전체 크기, 두 포맷 모두. 긴 렌더링은 기기가 절전 모드로 전환되면 중단되므로, 먼저 전원을 확인하세요.
- 필름 브랜치에 커밋합니다. 요청 시에만 병합하거나 푸시합니다. 이전 필름은 렌더링이 변경되지 않아야 합니다.
오디오 규칙
| 규칙 | 이유 |
|---|---|
사진은 음소거로 렌더링하고, 별도로 --codec=wav로 오디오를 렌더링한 다음 scripts/mux.py(-15 LUFS + 리미터)로 믹싱합니다. | Remotion의 인렌더 AAC는 전체 사운드트랙을 43ms 지연시킵니다. |
음악은 상업적으로 라이선스되거나 생성된 것이어야 하며, 모든 파일은 CREDITS.md에 기록됩니다. | 일부 "무료" 효과음 팩은 상업적 사용에 라이선스가 부여되지 않았습니다. |
선택한 트랙에 맞추기: scripts/beatgrid.py track [bars] [arc]는 BPM과 다운비트를 제공합니다. TRACK_BPM을 설정한 다음, music-edit.py(전체 마디, 다운비트에서 크로스페이드) 또는 fit-track.py(직접 윈도우)로 트랙을 자릅니다. | 필름이 트랙에 맞춰 리타이밍됩니다(반대의 경우가 아님). |
음성은 상업적 라이선스가 있는 TTS(Kokoro-82M은 Apache-2.0)에서만 가져옵니다. macOS say를 절대 사용하지 마세요. | say 라이선스는 개인 및 비상업적 용도입니다. |
| 효과음은 결정론적으로 생성됩니다. 각각의 새 사운드는 고유한 PRNG를 사용하여 끝에 추가합니다. | 그렇지 않으면 모든 이후 파일이 변경됩니다. |
렌더링에서 Math.random()을 절대 호출하지 마세요. film-camera.tsx의 hash()를 사용하세요. | 프레임은 매번 동일하게 렌더링되어야 합니다. |
결과물 전달 전 QA
- 타입체크.
- 음량 약 -15 LUFS, 실제 피크 -1 dBTP 미만 (
ffmpeg -af ebur128). 원시 WAV 피크는 0.99 미만으로 유지되어 클리핑이 없습니다. - 효과음이 해당 히트 프레임에 정확히 일치합니다.
- QR 코드가 1080p와 720p 모두에서 디코딩됩니다.
- 변경된 모든 섹션의 스틸 이미지를 두 포맷 모두로 렌더링(Remotion
renderStill)하고 직접 확인하세요. 리뷰어 에이전트는 잘린 가장자리를 놓칠 수 있으며, 작고 빠른 모델의 리뷰는 공식 리뷰로 간주되지 않습니다.
자주 발생하는 실수
| 실수 | 해결책 |
|---|---|
| 모션이 원시 프레임, 비트 또는 초에 키프레임됨 | sections.ts에 명명된 히트를 추가하고 참조하세요. |
| 카메라 롤 또는 틸트가 이후 샷에 영향을 미침 | 키가 전달되므로 필드를 재설정하세요(roll: 0). |
| 승인 전에 최종본 렌더링 | 먼저 720p 프리뷰를 보내세요. |
| 감독이 듣거나 본 적이 없는 음성, 트랙 또는 룩 | 먼저 캐스팅 보드에 올리세요. |
| 단일 패스 mp4에 오디오 포함 | 음소거 사진 -> WAV -> 믹싱. |
여러 날에 걸친 필름의 /tmp 아래 임시 작업 | 시스템이 정리합니다. 실제 워크트리 폴더를 사용하세요. |
자동 모드에서 $(...) 또는 루프가 포함된 쉘 원라이너가 거부됨 | 로직을 스크립트 파일에 넣으세요. |