Communitygithub.com

quyen2867/remotion-video-template

전문적인 50-60초 세로형 설명 동영상(TikTok/Shorts/Reels 9:16, 1080x1920 @ 30fps)을 Remotion으로 제작하며, edge-tts-universal 또는 CIT Voice Studio(TTS_PROVIDER 선택)의 자연스러운 내레이션을 활용합니다.

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

이 스킬은 `remotion-dev/skills`의 베스트 프랙티스(스프링 애니메이션, 클램핑 보간, 시퀀스 타이밍, 타이포그래피)를 기반으로 50~60초 길이의 짧은 설명 동영상을 제작합니다. 주제가 주어지면 6개 장면(Hook-Problem-Solution-Value-Outro)으로 구성된 스크립트를 작성하고, `TTS_PROVIDER` 환경 변수에 따라 edge-tts-universal(온라인 무료) 또는 CIT Voice Studio(오프라인, 베트남어 스튜디오 음성) 중 하나를 선택해 음성을 합성합니다. 각 장면의 오디오 길이를 `durationInFrames`로 매핑하여 정확한 타임라인 동기화를 수행하며, Remotion의 `<Sequence>`와 `<Series>`를 활용해 부드러운 전환을 구현합니다. 디자인은 다크 모드 글래스모피즘 카드, 모바일 최적화 타이포그래피(72-96px 제목, 40-50px 본문), 중앙 정렬 레이아웃과 함께 채널 브랜드 헤더를 항상 표시합니다. 최종 결과물은 `npx remotion render` 명령으로 MP4로 렌더링할 수 있습니다.

지원 대상~Claude Code✓Codex CLI~Cursor✓Antigravity
npx skills add https://github.com/quyen2867/remotion-video-template/tree/HEAD/.agents/skills/remotion-topic-explainer

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

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

문서

Remotion 주제 설명 동영상 스킬 (50-60초)

이 스킬은 모든 주제에 대해 고품질의 50~60초 짧은 형식의 설명 동영상(TikTok / YouTube Shorts / Reels 형식: 1080x1920 @ 30fps)을 제작하는 방법을 안내합니다.

다음 요소를 결합합니다:

  1. 시각적 베스트 프랙티스 (remotion-dev/skills에서 제공: 프레임 정확한 스프링, 보간 클램핑, 시퀀스 구성, 타이포그래피 계층).
  2. AI 음성 합성: .env에서 TTS_PROVIDER를 통해 edge (edge-tts-universal, 온라인, 무료) 또는 cit (CIT Voice Studio, 오프라인 베트남어 스튜디오 음성 - github.com/quyen2867/cit-voice-studio에서 다운로드, API 문서: docs/cit-voice-studio.md).
  3. 정확한 타이밍 동기화: 오디오 음성 길이를 Remotion 프레임 시퀀스에 직접 매핑합니다.

1. 동영상 구조 및 타이밍 (50-60초 / 30fps 기준 1500-1800프레임)

매력적인 짧은 동영상은 Hook-Problem-Solution-Value-Outro 프레임워크를 따릅니다:

장면이름시간프레임 범위 (@ 30fps)목적 및 시각 요소
1Hook0초 – 5초~150프레임즉시 주목 유도: 큰 제목, 호기심 자극 질문, 떠다니는 배지.
2맥락 / 문제점5초 – 15초~300프레임주제가 중요한 이유나 배경 제시. 경고 아이콘/비교.
3핵심 개념 115초 – 28초~390프레임첫 번째 핵심 원리 설명: 유리 카드, 설명 아이콘, 강조 키워드.
4핵심 개념 228초 – 42초~420프레임세부 사항 또는 작동 메커니즘 확장: 3단계 프로세스, 부드러운 흐름도.
5실제 영향42초 – 52초~300프레임실제 적용, 실용적인 조언 또는 인상적인 데이터.
6아웃트로 및 CTA52초 – 60초~240프레임강력한 한 문장 요약, Like/Share/Follow 요청 및 개인 브랜드.

총 길이: 1500 – 1800프레임 (약 50 – 60초).


2. TTS 음성 생성 (edge | cit)

2.1 .env를 통한 음성 구성

.env 파일이 올바르게 구성되었는지 확인하세요 (전체 내용은 .env.example 참조):

TTS_PROVIDER=edge                    # edge | cit
TTS_OUTPUT_DIR=public/audio

# Edge TTS (TTS_PROVIDER=edge)
EDGE_TTS_VOICE=vi-VN-HoaiMyNeural    # 또는 vi-VN-NamMinhNeural, en-US-ChristopherNeural
EDGE_TTS_RATE=+10%                   # +10% ~ +15%는 짧은 동영상의 빠른 템포에 매력적

# CIT Voice Studio (TTS_PROVIDER=cit)
CIT_TTS_BASE_URL=http://127.0.0.1:8001
CIT_TTS_VOICE=Hải Đăng               # 음성 목록: docs/cit-voice-studio.md 또는 GET /voices
CIT_TTS_SPEED=1.1                    # 0.5 - 2.0

TTS_PROVIDER=cit인 경우:

  • CIT Voice Studio 앱이 실행 중이어야 합니다. 스크립트는 오디오 생성 전에 자동으로 GET /health를 호출하고, 연결할 수 없으면 사용자에게 앱을 열도록 안내합니다 (또는 github.com/quyen2867/cit-voice-studio에서 다운로드).
  • 대사에는 감정 태그 [cười], [thở dài], [hắng giọng] 및 일시 정지 태그 [nghỉ 0.5s]를 삽입할 수 있습니다 (소리내어 읽히지 않음). 남용 금지: 장면당 최대 1개 태그.
  • 오류 400 Voice not found = 잘못된 음성 이름 (악센트 구분). CIT_TTS_VOICE를 확인하세요.

2.2 오디오 파일 생성 프로세스

주제를 받으면 음성 대본 파일을 생성하고 scripts/generate-tts.ts 스크립트를 실행하여 오디오를 생성합니다:

import { generateTopicVoices } from "../../scripts/generate-tts";

const scenes = [
  {
    id: "scene1_hook",
    text: "Bạn có biết Docker thực chất là gì và tại sao mọi lập trình viên đều cần nó?",
  },
  {
    id: "scene2_problem",
    text: "Trước đây, câu nói 'trên máy tôi vẫn chạy được' luôn là cơn ác mộng khi bàn giao sản phẩm.",
  },
  {
    id: "scene3_concept1",
    text: "Docker giải quyết việc này bằng Container - đóng gói toàn bộ code và môi trường vào một khối duy nhất.",
  },
  {
    id: "scene4_concept2",
    text: "Khác với máy ảo nặng nề, Docker chia sẻ chung nhân hệ điều hành, giúp khởi động chỉ trong tích tắc.",
  },
  {
    id: "scene5_impact",
    text: "Nhờ đó, bạn deploy ứng dụng mượt mà trên mọi máy chủ từ AWS, GCP cho đến VPS giá rẻ.",
  },
  {
    id: "scene6_outro",
    text: "Follow kênh để nắm trọn các kiến thức công nghệ ngắn gọn mỗi ngày nhé!",
  },
];

await generateTopicVoices("DockerShort", scenes);

오디오 파일은 public/audio/<TopicName>/<sceneId>.<ext> (edge는 .mp3, cit는 .wav)에 자동 저장되며, 각 장면의 정확한 프레임 수(durationInFrames)와 audioPath를 기록한 manifest.json 파일도 함께 생성됩니다.

  • 각 장면에 선택적 속성: voice (선택한 공급자의 음성), rate/pitch/volume (edge 전용), speed 0.5-2.0 (cit 전용).
  • 이미 존재하는 파일은 재사용됩니다(캐시). 대사나 음성을 변경한 후 다시 생성하려면 해당 오디오 파일을 먼저 삭제하세요.

3. Remotion 코딩 규칙 (remotion-dev/skills에서)

Remotion 소스 코드를 작성할 때는 다음 원칙을 반드시 준수해야 합니다:

3.1 스프링 애니메이션 사용

CSS keyframes/transitions 또는 무미건조한 linear easing을 사용하지 마세요. spring()을 사용하세요:

import { spring, useCurrentFrame, useVideoConfig } from "remotion";

const frame = useCurrentFrame();
const { fps } = useVideoConfig();

// 카드/아이콘을 위한 부드러운 바운스 스프링
const scale = spring({
  frame,
  fps,
  config: {
    damping: 12,    // 15 미만은 자연스러운 탄성 바운스 생성
    stiffness: 100,  // 강성
    mass: 0.8,
  },
});

const entrance = spring({
  frame: frame - 10, // 10프레임 지연
  fps,
  from: 50,
  to: 0,
});

3.2 안전한 보간 (항상 Clamp)

타임라인이 범위를 벗어날 때 값이 넘치지 않도록 항상 extrapolateLeft: "clamp" 및 extrapolateRight: "clamp"를 제공하세요:

import { interpolate } from "remotion";

const opacity = interpolate(frame, [0, 15], [0, 1], {
  extrapolateLeft: "clamp",
  extrapolateRight: "clamp",
});

3.3 오디오 임베드 및 시퀀스 동기화

Composition의 각 장면은 <Sequence> 또는 <Series>를 사용하여 정확한 타이밍을 관리합니다:

import { Audio, staticFile, Sequence } from "remotion";

// Scene 컴포넌트 내부 - manifest에서 경로를 가져오고, .mp3 확장자를 하드코딩하지 마세요 (cit 공급자는 .wav 출력):
<Sequence from={0} durationInFrames={sceneDuration}>
  <Audio src={staticFile(audioManifest.scenes[0].audioPath)} />
  <SceneContent />
</Sequence>
  1. 깔끔한 장면 전환 버퍼 (Snappy Transition Buffer):
    • 장면 사이의 간격은 음성이 끝난 후 +3 ~ +4프레임 (약 0.1초) 만 남겨야 합니다.
    • 버퍼가 너무 길면 (+15 ~ +20프레임) 장면 사이에 정적/데드 비트가 발생하여 짧은 동영상의 빠르고 매력적인 템포를 유지하지 못합니다. 다음 장면은 이전 문장이 끝나자마자 나타나야 합니다.
// Series에서 장면 길이 계산 예시
const d1 = audioManifest.scenes[0].durationInFrames + 3;
const d2 = audioManifest.scenes[1].durationInFrames + 3;
// ...

3.4 시각 디자인 표준 (세로 1080x1920)

  1. 배경: 고급스러운 다크 모드 (bg-slate-950 또는 from-slate-950 via-zinc-900 to-black 그래디언트)에 방사형 글로우/그리드 효과 결합.
  2. 글래스모피즘 카드:
    • backdrop-blur-xl bg-white/10 border border-white/20 rounded-3xl p-8 shadow-2xl
  3. 채널 브랜드 헤더:
    • 항상 상단 중앙(top: 150px, left: 50% translate-x)에 ⚡ [CHANNEL_NAME] 브랜드 컴포넌트를 표시하며, 환경 변수 CHANNEL_NAME (기본값: "mquyen")에서 읽어와 플랫폼(TikTok, Shorts, Reels)의 검색창, 팔로잉/For You 탭에 가려지지 않도록 합니다.
  4. 모바일 최적화 타이포그래피 (1080x1920):
    • 주요 제목: 72px - 96px, font-black 굵게, 선명한 그래디언트.
    • 카드 내용/인용문: 40px - 50px font-extrabold.
    • 보조 설명 텍스트: 28px - 36px font-semibold.
    • 카테고리 배지: 28px - 32px font-black uppercase.
  5. 중앙 레이아웃 및 한 줄 자막 (Single-Line Chunked Caption):
    • 주요 레이아웃: 모든 중요한 콘텐츠 블록은 화면 정중앙 (세로 justify-center)에 위치해야 합니다.
    • 자막 위치: 중앙 블록 아래 충분한 간격(mt-64)을 두어 TikTok/Reels 하단 툴바에 가려지지 않도록 합니다.
    • 한 줄 형식: 자막은 한 줄(약 5-7단어) 로만 표시되며, 큰 글자 text-4xl font-black로 자동으로 구문 단위로 잘리고 음성 진행(durationInFrames)에 따라 부드럽게 전환됩니다. rounded-full bg-slate-950/95 border-2 border-sky-400/50 px-10 py-5의 알약 카드를 사용하고 키워드를 강조합니다.

4. Antigravity / Codex를 위한 단계별 동영상 제작 프로세스

요청을 받으면: "[주제 X]에 대한 설명 동영상 생성":

단계 1: 스크립트 작성

  1. 6개 장면(Hook, Problem, Concept 1, Concept 2, Impact, Outro)을 결정합니다.
  2. 자연스럽고 간결한 베트남어 대사를 작성합니다 (각 장면 15-30단어).

단계 2: 음성 생성 (TTS Generation)

  1. .env에서 TTS_PROVIDER를 읽어 edge 또는 cit 중 어떤 것을 사용하는지 확인합니다.
  2. generateTopicVoices를 호출하는 scripts/generate-<topic>-audio.ts 스크립트를 생성하고, npx tsx scripts/generate-<topic>-audio.ts를 실행합니다.
  3. manifest.json / src/<TopicName>/audioData.ts에서 실제 프레임 길이 목록을 가져옵니다.

단계 3: 코드 디렉토리 src/<TopicName>/ 생성

표준 디렉토리 구조:

src/<TopicName>/
├── <TopicName>.tsx          # 여러 Series.Sequence를 조합하는 메인 Composition
├── types.ts                 # 스키마 및 속성
├── audioData.ts             # 오디오 길이 메타데이터
└── scenes/
    ├── Scene1Hook.tsx
    ├── Scene2Problem.tsx
    ├── Scene3Concept1.tsx
    ├── Scene4Concept2.tsx
    ├── Scene5Impact.tsx
    └── Scene6Outro.tsx

단계 4: src/Root.tsx에 Composition 등록

src/Root.tsx에 새 Composition을 추가합니다:

<Composition
  id="<TopicName>"
  component={<TopicName>}
  durationInFrames={totalFrames}
  fps={30}
  width={1080}
  height={1920}
  defaultProps={{}}
/>

단계 5: 확인 및 보고

  1. npm run lint를 실행하여 TypeScript/ESLint 오류를 확인합니다.
  2. 사용자에게 Remotion Studio에서 Composition을 열 수 있는 링크(http://localhost:3000) 또는 MP4 렌더링 명령어를 보고합니다:
    npx remotion render <TopicName> out/<TopicName>.mp4
    

관련 스킬