remotion-build — Remotion 비디오 생성
DESIGN.md(remotion-consult 산출물)를 기반으로 React 코드를 사용하여 MP4를 생성합니다. 자막이 유일한 타임라인이며, 모션 효과는 전체 모션 효과 라이브러리에서 import하고, 에셋은 교차 하네스 라우팅을 통해 가져옵니다.
워크플로우
Step 0 — 모드 선택 (네 가지 중 하나 선택, 먼저 정한 후 진행)
- 카테고리 템플릿: 사용자가 특정 스타일을 원하거나
remotion-shared/categories/의 네 가지 카테고리(구술 자막/데이터 시각화/제품 데모/브랜드 모션) 중 하나를 선택한 경우 → 해당 카테고리의DESIGN.template.md+motion-list.md를 읽고, 디자인 시스템을 상속받아 내용과 자막만 교체합니다. - 참조 참고: 사용자가 참조 비디오(최우선)를 제공하거나
remotion-shared/video-real-library.md에서 선택한 경우 → 자막 스타일/전환/리듬을 분석하고, 전체 모션 효과 라이브러리의 컴포넌트를 사용하여 재현합니다. - 자유 디자인: 참조도 템플릿도 없는 경우 →
video-anti-slop.md의 역프롬프트만 피합니다. - 기존 DESIGN(consult 산출물) 따르기: consult에서 DESIGN + 스타일 샘플이 이미 결정된 경우 → DESIGN 토큰/§8을 엄격히 따르며, 더 이상 스타일 방향을 묻지 않습니다 (Step 0.5에서는 승인 기준만 정렬하고, Phase 1 명확화를 반복하지 않습니다).
확신이 서지 않으면 옵션을 나열하여 사용자에게 제시합니다.
렌더링 코어 두 가지 중 선택 (다섯 번째 차원, DESIGN에 명시): 위의 네 가지 모드 외에도 렌더링 백엔드를 결정합니다 (본 스킬 기본값은 Remotion 코어; DESIGN에 명시되거나 사용자가 지정한 경우에만 HyperFrames 코어):
- Remotion 코어 (기본값): React 복잡 모션 / shotcraft 샷 카드 /
src/계층화 +Sequence+useCurrentFrame. 최고의 모션 자유도가 필요할 때 사용합니다. - HyperFrames 코어 (HeyGen 오픈소스 HTML→MP4, 선택 사항):
index.html데이터 속성 + GSAP 타임라인 (npx hyperframes init/render, 로컬 무료) → 웹페이지 작업에 더 가깝고, 내장npm run check(lint+대비+모션) 기능 제공. 에셋/BGM/자막/검증은 모두 재사용하고, 렌더링 방식만 변경합니다. 규칙은references/hyperframes-guide.md참조. - 판단: 복잡한 샷 카드(카드 뒤집기/파티클/3D) 또는 기존 Remotion 프로젝트가 있는 경우 → Remotion; 순수 HTML/GSAP 모션, 웹페이지 느낌, 내장 lint 필요 시 → HyperFrames. 동일 프로젝트에서 두 코어를 혼합하지 마십시오.
Step 0.5 — 요구 사항 정렬 + 승인 기준 (grill-me, 필수, ≤10 라운드)
grill-me 스킬을 실행하여 정렬: 한 문장 요구 사항, 화면 비율/길이/플랫폼, 자막 출처 (.srt/.vtt/구술 대본/처음부터), 모드, 스타일 방향. 반드시 네 가지 승인 기준을 산출해야 합니다:
- 구조: 카테고리/화면 비율/길이/fps
- 시각: 자막 글꼴/색상/구도가 DESIGN.md 또는 참조와 일치 (자유 모드는 "AI 느낌 없음")
- 내용: 자막 전체 문장이 모두 포함되고, 오탈자 없으며, 타임스탬프가 전체 영상을 포괄하고, 대본이 실제와 일치
- 기술: 자막 프레임 정렬 (문장 시작 및 끝 프레임에 자막 존재), still 프레임 추출 통과, MP4 렌더링 성공
10 라운드 내에 정렬되지 않으면 → 미결 항목을 기록하고 상태 그대로 빌드에 진입합니다.
Step 1 — 자막 기반 워크플로우 (핵심)
references/captions-guide.md 참조:
- 출처 라우팅: 기존 .srt/.vtt 파일이 있으면 → 직접 사용; 구술 대본.md 파일이 있으면 → 초안 .srt 작성; 처음부터 시작이면 → 먼저 구술 대본 초안을 작성한 후 .srt.
parseSrt({input})→Caption[], 빈 구간, 시간 중복, 범위 초과를 검증합니다.- 프레임 정렬:
startFrame = Math.round((startMs/1000)*fps),endFrame = Math.round((endMs/1000)*fps), 각 문장은<Sequence from={startFrame} durationInFrames={endFrame-startFrame}>로 감쌉니다. - 단어/문장 수준 강조:
createTikTokStyleCaptions→CaptionLayer컴포넌트; 중국어 전체 문장 단일 토큰 → 문장 수준으로 강등 (DESIGN.md highlightMode에서 결정). - 화면 리듬은 자막 문장 시작 startMs에 바인딩됩니다; 전체 영상
durationInFrames = round(max(endMs)/1000*fps) + trailing. - 단어 변경 후
serializeSrt로 다시 씁니다.
Step 1.5 — 음성 기반 srt 재구성 (타이밍 가정 실제 트리거, 먼저 음성 후 프레임 추출)
구술 영상에서 음성은 필수 프로세스입니다 (사용자에게 묻지 않음): TTS 생성 → ffprobe 실제 측정 → srt 재구성하여 타임라인 결정, 타이밍은 TTS 실제 측정값을 기준으로 합니다 (DESIGN §4 타이밍 가정 실제 트리거). 먼저 음성 후 프레임 추출 — Step 1 srt 정렬 후 음성 재구성으로 인해 다시 뒤집히고 이전 단계가 무효화되는 것을 방지합니다.
python scripts/media/tts_gen.py --provider edge-tts --lines lines.txt --save-dir public/audio/ --voice <voice>(기본값은 Key 없이 fallback; MiniMax 사용 가능 시 명시적으로--provider minimax로 변경, 국내 클라우드 TTS는mmx-media-pipeline.md§2 참조).- ffprobe로 각 문장의 실제 길이 측정 (
ffprobe -show_entries format=duration), 문장 사이 0.8초 호흡 간격. - srt 재구성 (
rebuild_srt.py): 각 문장 시작/끝 = 실제 측정 길이 누적 + 호흡 간격; public/captions.srt에 씁니다. - Root
SHOTS프레임 구간을 새 srt에 따라 업데이트 (round(ms/1000*fps)), 각 Sequence에<Audio src={staticFile("audio/s{n}.mp3")}>를 추가합니다. - BGM: AI 음악 생성이 필요하지 않은 경우 프로젝트 라이선스 에셋 라이브러리에서 가져옴; 프롬프트 기반 음악 생성이 필요한 경우 기본적으로 ACE-Step 로컬 생성 사용, 클라우드 음악 백엔드는 선택적 대안으로 사용. 가져온 후 전체 길이로 자르고 (ffmpeg
-t비디오 초), 볼륨을 낮춰 음성을 방해하지 않도록 합니다 (0.22-0.3). - 장면 프레임 예산 + 타이밍 사전 검사 ("핵심 모션 누락" 방지, 실제 3번 밟음): rebuild_srt가 출력하는 각 문장의
to-from이 해당 장면의 프레임 예산입니다. 샷 카드/데이터 모션을 작성하기 전에 먼저 확인: 카드 내부 마지막 키프레임 ≤ 장면 예산, 그렇지 않으면 카드 타이밍을 압축 (검증 단계에서 발견되지 않도록) ——- 짧은 문장 (2-3s≈60-90f): 도장 찍기/원 스캔/주기적 점등 등 끝부분 모션이 예산을 초과하기 가장 쉬움 (S2 빨간 도장 원래 70-88f, 68f 문장 초과 → 55-65f로 압축; S6 주기적 점등 원래 46-70, 70f 초과 → 46-64로 압축; S9 5바퀴 스캔 원래 136f, 128f 문장 초과 → 108f로 압축).
- 규칙:
카드 마지막 키프레임 = 시작 + 캐스케이드 총 길이 + 끝부분 정지, 반드시 ≤ 문장 예산; 초과 시 비율에 따라 stagger/단일 시간 압축, 끝부분 정지는 ≥4f 유지.
Step 2 — 참조 찾기
사용자가 제공한 참조가 최우선 → video-real-library.md → 자유 디자인. 참조가 있으면 "모션 효과 분해법" 사용 (참조 → 전체 모션 효과 라이브러리 컴포넌트 조합, motion-patterns-video.md 참조).
Step 3 — 역프롬프트 (비디오 버전 요약, 유일한 하드 제약)
- 하나의 자막 리듬만 전체에 사용하지 않음 (모든 문장 동일 길이, 단어 수준 강조 차별 없이 화면에 깜빡임)
- 모든 장면이 중앙에 동일한 구도, 전체가 fade만 있거나 하드 컷만 있는 경우 없음
- 균일하게 화면을 자르지 않음 (매 N초마다 자르기 = 호흡감 없음)
- 기본 자주색-남색 그라데이션 배경 사용하지 않음, 흔한 AI 글꼴 사용하지 않음
- 공허한 내레이션 자막 없음 ("시청해 주셔서 감사합니다", "시작해 보겠습니다")
- 모션 효과는 반드시 적용: 각 장면에 최소한 등장 모션 효과 + 장면 간 전환
- 여기까지.
Step 4 — 빌드 (기술적 기준)
references/remotion-build-guide.md 참조:
- 프로젝트 초기화:
_dev/remotion-tutorial에서 뼈대 복사 +npm i @remotion/captions@<정렬 버전>+ Chrome 경로 유지. - 전체 모션 효과 라이브러리에서 컴포넌트 import (
작업대/비디오/_모션효과라이브러리/) 또는src/components/로 복사. - 샷 카드 선택적 통합: DESIGN §8.2에서 카드 선택 시
remotion-shared/video-shots-spec.md의 "샷 카드 통합 단계"에 따라 실행 ([copy]/[참고]의도 표시 포함); 중국어 영상은 기본적으로 참고 방식 사용. - src 계층화: Root.tsx / theme.ts / captions.ts / components/.
- 결정론적 애니메이션 (
useCurrentFrame/interpolate/spring,Math.random및 브라우저 타이머 금지). - DESIGN.md가 있으면 토큰을 엄격히 따름.
- 에셋은
references/video-image-spec.md에 따라 교차 하네스 라우팅 (Codex image_gen / GPT 프롬프트 왕복 / 사용자 제공 이미지). - 에셋 생성 후 개요 재검증 (필수): 에셋 생성 완료 후, DESIGN §8 개요 기준으로 문장별 검증——①이미지가 해당 문장의 의미/레이아웃과 일치하는지 (vision 평가 적합도, <7이면 재생성 또는 프롬프트 조정) ②큰 글자 키워드가 장면 이미지와 조화를 이루고, 가리지 않는지 ③계층 z 순서가 개요 설계와 일치하는지. 불일치 시 → 키워드 조정 또는 에셋 재생성, "생성 즉시 사용" 금지; 각 화면 요소에 대해 여러 후보 중 최적 선택.
Step 5 — 검증 폐쇄 (grill-me 노드 테이블)
| 노드 | 트리거 | 최대 라운드 수 | 종료 조건 |
|---|---|---|---|
| 시작 | Step 0.5 | 10 라운드 | 승인 기준 최종 확정 |
| 수정 | 사용자 수정 요청 | 5 라운드/회 | 무엇을 수정할지 명확하고, 각 라운드마다 승인 기준 대조 |
| 최종 | 인도 전 | 4 라운드 | 승인 기준 항목별 통과 |
하드 검증 작업 (먼저 프레임 추출 후 렌더링, 긴 렌더링 시간 낭비 방지): 계층적 정량화 (4계층, DESIGN §8.2에서 증명 시점 키프레임 = 문장 시작/중간/0.82 최종 상태에서 수행):
- 계층1 배경 이미지 (장면 이미지 자체):
python scripts/media/layout_calc.py <장면이미지>—— 구도/여백/권장 텍스트 영역 (이미지 여백 구조에 따라 빈 공간 찾기, 상단이 깨끗해야 한다는 강제 없음; 상단 침범 시 → 텍스트를text_zone권장 영역으로 이동, 또는 더 깨끗한 이미지 재생성); - 계층2 배경 이미지+텍스트 (still 텍스트 포함): layout_calc 텍스트 배치 + frame_judge
--subtitle-hex실제 WCAG 대비 (큰 텍스트≥3.0/본문≥4.5); - 계층3 +모션 효과 (연속 프레임): 프레임 차이/연속 프레임 vision으로 모션 효과 실제 발생 판단 + 모션 효과가 장면과 겹치지 않음 (카드가 완전한 화면이면 장면 이미지 오버레이로 간주하지 않음, 시각 모드는 §8.2 참조);
- 계층4 전체 (완성 영상): frame_judge 전체 영상 +
audio_sync_check.py오디오-비디오 동기화 + 오버레이 검증 + 4가지 스킬 점수 + 동작 증명.
npx remotion compositions로 실제 ID 확인;- still 프레임 3-5장 추출 (문장 시작/문장 끝/전환 프레임) —— "최종 상태 프레임" 추출, 모션 효과 중간 프레임 아님 (실제 교훈 2026-08-17): 추출 프레임은 동작 완료 후 프레임 선택 (0.82 최종 상태 / 끝부분 정지 후), 모션 진행 중 프레임 추출 금지 — 중간 프레임은 vision/사람의 눈이 "누락/정적/검은 프레임"으로 오판하게 함 (S2 카드 뒤집기 중간에 빨간 도장 없음, S6 주행 거리계 롤링 중 주기적 점 없음, S7 타임라인 중간에 인물 샷 없음 모두 추출 프레임 시점 오류, 최종 상태 프레임 추출이 올바름). 자막이 존재하고 정렬되어 있으며, 구도가 깨지지 않음;
- 자막 정렬 검증: 문장 시작 프레임에 자막이 나타나고, 문장 끝 프레임에서 미리 사라지지 않음;
- 자동화 하드 지표 판단: 추출 프레임 후
python scripts/media/frame_judge.py preview/*.png --subtitle-hex <DESIGN 자막 색상, 예: E8833A> --subtitle-threshold 3.0 --text-bg-hex <텍스트 캡슐 배경, 예: F2F0EB>실행 (--text-region 텍스트가 구석에 있을 때 실제 위치 tl/tr/bl/br/center 전달, 하단 오판 방지; --text-bg-hex 알려진 캡슐 배경이면 직접 자막 대비 계산, 최빈값 건너뜀 — 최빈값은 장면 색상을 잡아내므로 텍스트가 장면 위에 있을 때 부정확; 큰 텍스트 장면 임계값 3.0 / 본문 4.5; 하나라도 FAIL이면 수정 트리거); 선택 사항으로pip install iqa-pytorch후 NIMA 미학 점수 추가 (>6.5는 참조 기록); 지표 임계값은references/video-quality-metrics.md참조; 어두운 디자인 밝기 FAIL은 차단하지 않음 (메트릭스 어두운 디자인 설명 참조, 대비 기준); - 각 추출 프레임을 체크리스트로 대조 검증 (약점 <3이면 수정 트리거):
- 구도: ≥2 시각적 요소, 모든 장면 중앙 위치 금지, 계층 z 순서 올바름 (bg/mid/fg)
- 자막: 존재하고 정렬, 가독성 (대비 ≥3:1), 깨진 텍스트 없음
- 전환: 문장 사이에 전환/등장 모션 효과 존재, 베어 컷 또는 정적 아님
- 에셋: AI 오류 텍스트 없음, 계층 §8.1 준수, 투명 오버레이 깔끔
- 모션 효과: 장면당 최소 2가지 모션 효과 존재 (에셋 등장/퇴장 + 글꼴 + 배경 중 3택2), 배경에 모션 효과 포함
- AI 느낌 없음:
video-anti-slop.md역프롬프트 대조
- 오버레이 검증 + 시각 모드 확인 (paper-collage-video spatial-contract 참조, 2026-08-16 확장): 추출 프레임으로 문장별 검증——①큰 글자 캡슐이 예약 영역 (상단 여백)에 위치 ②주체가 큰 글자/자막 영역을 압박하지 않음 ③전경이 중후경 주체를 가리지 않음 ④카드 모션 효과와 장면 이미지가 겹치지 않음: 완전한 화면 카드 (주행 거리계/계기판/파티클 기둥/집중 조명 어두운 장면)는 절대 장면 이미지 오버레이로 간주하지 않음 (시각 모드 3택1, DESIGN §8.2 참조) ⑤모션 효과 의미가 문장 의미와 일치 (vision이 파티클 기둥/스캔 라이트/디지털 롤링이 해당 장면에서 무엇을 표현하는지, 구술 의미와 일치하는지 판단, 의미 불명확 시 수정 트리거). 오버레이/의미 불명확 → 시각 모드 변경 또는 불필요한 카드 제거.
- 4가지 스킬 심사 하드 게이트 (하나의 게이트라도 통과하지 못하면 수정, 참조 아님): 하위 에이전트가 독립적으로 실행 (hallmark/taste는 독립 에이전트가 수행, 주 모델이 자체 심사/통과 금지) ——
taste-skillPre-Flight (40+ 항목 취향 검사)hallmark audit(57 게이트 AI slop 방지)ui-ux-pro-max(UX 가이드라인: 가독성/계층/일관성)open-design/anti-ai-slop("7대 죄악" 템플릿 제거) 추출 프레임/완성 영상 대조 심사, 통과 항목 수로 점수 계산 후 통과 (심사 보완, 자체 심사/통과 방지): hallmark 57 게이트 통과 ≥90% (≥51개)여야 통과, taste 40+ 항목 통과 ≥85%여야 통과, ui-ux-pro-max / open-design 핵심 항목 모두 통과; 통과하지 못한 항목을 나열하여 수정 트리거, 모든 게이트 통과 후에야 render 인도.
npx remotion render <id> out/final.mp4;- 동작 증명 시점 (paper-collage-video proof moments 참조): DESIGN §8.2에 따라 각 문장 증명 시점 (문장 시작/중간/0.82 최종 상태)에서 프레임 추출 + 동작 유형 실제 발생 검증 (등장 완료/지속적 움직임/최종 상태 정지);
ffmpeg -vf "fps=4"로 연속 프레임 추출 → vision이 DESIGN에 따라 동작 발생 판단——팬 한 프레임 정적 프레임 ≠ 동작 증명 (파티클/집중 조명/디지털은 연속 프레임으로 확인 필요); 전환 부드러움/등장 및 퇴장 점프 없음 (video-quality-metrics §4.6); - 오디오-비디오 동기화 확인 (구술 영상 축, 심사 보완): 완성 영상에 대해
python scripts/media/audio_sync_check.py out/final.mp4 public/captions.srt실행——각 srt 문장 시작 ±0.15s 내에 음성 소리 있어야 함 (RMS≥0.01), 문장 시작 시 정적 = 음성 어긋남/누락/문장 끝 잘림 → 수정; - 승인 기준 항목별 대조 확인 → STATUS PASS/FAIL/BLOCKED, NEXT_OWNER.
레드라인
- 자막 기반은 하드 제약: captions.srt가 존재하면 유일한 타임라인 소스이며, 길이는 이로부터 파생됩니다.
- 먼저 프레임 추출 후 렌더링: still이 통과하지 않으면 전체 영상을 render하지 않습니다.
- 샷 카드 참고는 필수 아님: DESIGN §8에서 카드를 선택하면 통합 (shotcraft/demos/{카테고리}/{카드}를 copy하여 프로젝트에 적용), 카드를 선택하지 않았거나 중국어 영상 참고 방식은 누락으로 간주하지 않음; 카드 미통합은 BLOCKED가 아님.
- 에셋은 실제 이미지 생성으로, SVG 생성 금지: 주체 에셋은 우선 Codex 또는 이미 구성된 이미지 백엔드 사용, 투명은
--transparent/remove_white_bg.py사용. - 프로그래매틱 데이터 카드는 우선 shotcraft 전체 버전을 실제로 copy, 축소 SVG 수동 작성 금지 (실제 교훈 2026-08-17): 자체 제작 데이터 카드 (계기판/링/주행 거리계/차트)를 수동으로 축소 SVG (원시 circle/line/path, 눈금/빨간 영역/허브/글로우 디테일 없음)로 작성하면 품질이 낮아짐 (S9 ring 수동 버전 mmx vision 3.5/10, 실제 shotcraft NeedleSweepSelftest 전체 디테일 copy 후 8.5/10). 데이터 카드는 무조건 shotcraft demos/data, typography에서 실제로 전체 버전 copy (눈금/주/부/글로우/계기판 허브/포인터 끝 등 모든 디테일 포함), 그런 다음 색상 스킨만 리매핑; 단순 장식 (배경 광점/하단 레일)만 프로그래매틱하게 그리기.
- 음성 기반 srt 재구성은 필수 (Step 1.5, 먼저 음성 후 프레임 추출): 구술 영상에서 Step 1.5는 반드시 TTS→ffprobe→srt 재구성하여 타임라인 결정 (타이밍은 TTS 실제 측정값 기준, DESIGN §4), 프레임 추출 검증은 음성 재구성 srt 이후에 수행, 사용자에게 묻지 않음.
- 디자인 방향 변경 금지: DESIGN.md에서 정해졌으면 그대로 수행; 방향 변경이 필요하면 remotion-consult로 돌아감.
- 허위 정보 금지: 자막/데이터 허위 구성 금지.
참조 파일
| 파일 | 읽는 시기 |
|---|---|
references/captions-guide.md | Step 1 자막 타임스탬프 정렬 (핵심) |
references/remotion-build-guide.md | Step 4 엔지니어링 규범 |
references/motion-patterns-video.md | Step 2/5 모션 효과 구현 |
references/video-image-spec.md | Step 4 에셋 라우팅 |
references/codex-imagegen.md | Step 4 Codex로 에셋 생성 시 |
references/mmx-media-pipeline.md | Step 4 미디어 백엔드 (MiniMax 선택 사항 + TTS/BGM 폴백 체인 + 알려진 함정) |
references/video-quality-metrics.md | Step 5 자동화 판별 지표 (frame_judge.py + VMAF/NIMA/ASL 임계값) |
references/hyperframes-guide.md | Step 0 렌더링 코어=HyperFrames 시: HTML 데이터 속성/GSAP/check 규칙 + CLI |
references/hyperframes-blocks.md | HyperFrames 렌더링 코어 시 모션 효과 블록 선택: registry blocks 154개를 카테고리별로 빠르게 조회 (shotcraft와 동등) |
.claude/skills/remotion-shared/video-anti-slop.md | Step 3 역프롬프트 기준선 |
.claude/skills/remotion-shared/video-tokens-spec.md | theme.ts 작성 시 |
.claude/skills/remotion-shared/categories/{카테고리}/motion-list.md | 모션 효과 조합 선택 |
.claude/skills/remotion-shared/video-shots-spec.md | 샷 레시피 카드 시스템 + 권위 있는 기법 (빌드 시 샷 카드 선택: demos/{카테고리}/{카드}를 프로젝트로 copy) |
.claude/skills/remotion-shared/aesthetic-judgment/ | Step 5 검증: 촬영/편집/프론트엔드 타이포그래피 6축 판별 (<3이면 수정 트리거) |
.claude/skills/ui-ux-pro-max/SKILL.md | 디자인 규칙 엔진: Step 4 빌드 시 UX 가이드라인 + 우선순위 확인 |
.claude/skills/taste-skill/SKILL.md | Step 5 최종 검사: Pre-Flight 40+ 항목 (인도 전 자체 점검) |
.claude/skills/hallmark/SKILL.md | Step 5 디자인 심사: 57 게이트 / hallmark audit (검증 전) |
자료실/AI도구/design-skills/open-design/craft/anti-ai-slop.md | Step 3 템플릿 제거 규칙 ("7대 죄악") + 151 디자인 시스템 대안 |
.claude/skills/design-shared/review-panel.md | 심사 패널: agency-agents 관점 + 디자인 시스템 라이브러리/미적 참조 라이브러리 판단 기준 (Step 5 검증 점수) |
출력 및 마무리
STATUS: PASS | FAIL | BLOCKED
산출물: out/final.mp4 경로 + preview/ 프레임 추출 경로
승인 기준: 항목별 달성 / 미달성 / 미결
NEXT_OWNER: user (효과 확인) | remotion-consult (방향 변경)
확인 필요: 미결 사항