Communitygithub.com

anaydhawan/openvidstudio

콘텐츠, 애니메이션 및 효과 모범 사례

openvidstudio란 무엇인가요?

이 스킬은 Remotion 기반 React 마크업을 사용하여 고품질 비디오 콘텐츠를 제작하는 방법을 상세히 설명합니다. `useCurrentFrame()`과 `interpolate()`를 활용한 애니메이션 구동, CSS transition/animation 대신 Remotion 방식의 애니메이션 적용, `Interactive` 컴포넌트를 통한 편집 가능한 마크업 구조 등 핵심 패턴을 제시합니다. 또한 비디오/오디오/이미지 등의 미디어 에셋 처리, 3D 콘텐츠(Three.js), 텍스트 하이라이트, 음성 해설(Voiceover), 자막, 전환 효과, 사운드 효과, 오디오 시각화, 지도(Mapbox/MapLibre), Lottie 애니메이션, GIF, 폰트 로딩 등 광범위한 주제를 다룹니다. 이 스킬은 Claude Code, Cursor, Codex 등 AI 에이전트에서 활용할 수 있으며, Remotion Studio 미리보기, 단일 프레임 렌더링, FFmpeg를 통한 고급 비디오 처리, 매개변수화된 비디오(Zod 스키마), 동적 duration/dimensions 등 실용적인 워크플로우도 포함합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/anaydhawan/openvidstudio/tree/HEAD/.agents/skills/remotion-markup

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

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

미리보기

스킬 README에서

문서

이 문서는 Remotion React 마크업 작성에 대한 안내입니다. 해당되지 않는 경우, Remotion 모범 사례를 대신 로드하세요.

사용자 변경 사항 보존

사용자는 대화 외부에서 코드를 편집할 수 있습니다.

그 사이에 놀라운 변경 사항이 감지되면 덮어쓰지 말고, 의도적인 것으로 간주하거나 확인을 요청하세요.

일반 규칙

애니메이션은 useCurrentFrame()과 interpolate()를 사용하여 구동하세요. CSS transition 또는 animation은 올바르게 렌더링되지 않으므로 리팩토링해야 합니다. Tailwind 애니메이션 클래스는 올바르게 렌더링되지 않으므로 리팩토링해야 합니다.

타이밍을 사용자 정의하려면 Easing.bezier()와 Easing.spring()을 사용하세요.

Remotion 대화형 모범 사례에 따라 마크업을 구성하세요.

import { useCurrentFrame, Easing, interpolate, Interactive } from "remotion";

export const FadeIn = () => {
  const frame = useCurrentFrame();

  return (
    <Interactive.Div
      name="Title"
      style={{
        opacity: interpolate(frame, [0, 2 * fps], [0, 1], {
          extrapolateRight: "clamp",
          extrapolateLeft: "clamp",
          easing: Easing.bezier(0.16, 1, 0.3, 1),
        }),
      }}
    >
      Hello World!
    </Interactive.Div>
  );
};

interpolate() 호출은 style prop 안에 인라인으로 유지하세요. transform 대신 scale, translate, rotate CSS 속성을 사용하세요.

// 👍 인라인 편집 가능한 키프레임 및 transform 단축 속성
style={{
  scale: interpolate(frame, [0, 100], [0, 1], {
    extrapolateLeft: 'clamp',
    extrapolateRight: 'clamp',
    easing: Easing.spring({damping: 200}),
    output: 'perceptual-scale' // `scale` 애니메이션의 경우 "output: 'perceptual-scale'" 사용
  }),
  translate: interpolate(frame, [0, 100], ["0px 0px", "100px 100px"], {
    extrapolateLeft: 'clamp',
    extrapolateRight: 'clamp',
    easing: Easing.spring({damping: 200}),
  }),
  rotate: interpolate(frame, [0, 100], ["20deg", "90deg"], {
    extrapolateLeft: 'clamp',
    extrapolateRight: 'clamp',
    easing: Easing.spring({damping: 200}),
  }),
}}

// 👎 인라인이 아닌 값과 transform 문자열은 Studio에서 편집하기 어려워짐
const scale = interpolate(frame, [0, 100], [0, 1]);

style={{
  transform: `scale(${scale})`,
}}

에셋

에셋은 프로젝트 루트의 public/ 폴더에 배치하세요. staticFile()을 사용하여 public/ 폴더의 파일을 참조하세요.

미디어 컴포넌트

비디오와 오디오는 @remotion/media의 <Video>와 <Audio>를 사용하여 추가하세요. 이미지는 <CanvasImage> 컴포넌트를 사용하여 추가하세요. 애니메이션 GIF, APNG, WebP 또는 AVIF 이미지는 <AnimatedImage>를 사용하여 추가하세요. Chrome을 사용하지 않는 경우 @remotion/gif를 사용하세요. public/ 파일에는 staticFile()을 사용하거나 원격 URL을 직접 전달하세요.

import { Audio, Video } from "@remotion/media";
import { staticFile, CanvasImage, AnimatedImage } from "remotion";

export const MyComposition = () => {
  return (
    <>
      <Video src={staticFile("video.mp4")} style={{ opacity: 0.5 }} />
      <Audio src={staticFile("audio.mp3")} />
      <CanvasImage
        src={staticFile("logo.png")}
        style={{ width: 100, height: 100 }}
      />
      <Video src="https://remotion.media/video.mp4" />
      <AnimatedImage src={staticFile('nyancat.gif')} />
    </>
  );
};

예제 장면

import {
  AbsoluteFill,
  Easing,
  Interactive,
  interpolate,
  useCurrentFrame,
  useVideoConfig
} from "remotion";

export const Empty = () => {
  const {fps} = useVideoConfig();
  const frame = useCurrentFrame();

  return (
    <AbsoluteFill
      name="Scene"
      style={{
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: 'white'
      }}
    >
      <Interactive.Div
        name="Title"
        style={{
          opacity: interpolate(frame, [1 * fps, 2 * fps], [0, 1], {
            extrapolateRight: "clamp",
            extrapolateLeft: "clamp",
            easing: Easing.bezier(0.16, 1, 0.3, 1),
          }),
          fontSize: 88
        }}
      >
        Title
      </Interactive.Div>
      <Interactive.Div
        name="Subtitle"
        style={{
          opacity: interpolate(frame, [2 * fps, 3 * fps, 8 * fps, 10 * fps], [0, 1, 1, 0], {
            extrapolateRight: "clamp",
            extrapolateLeft: "clamp",
            easing: [Easing.bezier(0.16, 1, 0.3, 1), Easing.linear, Easing.bezier(0.16, 1, 0.3, 1)],
          }),
          fontSize: 32
        }}
      >
        Subtitle
      </Interactive.Div>
    </AbsoluteFill>
  );
}

지연, 트리밍

대부분의 컴포넌트(<AbsoluteFill>, <Interactive.*> <Img>, <AnimatedImage>, <CanvasImage>, <HtmlInCanvas>, <Solid>, <Sequence> (from remotion), <Video>와 <Audio> (from @remotion/media), <Gif> 등)는 다음 props를 지원합니다.

from

<Img from={1 * fps} {/* ... */}/>
<Video from={1 * fps} {/* ... */}/>
<Interactive.Div from={1 * fps} {/* ... */}/>

요소가 타임라인에 나타나기 시작하는 시점입니다.

durationInFrames

<Img durationInFrames={20 * fps} {/* ... */}/>
<Interactive.Div durationInFrames={20 * fps} {/* ... */}/>

레이어가 타임라인에서 재생되는 시간입니다. 미디어의 경우 미디어의 자연 재생 시간을 전달하세요: <Video durationInFrames={29.322 * fps}/>

trimBefore

내부 시계가 나중에 시작되어야 하는 컴포넌트에 유용합니다.

// 첫 2초의 푸티지를 잘라냄
<Video trimBefore={2 * fps} {/* ... */} />

// 자식의 `useCurrenFrame()`이 `10 * fps`에서 시작됨
<Sequence trimBefore={10 * fps} {/* ... */} />

대체 방법

컴포넌트가 이러한 props를 지원하지 않는 경우, 이러한 props가 있는 remotion의 <Sequence>로 감싸세요.

  • layout="absolute-fill"은 Sequence가 AbsoluteFill처럼 동작하게 합니다.
  • layout="none"은 "headless" 모드이며, 래퍼 요소가 사용되지 않습니다.

지도

비디오에 지도를 포함하려면 Remotion Maps을 참조하세요.

텍스트 하이라이트 및 주석

텍스트 하이라이트(하이라이트 마커), 원, 밑줄, 취소선, 지워진 텍스트, 상자에 대해서는 text-highlights.md를 참조하세요.

다중 장면 비디오

여러 개의 연속 장면으로 비디오를 만들 계획이라면 multi-scene-video.md를 참조하세요.

음성 해설

ElevenLabs TTS를 사용하여 AI 생성 음성 해설을 Remotion 컴포지션에 추가하려면 voiceover.md를 참조하세요.

비디오 임베딩

비디오 임베딩에 대한 고급 지식(트리밍, 볼륨, 속도, 루핑, 피치)은 embedding-videos.md를 참조하세요.

오디오 임베딩

트리밍, 볼륨, 속도, 피치와 같은 고급 오디오 기능은 audio.md를 참조하세요.

비디오 편집

Remotion Studio에서 편집 가능한 비디오 타임라인을 구성하는 방법은 video-editing.md를 참조하세요.

자르기

컴포넌트의 보이는 사각형을 자르려면 cropping.md를 참조하세요.

전환

장면 전환 패턴은 transitions.md를 참조하세요.

시각 및 픽셀 효과

시각 효과를 만들 때 CSS와 HTML로 구현 가능한지, 셰이더가 필요한지 고려하세요. 선호 순서:

  1. 일반 HTML + CSS 또는 기타 웹 기술
  2. 요소에 직접 적용되는 효과(<Video>, <Img>), 또는 콘텐츠를 <HtmlInCanvas>로 감싸는 방법. <HtmlInCanvas>는 effects도 허용합니다:
  • effects.md를 통한 나열된 효과
  • 사전 설정이 없을 때 effects.md를 통한 사용자 정의 createEffect()

3D 콘텐츠

Three.js 및 React Three Fiber를 사용한 Remotion의 3D 콘텐츠는 ./3d.md를 참조하세요.

사운드 효과

사운드 효과를 사용해야 할 때는 ./sfx.md 파일을 로드하여 자세한 정보를 확인하세요.

오디오 시각화

오디오를 시각화(스펙트럼 막대, 파형, 베이스 반응 효과)해야 할 때는 ./audio-visualization.md 파일을 로드하여 자세한 정보를 확인하세요.

지도

정적 지도, 애니메이션 경로 및 마커, 지리적 설명, Mapbox, MapLibre, MapTiler, GeoJSON 또는 3D 지리적 비행 오버의 경우 Remotion Maps를 로드하세요.

자막

자막 또는 캡션을 다룰 때는 Remotion Captions 스킬을 로드하여 자세한 정보를 확인하세요.

Google Fonts

Remotion에서 글꼴을 로드하는 권장 방법입니다. Google Fonts 로드 방법은 google-fonts.md를 참조하세요.

로컬 글꼴

로컬 글꼴 로드 방법은 local-fonts.md를 참조하세요.

GIF

Remotion의 타임라인과 동기화된 GIF를 표시하는 방법은 gifs.md를 참조하세요.

고급 이미지

이미지 크기 조정 및 위치 지정, 동적 이미지 경로, 이미지 크기 가져오기는 images.md를 참조하세요.

Lottie 애니메이션

Remotion에 Lottie 애니메이션을 포함하려면 lottie.md를 참조하세요.

타이밍

interpolate()에 대한 더 많은 타이밍 기술은 timing.md를 참조하세요.

매개변수화된 비디오

Zod 스키마를 추가하여 컴포지션을 매개변수화하는 방법은 parameters.md를 참조하세요.

DOM 노드 측정

Remotion에서 DOM 요소 크기를 측정하는 방법은 measuring-dom-nodes.md를 참조하세요.

텍스트 측정

텍스트 크기 측정, 텍스트를 컨테이너에 맞추기, 오버플로 확인은 measuring-text.md를 참조하세요.

FFmpeg 사용

비디오 트리밍이나 무음 감지와 같은 일부 비디오 작업에는 FFmpeg를 사용해야 합니다. 자세한 내용은 ./ffmpeg.md 파일을 로드하세요.

무음 감지

비디오 또는 오디오 파일에서 무음 세그먼트를 감지하고 잘라내야 할 때는 ./silence-detection.md 파일을 로드하세요.

동적 duration, 크기 및 데이터

컴포지션 duration, 크기 및 props를 동적으로 설정하는 방법은 calculate-metadata.md를 참조하세요.

고급 컴포지션

스틸, 폴더, 기본 props를 정의하고 컴포지션을 중첩하는 방법은 compositions.md를 참조하세요.

고급 시퀀싱

지연, 트리밍, 항목 duration 제한과 같은 더 많은 시퀀싱 패턴은 sequencing.md를 참조하세요.

모듈 설치

npx remotion add를 사용하여 올바른 버전의 새 패키지를 추가하세요.

npx remotion add @remotion/media

이는 @remotion/* 패키지, mediabunny, @mediabunny/*, zod에 적용됩니다.

마크업 미리보기

npx remotion studio --no-open

이 명령은 장기 실행 프로세스를 시작하고 미리보기를 위한 서버 URL을 출력합니다. 이미 서버가 시작된 경우 URL을 출력합니다. /[composition-id]로 이동하여 특정 컴포지션을 방문할 수 있습니다. 예: http://localhost:3000/MapAnimation

선택 사항: 단일 프레임 렌더링 확인

CLI로 단일 프레임을 렌더링하여 레이아웃, 색상 또는 타이밍을 간단히 확인할 수 있습니다. 사소한 편집, 순수 리팩토링 또는 Studio나 이전 렌더링에서 이미 충분한 확신이 있는 경우 건너뛰세요.

npx remotion still [composition-id] --scale=0.25 --frame=30

30fps에서 --frame=30은 1초 지점입니다(--frame은 0부터 시작).

Individual skills in this repo

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

관련 스킬