Communitygithub.com

TimeCraker/video-motion

Remotion을 사용하여 비디오 주석, 기술 시각화, 인트로 장면 및 썸네일을 제작하고, 시리즈 시각 템플릿을 적용하며, 필요에 따라 Lottie, 3D 및 공식 전문 가이드를 통합합니다. 비디오 그래픽 및 모션 효과 제작에 적합하며, 인트로는 조립 워크플로우에 의해 조정되고, 기존 웹 애니메이션은 web-capture을 통해 처리됩니다.

video-motion란 무엇인가요?

이 스킬은 Remotion을 기반으로 한 비디오 모션 그래픽 제작 도구로, 데이터 기반 동적 장면, 주석 오버레이, 인트로 아웃트로 및 썸네일 제작을 지원합니다. `src/cues.ts` 파일을 중앙 데이터 계약으로 사용하여 모든 좌표, 시간 및 텍스트를 선언하고, FX 컴포넌트는 하드코딩 없이 cues 파일 변경 후 단일 명령으로 비디오를 다시 렌더링할 수 있습니다. Lottie, 3D, 지도 등 다양한 시각화 유형을 위한 전문화된 브랜치를 제공하며, 시리즈 전체의 일관성을 유지하기 위해 토큰, 폰트, 장면, 자막, 썸네일 및 오디오 트랙을 프로젝트 전반에 걸쳐 통일합니다. 주요 플랫폼은 Claude Code, Cursor, Codex와 같은 AI 에이전트 환경이며, 명령줄 인터페이스를 통해 작동합니다. 또한 상세한 4단계 검증 프로세스(렌더링 코드 확인, 프레임 이미지 검사, 연속 재생 및 오디오 확인)를 포함하여 최종 출력물의 품질을 보장합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/TimeCraker/vibe-studio/tree/HEAD/skills/video-motion

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

video-motion — 비디오 배경에 모션 효과 오버레이 (Remotion)

설계가 곧 코드: 좌표 / 시간 / 텍스트는 전부 src/cues.ts (데이터 계약, 필드는 변경 불가)에 선언되며, fx 컴포넌트는 하드코딩이 없습니다. cues를 변경하고 단일 명령을 다시 실행하면 전체 비디오가 재생성됩니다. 세 가지 모션 효과 레이어: 자막 SubtitleTrack / 데이터 막대 DataBars / 원형 강조 표시 Spotlight (circle / arrow / box).

기술 다이어그램, 프로세스/데이터 화면, Lottie, 3D, 지도 또는 Studio 파라미터 편집은 전문 시각 제작에 따라 관련 브랜치에서 참조하세요. 감독이 콘텐츠와 시각적 방향을 제공하면, 제작 모듈이 실제 프로젝트 자산/코드 및 렌더링 증거를 제공합니다. 현재 컴포넌트, 타입 및 잠금 엔진 인터페이스가 우선시됩니다.

시리즈 비디오는 시리즈 일관성에 따라 섹션 규칙을 프로젝트의 토큰, 폰트, 장면, 자막, 썸네일 및 실제 오디오 트랙에 적용합니다. 실제 입력 버전을 재사용하고 이번 콘텐츠로 렌더링하여 대조하며, 단일 테마 값을 변경하는 것을 전체 비디오가 통일되었다고 간주하지 않습니다. 제품 데모는 실제 녹화/캡처 자료에 주석을 오버레이하며, 이후의 마우스 또는 원형 표시는 실제 동작과 결과와 일치해야 합니다.

Step 1 · 스크립트 디자인 (자료를 보고, 화면을 추측하지 마세요)

  1. 프레임을 추출하여 자료 보기: npx remotion still remotion/index.ts FootageOverlay <출력>/f-<n>.png --frame=<n>, 샷과 주요 변화에 따라 프레임 선택; 실제 생성된 이미지의 절대 경로를 사용하여 이미지 읽기
  2. src/cues.ts 모션 효과 스크립트 작성:
    • 자막은 화면을 설명: 시청자가 현재 보고 있는 것을 말하고, 의미와 읽기 속도에 따라 분할
    • 원형 표시는 실제 대상을 가리킴: circle / arrow / box가 화면에 실제로 존재하고 주목할 가치가 있는 요소를 가리키며, 좌표는 먼저 프레임 추출을 통해 착지점 확인
    • 숫자는 출처가 명확해야 함: 데이터 막대 값은 실제 출처(화면 HUD / 결제 패널 / 백엔드 데이터)에서 가져오고, 가져올 수 없으면 자막에 "데모 데이터" 명시
  3. 해석을 대상과 관련된 세부 사항에 연결: HUD, 채팅, 프롬프트 및 작업은 증거로 사용될 수 있지만, 설명에 필요한 내용만 표시; 큐 밀도를 위해 전체 화면을 채우지 않음

Step 2 · 엔지니어링 및 사양 (자료에 따라 적응)

  1. templates/remotion-app/를 작업 디렉토리에 복사하고 npm install 실행 (Remotion 서브 패키지는 동시에 설치해야 하며, 버전이 엄격하게 연동됨); 설치 후 npm run typecheck 실행 (esbuild 관용이 타입 클린을 의미하지 않음, tsc 통과해야 함; 템플릿에 typescript devDependency 포함되어 있어 설치 후 바로 실행 가능)
  2. 네이티브 사양: node scripts/probe-footage.mjs <자료 경로> 명령어는 ffprobe를 사용하여 src/footage-params.ts를 생성합니다. 출력 해상도 / 프레임 속도는 자료에 따라 유동적이며, 하드코딩되지 않습니다. 자료를 변경하면 이 스크립트를 다시 실행하기만 하면 됩니다.
  3. 자료는 skill 디렉토리에 포함되지 않음: 렌더링 시 --public-dir <자료 디렉토리> 사용 (staticFile이 프로젝트 자료 라이브러리를 직접 읽음); 인자를 전달하기 어려운 경우에만 자료를 public/footage.mp4로 복사
  4. cues는 1080p 디자인 좌표로 작성하며, FootageOverlay에는 transformOrigin: "top left"가 내장되어 있어 전체 크기가 임의의 캔버스에 맞게 조정됩니다. 해상도를 변경해도 cues를 수정할 필요가 없으며, 모션 효과 위치가 흐트러지지 않습니다.

Step 3 · 생성 (단일 명령)

렌더링 전에 먼저 검증: node scripts/verify-cues.mjs (deck 자막은 src/deck-cues.ts 파라미터 사용), 오류가 0이어야만 렌더링 진행; 총 시간 경고는 알림만 하고 차단하지 않음.

cd <remotion-app>
npx remotion render remotion/index.ts FootageOverlay <저장소>/products/<프로젝트명>/demo.mp4 --crf=16 --public-dir <자료 디렉토리>

결과물은 저장소 products/<프로젝트명>/ 디렉토리에 저장 (디렉토리 규칙: skill은 순수 도구이므로 결과물이 skill 내에 남지 않음; 다른 저장소에서 사용 시 해당 프로젝트 루트 output/<skill 이름>/에 저장); --crf=16은 고품질. 대용량 자료 렌더링은 백그라운드에서 실행 (1440p60 × 30s 약 10분 소요), 종료 코드 + ffprobe로 검증하며, 진행률 표시줄에 의존하지 않음.

Step 4 · 3단계 검증 (필수, 생략 불가)

① 프로그램: 렌더링 종료 코드 0; npx remotion compositions remotion/index.ts가 출력한 durationInFrames / 너비 / 높이 / fps가 자료 메타데이터와 일치; npx remotion still로 주요 자막, 데이터 변화 및 전환에서 대표 프레임 선택 — 각 자막의 start+0.3s / end-0.3s, 데이터 막대 t-0.3s / t+1.5s, 원형 강조 표시 t+0.5s / t+ttl+0.3s (compositions이 출력한 실제 fps로 프레임 번호 변환).

② 이미지 읽기: 실제 PNG를 읽어 프레임별로 확인: 등장/사라짐 시간과 텍스트, 막대 높이 비율과 값 레이블, 원형 강조 표시 유형과 위치, 배경에 깨짐/늘어짐 없음, 전체 프레임에 깨진 문자 없음 (중국어는 Microsoft YaHei 폴백 사용). 문제가 있으면 해당 소스 파일에 기록하고, 재렌더링 후 원래 문제와 인접 연결을 확인; 판단하거나 수정할 수 없는 차단 문제가 있으면 명확히 보고.

③ 연속 재생 및 청취: 프레임 추출만으로는 리듬과 동기화를 증명할 수 없으므로, media-qc의 시청각 방법을 사용하여 실제 클립과 오디오 트랙을 확인하고, 검사 범위를 기록; 사용자가 최종 완성본을 검토.

Step 5 · 전달

보고서: 완성본 경로 및 크기 / 해상도 프레임 속도 (=자료 네이티브) / 3단계 검증 결과 (프레임 추출 확인표 포함) / cues.ts 위치 (재실행 가능). 결과물과 mp4는 절대 git에 포함되지 않음.

PPT 페이지별 비디오 제작 (DeckVideo, 두 번째 비디오 유형)

단일 엔진, 두 가지 비디오 유형: 위의 Steps는 "비디오 배경에 모션 효과 오버레이"이고, 이 섹션은 "PPT 페이지별" — pptx 페이지 이미지 + 페이지별 음성 해설을 직접 비디오로 출력하며, 페이지 시간은 음성 해설의 실제 길이에 따라 결정되고, 자막은 분할 스크립트의 타임라인에 따라 나타납니다.

  1. pptx 및 분할 스크립트: ppt skill의 결과물 pptx; 내레이션 분할 스크립트 script.json 작성, ref는 "page N" (N=페이지 번호), 먼저 python skills/narration/templates/verify_narration.py <script.json> 통과 (모두 통과). 각 세그먼트는 ≤20자 (자막 한 줄 약은 세그먼트 텍스트를 직접 표시), 페이지 내 여러 세그먼트는 마침표로 연결하여 해당 페이지의 내레이션으로 사용
  2. 페이지 이미지: python scripts/extract_pages.py <in.pptx> public/deck/pages — COM을 통해 PDF로 변환 후 fitz로 200dpi 렌더링, p-<N>.png 출력 (2667×1500, 캔버스 contain으로 채움)
  3. 음성 해설: 테스트는 powershell -File scripts/make_deck_audio.ps1 <script.json> public/deck/audio 실행 (SAPI Huihui가 페이지별로 page-N.wav 출력); 공식 프로세스는 사람이 CapCut에서 페이지별로 음성 해설을 녹음하고, 동일한 이름 page-N.wav로 동일 디렉토리에 저장, 다운스트림에 영향 없음
  4. 연결 및 렌더링: node scripts/build-deck-params.mjs <script.json> public/deck가 src/deck-params.ts + src/deck-cues.ts를 생성 (페이지 시작점 / 총 길이 / 자막 시간은 모두 파생 값, 수동 수정 금지) → npx remotion render remotion/index.ts DeckVideo <저장소>/products/<프로젝트명>/deck.mp4 --crf=16
  5. 3단계 검증: Step 4의 3단계와 동일 (프로그램 ffprobe / compositions 대조 + 프레임 추출 이미지 확인 + 사용자 시청). L2 프레임 추출 핵심: 각 페이지 첫 프레임+0.3s에서 페이지 순서 확인; 오버랩 중간점은 다음 페이지 start+0.25s (오버랩 끝은 페이지 창 끝, 0.5s 크로스 디졸브); 자막 start+0.3s / end+0.3s에서 텍스트 및 퇴장 확인. 페이지 첫 프레임+0.3s에서 spring 페이드인이 완료되지 않아 전체 프레임이 약간 회색인 것은 전환 중간 상태이지 결함이 아님

페이지 이미지 및 음성 해설은 public/deck/에 저장 (.gitignore가 이미 포함되어 있어 git에 들어가지 않음); 캔버스 1920×1080@30은 build-deck-params.mjs 상단에 상수로 정의되어 있으며, 두 줄만 수정하면 4K가 됨.

장면화 비디오 v2→v3 품질 공정 (scene-kit 직접 렌더링, 세 번째 비디오 유형)

PPT 페이지별 비디오의 업그레이드 라인: 화면 주체가 "PPT 페이지 이미지"에서 Remotion 컴포넌트가 직접 렌더링하는 모션 효과 장면 (src/scene-kit/ 24개 컴포넌트)으로 변경되며, 페이지 시간/오디오/자막 메커니즘은 deck-params 파생 체인을 그대로 사용합니다. "밋밋함" 또는 "저품질" 판단은 docs/2026-08-30-motion-grammar.md를 참조; 이 섹션은 품질 공정의 하드 룰입니다.

품질 기준

docs/2026-08-30-motion-grammar.md의 콘텐츠 유형에 따라 검수 방식을 선택합니다. 토큰 및 브랜드 연속성을 유지; 화면은 실제 주체와 읽을 수 있는 정보를 중심으로 하며, 움직임은 변화를 설명합니다. 여백, 정지 상태 및 각 샷의 지원 정보량은 샷의 목표에 따라 판단하며, 고정 할당량이나 정적 PPT 거부를 적용하지 않습니다.

먼저 content-director가 사실 출처, 스토리보드 및 아트 브리핑을 제공한 다음, 대표 프레임과 짧은 샘플을 확인합니다. 구조 다이어그램은 SVG를 우선, 실제 인터페이스는 스크린샷/녹화 사용, 일러스트레이션이 필요할 때 사용 가능한 imagegen 도구를 연결하고 자산을 등록합니다. 새로운 ArtLayer 및 더 많은 모션 효과가 자동으로 아트 품질 통과를 의미하지는 않습니다.

장면 설계 방법 (일반적, 사전 설정된 답변 없음)

먼저 assets/patterns.md 페이지별 솔루션 라이브러리를 확인합니다. 유사한 상황에 이미 검증된 PAT 항목이 있으면 이를 사용하여 파라미터를 수정 (상황 → 레이아웃 → 컴포넌트 → 함정 → 참조 프레임이 모두 항목에 있음), 없으면 처음부터 설계합니다. 각 페이지의 카피는 먼저 콘텐츠 유형 (내러티브痛点/기능 데모/데이터 설득/프로세스 설명/개념/행동 촉구 6가지 유형)을 결정한 다음, "주체는 카피 콘텐츠에 의해 결정, 동일 유형의 여러 페이지는 동일한 시각적 솔루션을 반복하지 않음, 배경군은 콘텐츠 분위기를 지원"의 세 가지 규칙에 따라 주체 형식과 컴포넌트 조합을 결정합니다. 작업 시작 전에 설계표를 생성 (각 페이지: 카피 요약 → 콘텐츠 유형 → 주체 형식 → 배경군 → 컴포넌트 조합 → 이유 → 화면 정보 패키지 항목별 + 출처 → 주체 주석), 설계표는 사전 검토를 받아야 하며, 통과해야 코드 작성; 지원 정보는 항목별로 출처 표시 (내레이션 스크립트/프로젝트 문서/자료에서 볼 수 있는 내용).

세 가지 하드 레슨 (규칙으로 작성)

  1. 완료 상태에서 읽기 위한 일시 정지 허용: 채팅, 차트 또는 프로세스가 상태 변화를 표시해야 할 때 기존 컴포넌트 사용; 정지 샷은 정보와 리듬에 따라 판단하며, 검사 결과를 위해 장식 모션 효과를 강요하지 않음.
  2. 래핑 컴포넌트는 반드시 명시적으로 width를 전달해야 함: 새 컨테이너가 이전 컴포넌트를 감쌀 때 width가 없으면 블록 레벨 요소가 부모 컨테이너를 채움 (일러스트레이션이 제목을 덮음, 휴대폰 케이스가 700px 너비로 늘어남, 두 번 모두 동일한 근본 원인); 래핑 컨테이너는 항상 style={{ width, ...style }} 사용.
  3. 긴 스크린샷은 먼저 공백률을 확인한 후 솔루션 결정: 긴 스크린샷을 받으면 먼저 행별로 std/공백 비율 계산 (PIL 스크립트), 지연 로딩으로 스크린샷에 렌더링되지 않은 "빈 긴 이미지"는 스크롤 시 바로 죽음 — 먼저 클로즈업 자르기, 자료 수정 후 다시 스크롤로 전환.

MG 무기고 (S0-S6, 완성본 품질의 주력 탄약)

템플릿에는 전체 무기 세트가 포함되어 있으며, 각 컴포넌트의 구체적인 사용법은 assets/component-catalog.md를 참조 (scene-kit 24개 컴포넌트 / entrance-kit 9개 동사 / vendor 커뮤니티 선정 / 폰트), 여기서는 절대 규칙만 기록:

  • 버전 절대 규칙: 모든 @remotion/*은 정확히 동일한 버전이어야 함 (예: 4.0.533, ^ 없음) — 버전 불일치는 Remotion의 하드 오류이며 경고가 아님; 새 패키지를 추가하려면 먼저 기존 버전에 맞춤 (check-docs의 3.7항목이 감시, 어긋나면 빨간불)
  • 4.0.533 API 사실 (문서/기억과 차이 있음, 실제 테스트 완료; 4.0.518→4.0.533 업그레이드는 still 기준 PSNR 전체 inf 대조, API 형태 변경 없음): evolvePath는 클리핑되지 않은 path에 대한 dash 속성 반환; interpolatePath(value, from, to)는 세 개의 독립 파라미터; fitText는 withinWidth만 받고 {fontSize} 객체 반환; 중국어 여러 줄은 fitTextOnNLines 사용 불가 (공백으로 단어 분할); parseSrt는 {input} 객체를 받고 (원시 문자열은 undefined.split 오류), {captions:[{text,startMs,endMs}]} 밀리초 단위 반환
  • transform 래핑 함정 (S6 이중 함정 기록): transform이 있는 래핑 동사 (CameraPush/SlideGroup/TextBreath/BlurTrail)는 직접 position:absolute 서브트리를 감싸면 안 됨 — transform 요소는 absolute 자손의 containing block이 되어 흐름 내 높이가 0이 되고 내용물이 상단으로 넘침. 컴포넌트는 이미 자체 충분 (CameraPush 루트 inset 0, BlurTrail 메인 레이어 흐름 내), 사용 시에도 크기가 없는 absolute 부모 내에서 직접 래핑하지 않도록 주의
  • 공식 <Trail>/TransitionSeries 의미: Trail 루트는 AbsoluteFill (페이지 수준 오버레이 의미), 요소 수준 잔상은 scene-kit의 BlurTrail 사용 (이미 relative화됨); TransitionSeries 전환은 인접 페이지 길이를 소비, 완성 엔진은 기본적으로 전환 없음 (Series 하드 컷) + 페이지 내 동사
  • vendor 규율: copy-paste로 저장소에 입고, npm 의존성 아님; 업그레이드 = 다시 가져와서 재처리; 4가지 규율은 템플릿 src/vendor/README.md 참조
  • Lottie 자산 흐름: 무료 상업용 JSON은 assets/lottie/로 이동 (README 3개 필드 등록) → 사용 시 프로젝트 public/으로 복사 → LottieLayer src에서 참조; 인테이크 시 표현식이 포함된 JSON은 금지 (렌더링 불확실)
  • 복잡한 효과 예산: ShutterBlur의 samples 및 BlurTrail의 layers는 렌더링 비용을 증가시킴; ThreeStage는 장면과 시스템 차이에 따라 실제 측정. 먼저 대표 프레임/짧은 클립을 렌더링한 후 규모를 결정하며, 전체 비디오에 고정 샷 할당량을 설정하지 않음.

검수 절차 (4단계)

L1 프로그램 (렌더링 종료 코드, 전체 로그 캡처, 파이프 테일 금지; ffprobe = compositions 프레임 수 대조); L2 프레임 추출 (리스크에 따라 진입/안정된 풀샷/정보 클로즈업/전환 및 자막 대표 프레임 선택, 실제 이미지 확인; 확대는 세부 사항 확인에만 사용, 페이지당 고정 수량 없음); L2.5 무음 테스트 (페이지별 블라인드 답변 주제); L3 보고서 (기술 범위, 키 프레임 증거, 수동 검토 항목 및 필요 시 이전/이후 대조 포함). 일반적인 가치가 있는 컴포넌트, 토큰 및 레이아웃이 확인되면 자산 환류 규칙에 따라 템플릿/등록부에 다시 기록; 프로젝트 전용 콘텐츠는 프로젝트 내에 유지하며, 새로운 경험이 없으면 추가 작업 티켓을 생성하지 않음. 렌더링 명령은 DeckVideo와 동일 (composition을 장면화 컴포넌트로 변경, 예: DeckVideoV2), 썸네일은 npx remotion still로 이미지 생성 (still 프레임 번호는 진입 spring 길이를 고려해야 함).

썸네일 이미지 출력 (Cover, 네 번째 결과물)

비디오를 렌더링하지 않고 한 프레임을 렌더링: 단일 명령으로 1920×1080 썸네일 PNG를 생성하며, 비디오 게시 시 첨부 이미지로 사용합니다.

  1. props: products/<프로젝트명>/cover-<이름>.json에 { title, subtitle?, badge?, bg?, preset } 작성. preset ∈ photo (bg 이미지 전체 채움 + 하단 55% 검정 그라데이션 마스크로 대비 보장) / dark (어두운 그라데이션, 기본값) / clean (밝은 배경 + 상단 미세 라인); bg는 remotion-app public/ 디렉토리 내의 상대 경로. subtitle 생략 시 렌더링되지 않음; badge 생략 시 ASTERFORGE 브랜드 각인으로 대체
  2. 렌더링: npx remotion still src/cover-index.ts Cover <출력>.png --props=<json 파일 경로> (독립적인 진입점으로 Root.tsx를 거치지 않으며, DeckVideo와 병렬 작업 시 충돌 없음)
  3. 확인: 이미지를 읽어 제목이 완전하고 잘리지 않았는지, photo 마스크 아래 텍스트를 읽을 수 있는지, 깨진 문자 블록이 없는지 확인; 실제 결과물의 절대 경로를 사용하고, 현재 버전 또는 해시를 재확인. 제목 줄 수는 대상 화면 크기와 읽기 필요에 따라 조정.

경계 및 함정

  • 실제 결과물의 절대 경로를 사용하여 이미지를 읽고, 현재 파일 버전 또는 해시를 재확인; 특정 도구에 실제로 경로 제한이 있는 경우에만 경로를 변환.
  • GBK 콘솔: print는 전부 영어
  • Chrome Headless Shell: 첫 npx remotion browser ensure는 Google 소스에서 다운로드 (수백 MB), 중국 네트워크에서는 시간 초과 가능 — 실패 시 즉시 보고, 대용량 파일 다운로드를 반복 재시도하지 않음
  • 대용량 미디어, 의존성 및 캐시는 Git에 포함되지 않음; 제작 레시피, 썸네일, 자막, 게시 구성 및 검수 메타데이터는 아카이브 규칙에 따라 보관.

현재 워크플로우 및 기술 참조

node scripts/studio.mjs init --id <이름> --line b로 템플릿을 불러오고, job.json의 deps/typecheck는 재실행 가능; 본 프로젝트의 params/render/QC 명령은 장면과 실제 오디오 트랙이 결정된 후 job.json에 추가됩니다. 렌더링 후 media-qc를 호출하며, 기술 보고서와 사용자 최종 검토는 별도로 기록; 아카이브 검증 통과 후 캐시 정리.

공식 remotion-best-practices는 python scripts/install-upstream-skills.py를 통해 프로젝트 캐시에 고정 설치된 후, setup-skills에 의해 마운트됩니다. 출처는 references/upstream.json 참조; 이는 기술 참조이며, 본 저장소 워크플로우를 대체하지 않습니다. 공식 참조 4.0.538과 현재 엔진 4.0.533은 별도로 관리되며, 새 API를 사용하기 전에 먼저 로컬 타입과 실제 렌더링을 확인하고, 자동 업그레이드하지 않음.

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

관련 스킬