Communitygithub.com

iamaanahmad/remotion-programmatic-video

React 코드로 비디오를 제작하세요 - Remotion을 사용한 컴포지션, 시퀀스, 스프링, 인터폴레이션, 오디오 동기화, 데이터 기반 속성, 스튜디오 미리보기 및 MP4 렌더링. 설명 영상, 제품 데모, 릴리스 노트, 데이터 차트, 브랜드 템플릿 또는 코드로 재현 가능한 모든 비디오에 적합합니다.

remotion-programmatic-video란 무엇인가요?

이 스킬은 React 컴포넌트를 프레임 단위로 렌더링하여 프로그래매틱 방식으로 비디오를 제작할 수 있는 Remotion의 핵심 기능을 제공합니다. 각 프레임은 프레임 번호에 대한 순수 함수로 표현되어 애니메이션이 결정적이며 재렌더링이 가능합니다. Remotion은 `useCurrentFrame()`과 `useVideoConfig()` 같은 React 훅을 사용하여 프레임 기반 애니메이션을 구현하며, `interpolate()`와 `spring()` 같은 내장 애니메이션 프리미티브를 제공합니다. `Sequence` 컴포넌트를 통해 장면을 시간 순서대로 배치하고, `@remotion/transitions`로 페이드, 슬라이드, 와이프 같은 전환 효과를 추가할 수 있습니다. 오디오/비디오 동기화는 `staticFile()`을 사용한 미디어 에셋 관리와 `calculateMetadata`를 통한 동적 지속 시간 계산으로 이루어집니다. 이 스킬은 Remotion API의 주요 버전 간 변경 사항을 주의해야 하며, 공식 문서(remotion.dev)를 함께 참조할 것을 권장합니다. 스튜디오 미리보기와 CLI 렌더링을 모두 지원하며, `npx create-video@latest`로 프로젝트를 시작합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/iamaanahmad/agents-video-editing-skills/tree/HEAD/skills/remotion-programmatic-video

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

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

문서

Remotion (프로그래매틱 비디오)

Remotion은 React 컴포넌트를 프레임 단위로 렌더링합니다. 각 프레임은 프레임 번호에 대한 순수 함수이므로 애니메이션은 결정적이며 다시 렌더링할 수 있습니다.

Remotion의 API는 주요 버전 간에 변경됩니다. 설치된 버전(npm ls remotion)과 공식 문서(remotion.dev)를 읽고 확실하지 않은 API를 사용하기 전에 확인하세요. 기업의 상업적 사용을 위해 Remotion의 라이선스 조건을 확인하세요.

설정

npx create-video@latest          # 빈 템플릿(TypeScript) 선택
cd my-video && npm install
npx remotion studio              # 실시간 미리보기
npx remotion render MyComp out/video.mp4
npx remotion still MyComp out/thumb.png --frame=45

개념 모델

  • useCurrentFrame()은 현재 프레임을 반환하며, 0부터 시작합니다.
  • useVideoConfig()은 fps, width, height, durationInFrames를 제공합니다.
  • 아무것도 자동으로 애니메이션되지 않습니다. 스타일을 프레임에서 계산합니다.
  • CSS 전환, setTimeout, Math.random() 또는 Date.now()를 애니메이션에 절대 사용하지 마세요. 이들은 렌더링 결정성을 깨뜨립니다. 대신 remotion의 random('seed')를 사용하세요.

컴포지션

// src/Root.tsx
import {Composition} from 'remotion';
import {Explainer} from './Explainer';

export const RemotionRoot = () => (
  <Composition
    id="Explainer"
    component={Explainer}
    durationInFrames={30 * 20}   // 30fps에서 20초
    fps={30}
    width={1920}
    height={1080}
    defaultProps={{title: 'Hello'}}
  />
);

애니메이션 프리미티브

import {AbsoluteFill, Sequence, interpolate, spring, useCurrentFrame, useVideoConfig} from 'remotion';

export const Title: React.FC<{text: string}> = ({text}) => {
  const frame = useCurrentFrame();
  const {fps} = useVideoConfig();

  const opacity = interpolate(frame, [0, 15], [0, 1], {extrapolateRight: 'clamp'});
  const scale = spring({frame, fps, config: {damping: 200}});   // 부드럽고 튕김 없음

  return (
    <AbsoluteFill style={{justifyContent: 'center', alignItems: 'center'}}>
      <h1 style={{opacity, transform: `scale(${0.9 + 0.1 * scale})`, fontSize: 96}}>{text}</h1>
    </AbsoluteFill>
  );
};

export const Explainer = () => (
  <AbsoluteFill style={{backgroundColor: '#0b1020', color: 'white'}}>
    <Sequence from={0} durationInFrames={90}><Title text="Intro" /></Sequence>
    <Sequence from={90} durationInFrames={120}><Title text="핵심 내용" /></Sequence>
  </AbsoluteFill>
);

값이 범위를 벗어나지 않도록 하려면 항상 interpolate에 extrapolateLeft/Right: 'clamp'를 전달하세요.

미디어

import {staticFile, Audio, OffthreadVideo, Img} from 'remotion';

<Audio src={staticFile('voiceover.mp3')} />
<Audio src={staticFile('music.mp3')} volume={0.12} />
<OffthreadVideo src={staticFile('demo.mp4')} />
<Img src={staticFile('logo.png')} />

에셋은 public/ 디렉토리에 넣고 staticFile()로 참조하세요. <img> 대신 <Img>를 사용하여 렌더링이 이미지를 기다리도록 하세요. 최신 Remotion 버전은 업데이트된 미디어 컴포넌트를 제공하므로 설치된 버전의 문서를 확인하세요.

장면을 내레이션에 동기화

장면 길이를 하드코딩하지 마세요. 오디오에서 파생시키세요.

  1. 장면별 음성 파일(voiceover-tts 스킬)을 생성합니다.
  2. ffprobe로 각 길이를 측정하고 scenes.json을 {id, audio, seconds} 형식으로 작성합니다.
  3. 컴포지션에서 Math.ceil((seconds + 0.5) * fps)로 변환하고 누적 오프셋으로 <Sequence>를 배치합니다.
  4. <Composition>에서 calculateMetadata를 사용하여 해당 데이터로 총 durationInFrames를 설정합니다.

음성이 다시 녹음되면 비디오가 자동으로 재조정됩니다.

전환

@remotion/transitions를 설치하고 fade(), slide(), wipe()와 함께 TransitionSeries를 사용하세요. 전환은 두 장면을 겹치므로 전체 길이가 전환 지속 시간만큼 줄어듭니다. 30fps에서 전환은 12~20프레임으로 유지하세요.

글꼴 및 브랜드

@remotion/google-fonts 또는 @remotion/fonts로 글꼴을 로드하여 첫 번째 프레임 이전에 준비되도록 하세요. 색상, 글꼴 및 로고를 하나의 brand.ts 파일에 유지하여 리브랜딩을 한 파일 변경으로 처리할 수 있게 하세요.

성능 및 렌더링

  • 스튜디오에서 미리보기, CLI에서 렌더링합니다.
  • --concurrency=50%는 CPU 사용량을 제한합니다. --codec=h264가 기본값입니다. 편집 연계를 위해 --codec=prores를 사용하세요.
  • 무거운 블러, 그림자 및 큰 SVG 필터는 느립니다. 이러한 경우 미리 렌더링된 에셋을 선호하세요.
  • 소스 푸티지에는 <video> 대신 <OffthreadVideo>를 사용하여 프레임 정확한 추출을 얻으세요.
  • 빠른 초안을 위해 --scale=0.5와 --frames=0-90 범위를 사용하세요.

일반적인 실수

실수해결 방법
렌더링 시 깜빡임 또는 이미지 누락<Img>, staticFile 및 비동기 데이터를 위한 delayRender 사용
미리보기와 렌더링 간 애니메이션 차이비결정적 코드(시간, 난수) 제거
다른 로케일에서 텍스트 오버플로우명시적 너비 설정, 가장 긴 문자열 테스트
전환 추가 후 비디오가 너무 길어짐총 프레임에서 전환 프레임 빼기
렌더링에서 오디오가 들리지 않음파일 경로와 <Audio>가 활성 <Sequence> 내부에 있는지 확인

타이밍 및 이징 선택을 위해 motion-design-craft와 함께 사용하세요.

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

관련 스킬