스킬: Motion Video 3D (Remotion + Three.js + PiP)
사용 시기
- "내 영상이 구석에서 말하는 3D 영상 만들어 줘"
- "[주제]에 관한 시네마틱 TikTok 스타일 영상"
- "3D 배경과 애니메이션 자막이 있는 영상"
- "[내 오디오/내 영상]이 X라고 말하는 영상"
철학 (황금률)
영상은 주제에 대해 창의적이고 상황에 맞아야 합니다. 일반적인 3D로는 충분하지 않습니다. 대본의 각 문장은 개념을 번역하는 고유한 시각적 요소를 영감해야 합니다. 예시:
- "8분 20초" 문장 → 8:20까지 돌아가는 디지털 주행거리계
- "300,000 km/s" 문장 → 바늘이 있는 SF HUD 속도계
- "비행기가 3바퀴를 돈다" 문장 → 궤적을 남기며 지구를 공전하는 비행기
- "빛이 태양에서 지구로 여행한다" 문장 → 렌즈 플레어가 있는 광자
사용자는 이러한 수준의 상황적 창의성을 요구합니다. 절대 페이드인만 있는 정적 텍스트를 만들지 마십시오.
사전 요구 사항 (시작 전 확인)
- Node.js + npm 설치
- FFmpeg 설치 (
brew install ffmpeg) - Whisper-cpp 설치 (
brew install whisper-cpp) — 단어 동기화 용 - FREESOUND_API_KEY
~/.zshrc에 설정 (SFX API 필수) - 내레이터 비디오/오디오
public/eu.mp4또는public/audio/*.mp3
하나라도 없으면 중단하고 사용자에게 알립니다.
1. 프로젝트 구조
~/Documents/[프로젝트 이름]/ ├── public/ │ ├── eu.mp4 # 내레이터 비디오 (PiP가 있는 경우) │ ├── audio/*.mp3 # 순수 오디오 (비디오가 없는 경우) │ ├── images/[주제]/ # 다운로드한 이미지 (credits.json 포함) │ └── sfx/ # Freesound에서 다운로드한 SFX ├── src/ │ ├── three/ # 3D 씬 (Three.js) │ ├── components/ # 자막, HUD, 오버레이 │ ├── timeline.json # 모든 타이밍 (진실의 원천) │ └── Root.tsx ├── scripts/ │ ├── align-words.py # Whisper → 단어 타임스탬프 │ ├── gen-sfx.mjs # 로컬 합성 (패드, 드론) │ ├── fetch-freesound.mjs # 필수: Freesound API에서 SFX 다운로드 │ ├── finalize.sh # -14 LUFS + faststart │ └── contact-sheet.sh # 안전 영역이 있는 컨택트 시트 ├── out/ │ ├── final_[주제].mp4 │ ├── thumbnail.png # 1080x1920 썸네일 │ └── contact_sheet.png └── timeline.json
2. 필수 워크플로 (순서대로)
단계 0: 브리핑
사용자와 확인:
- 영상 주제
- 오디오 실제 길이 (절대 펀치라인 자르지 않음)
- 색상 팔레트 (기본: 딥 블랙 + 주제와 일치하는 악센트 색상)
- 3D 배경 스타일 (섹션 3 참조)
- PiP (비디오가 있는 경우): 위치 오른쪽 아래, x ≤ 940
- 자막: 운동형 (섹션 5 참조)
단계 1: 설정 + Whisper
- Remotion + @remotion/three + @react-three/fiber + three 초기화/확인
scripts/align-words.py실행하여 오디오 전사- 각 단어의 정확한 타이밍으로
timeline.json생성 - 장면 코딩 전에 멈추고 승인 대기
단계 2: 테마 3D 배경 (섹션 3 참조)
단계 3: PiP (있는 경우) + 자막 + HUD (섹션 4, 5 참조)
단계 4: Freesound를 통한 SFX (섹션 6 참조) — 필수
단계 5: 렌더링 + 믹스 + 컨택트 시트 + 썸네일
3. 동적 3D 배경 (창의성 필수)
규칙: 배경은 정적이어서는 안 됩니다. 지속적인 움직임과 떠다니는 요소가 있어야 합니다. 주제에 따라 스타일을 결정하십시오:
| 주제 | 3D 배경 |
|---|---|
| 우주 / 천체 | 시차가 있는 별 3개 층, 미세한 성운, 지평선의 행성 |
| 프로그래밍 / 기술 | 떠다니는 코드 매트릭스, "비트" 입자, 와이어프레임 회로, 애니메이션 그리드 |
| iPhone / 미니멀리스트 | 떠다니는 먼지 입자 (느리고 크기 다양), 부드러운 체적광, Stranger Things 거꾸로 세계 스타일 |
| 자연 | 떠다니는 유기적 잎/입자, 여과된 햇빛, 시차를 통한 깊이 |
| 도시 / 도심 | 먼 네온 불빛, 빗방울 입자, 시차 스카이라인 |
| 과학 / 실험실 | 떠다니는 분자, 와이어프레임 시험관, 빛나는 입자 |
항상 포함:
- 시차 (최소 3개 층, 속도 다름)
- 카메라 움직임 (영상 전체에 걸친 미세한 드리프트)
- 체적 조명 (부드러운 빛, 평평하지 않음)
- 후처리 (블룸, 미세한 비네트)
- 주제와 일치하는 색상 (일반 팔레트 사용 금지)
4. PiP (Talking-head) — 비디오가 있는 경우
- Remotion의
<OffthreadVideo>사용 - 정확한 종횡비 (얼굴 왜곡 금지)
- 위치: 오른쪽 아래, BUT 안전 영역 준수 (x ≤ 940)
- 스타일: 둥근 모서리 24px, 부드러운 그림자, 얇은 테두리
- 절대 원본 비디오의 색상, 배경, 종횡비, 오디오 변경 금지
- 페이오프 순간에만 확대 (예: 1.12x)
- 오디오만 있는 경우: PiP 대신 목소리에 맞춰 맥박치는 "오디오 시각화 HUD" 추가
5. 자막 (운동형 + "직사각형" 없음)
애니메이션 규칙:
- 단어별 (문장별 아님) — 각 단어가 말하는 정확한 프레임에 표시
- 오버슈트가 있는 Ease-out (~단어당 0.15초)
- 키워드: 흰색 플래시 + 악센트 색상에 정착 + 글로우 + 짧은 확대
- 미리 레이아웃된 줄 (단어가 줄을 "뛰어넘지" 않도록)
⚠️ 중요 규칙: 직사각형 금지
텍스트 뒤에 단색 background-color를 사용하지 마십시오. 가독성을 위해 다음만 사용:
text-shadow: 4px 4px 8px rgba(0,0,0,0.9)filter: drop-shadow(0 2px 8px rgba(0,0,0,0.8))- 선택 사항: 개별 단어 뒤에 ≤ 15% 불투명도의 방사형 그라데이션
- 절대: 문장 주위에
<div style="background: rgba(0,0,0,0.7)">사용 금지
텍스트는 배경 위에 떠 있어야 하며, 카드처럼 보이면 안 됩니다.
위치:
- 가로 중앙
- Y 1400-1550 사이
- 최소 크기: 72px (모바일에서 읽기 가능)
6. Freesound API를 통한 SFX (필수)
사용자는 Freesound API에서 사운드를 다운로드해야 합니다. 로컬 합성만 사용하지 마십시오.
흐름:
~/.zshrc에서FREESOUND_API_KEY확인scripts/fetch-freesound.mjs생성/사용하여 검색 및 다운로드- 최소 SFX 맵 (주제에 맞게 조정):
| 순간 | 유형 | Freesound 검색어 |
|---|---|---|
| 오프닝 | 부드러운 디지털 부팅 | "soft digital boot" |
| 텍스트 충격 | 시네마틱 히트 | "cinematic impact hit" |
| 카운터 | 시계 틱 | "digital counter tick" |
| 속도계 | 속도계 윙 | "engine whine pitch up" |
| 날아가는 물체 | 제트 윙 | "jet flyby whoosh" |
| 3D 공개 | 상승 리저 | "cinematic riser" |
| 도착/클라이맥스 | 붐 + 차임 | "cinematic boom chime" |
| 최종 CTA | 부드러운 차임 | "soft notification chime" |
- CC0 우선 필터링; 대체 CC-BY (
public/sfx/CREDITS.json에 기록) public/sfx/에 저장- 연속 사운드(스페이스 패드, 드론, 긴 리저)는 로컬로 합성만
scripts/gen-sfx.mjs를 통해
믹싱:
- 음성: 절대 처리 금지 (-14 LUFS 달성을 위해 게인만 올림, 리미터 -1 dBTP)
- SFX: 덕킹 -3dB (후시), -8dB (붐) — 음성을 낮추는 것이 아니라 SFX를 음성 아래로 낮춤
- 스페이스 패드: -24dB 연속, 페이드인 1초, 페이드아웃 2초
- 최종 라우드니스: -14 LUFS, 최대 피크 -1 dBTP
7. TikTok 안전 영역 (필수)
- 캔버스: 1080×1920, 60fps
- 안전 영역: x ∈ [60, 1020], y ∈ [120, 1670]
- 액션 바 (오른쪽): x > 960 침범 금지
- 상단 바: y < 120
- 하단 (캡션): y > 1670
- PiP: 절대 x > 940 오버랩 금지
- 항상 안전 영역 오버레이가 있는 컨택트 시트로 검증
8. 최종 체크리스트
- 길이 = 오디오 실제 길이 (펀치라인 자르지 않음)
- Whisper가 단어 단위로 전사 및 동기화함
- 테마 3D 배경 + 동적 + 시차
- 운동 타이포그래피 자막, 직사각형 배경 없음
- PiP 안전 영역 준수 (x ≤ 940) — 있는 경우
- 최소 5개의 창의적 상황별 요소 (HUD, 날아가는 물체)
- Freesound API에서 다운로드한 SFX (합성만 아님)
- 믹싱 -14 LUFS / -1 dBTP
- 안전 영역 오버레이가 있는 컨택트 시트
- 썸네일 생성 (out/thumbnail.png)
- 3초 후크 검증 (3D 요소 + 텍스트 + SFX + 카메라)
- ffprobe로 1080x1920, 60fps, H.264 + AAC 검증
9. macOS 샌드박스 문제 처리
Claude Code가 "Operation not permitted"로 폴더 접근을 잃는 경우:
- 모든 파일을 스크래치패드에 준비
- 설치 및 렌더링하는 단일 스크립트
finish-v2.sh생성 - 사용자가 터미널에서 수동으로 실행
- Claude Code는 사용자가 다시 붙여넣는 ffprobe 출력을 읽음
항상 마지막에 수동 폴백 포함.
10. 이미지 라이선스 정보 (다운로드하는 경우)
- Wikimedia Commons (CC0/CC-BY/CC-BY-SA) 선호 — 항상 라이선스 확인
- Apple/공식 기업 (공정 사용 편집) 선호
- 임의 사이트 / Pinterest / 스톡 이미지 피할 것
credits.json저장: {filename, source_url, author, license}- 다운로드 전에 각 이미지를 감사하는
LICENSE_CHECK.md생성 - 명확한 라이선스가 없으면 Three.js로 절차적 대안 생성
요약: 이 스킬은 모든 대본을 테마 3D, 운동 타이포그래피, 창의적 HUD, PiP(선택 사항), Freesound를 통한 전문 사운드 디자인이 포함된 시네마틱 TikTok 영상으로 변환합니다. 상황적 창의성은 필수입니다 — 대본의 각 문장은 고유한 시각적 요소를 영감해야 합니다.