비디오 생성
Remotion을 활용한 JSON 기반 비디오 생성 파이프라인입니다. 구조화된 JSON으로 타임라인을 작성하고, 테마 지원, TTS 나레이션, 트랜지션, 풍부한 컴포넌트 라이브러리를 갖춘 MP4로 렌더링합니다 — 모든 작업을 커맨드 라인에서 수행할 수 있습니다.
기본 활성: 예 AI & 미디어
video 스킬은 시스템 프롬프트에 자동으로 주입됩니다. 에이전트가 "video", "Remotion", "animation", "mp4", "render video", "slides to video" 같은 키워드를 감지하면 활성화됩니다. 수동 로딩이 필요 없습니다.
빠른 참조
| 스킬 이름 | video |
| 카테고리 | AI & 미디어 |
| 기본 활성 | 예 — 트리거 키워드 감지 시 자동 주입 |
| 트리거 | video, Remotion, animation, mp4, render video, slides to video |
| SKILL.md 경로 | skills_ref/video/SKILL.md |
| 출력 디렉토리 | /tmp/remotion-render/ |
| 런타임 | Node.js 22.4+, pnpm, ffmpeg, ffprobe |
| 부트스트랩 | node scripts/ensure-remotion.mjs |
| TTS 제공자 | Gemini (기본), Supertone, Supertonic |
| 관련 스킬 | pptx, diagram |
CLI 명령어
모든 명령어는 skills_ref/video/ 디렉토리에서 실행합니다. 출력은 기본적으로 /tmp/remotion-render/에 저장됩니다 — 렌더링 출력은 소스 트리 외부에 유지하세요.
| 작업 | 명령어 |
|---|---|
| 렌더링 (동기) | node scripts/pipeline.mjs --timeline <path> [--preset Landscape-1080p] |
| 렌더링 + TTS | node scripts/pipeline.mjs --timeline timeline.draft.json |
| TTS 건너뛰기 | node scripts/pipeline.mjs --timeline timeline.draft.json --skip-tts |
| TTS 일괄 처리 | node scripts/tts.mjs --batch timeline.draft.json [--provider supertone] |
| TTS 단건 | node scripts/tts.mjs --text "Hello" --output /tmp/tts-out.m4a [--provider gemini] |
| 음성 목록 | node scripts/tts.mjs --list-voices [--provider supertone] |
| 렌더링 (비동기) | node scripts/pipeline.mjs --timeline <path> --async |
| 상태 확인 | node scripts/pipeline.mjs --status /tmp/remotion-render/render-result.json |
| 미리보기 | cd remotion-project && pnpm exec remotion studio |
| 검증 | node scripts/validate-artifact.mjs /tmp/remotion-render/TimelineVideo.mp4 --preset Landscape-1080p |
파이프라인 사용법
# 동기 (기본) — 렌더링 완료까지 대기
node skills_ref/video/scripts/pipeline.mjs \
--timeline timeline.json \
--output /tmp/remotion-render
# 프리셋 오버라이드 (timeline.meta.preset이 기준값)
node skills_ref/video/scripts/pipeline.mjs \
--timeline timeline.json \
--preset Portrait-1080p
# 비동기 — 즉시 반환, 백그라운드에서 렌더링
node skills_ref/video/scripts/pipeline.mjs \
--timeline timeline.json \
--async
# 비동기 상태 확인
node skills_ref/video/scripts/pipeline.mjs \
--status /tmp/remotion-render/render-result.json
timeline.meta.preset이 해상도 설정의 기준값입니다. CLI의 --preset 플래그로 오버라이드할 수 있지만 경고가 표시됩니다. 항상 타임라인 JSON에서 프리셋을 설정하는 것을 권장합니다.
타임라인 작성
비디오는 meta 블록(제목, 프리셋, fps, 재생 시간)과 타입이 지정된 슬라이드의 elements 배열로 구성된 JSON 타임라인으로 정의됩니다. 각 요소는 타입, 타이밍, 속성, 그리고 선택적 트랜지션을 지정합니다.
최소 예제
{
"meta": {
"title": "My Video",
"preset": "Landscape-1080p",
"fps": 30,
"totalDurationSec": 15
},
"elements": [
{
"type": "title",
"startSec": 0,
"durationSec": 5,
"props": { "title": "Hello World", "subtitle": "A demo" },
"transition": { "type": "fade" }
},
{
"type": "content",
"startSec": 5,
"durationSec": 5,
"props": {
"header": "Key Points",
"bulletPoints": ["Fast", "Safe", "Beautiful"]
},
"transition": { "type": "slide", "direction": "from-right" }
},
{
"type": "code",
"startSec": 10,
"durationSec": 5,
"props": {
"code": "const x = 42;",
"language": "typescript",
"title": "Example"
},
"transition": { "type": "fade" }
}
],
"audio": []
}
테마 시스템
각 비디오는 meta.theme을 통해 고유한 미학을 정의해야 합니다. 폰트는 크로스 플랫폼 렌더링을 위해 @remotion/google-fonts로 로드됩니다. 기본 테마는 Chakra Petch(디스플레이), Outfit(본문), JetBrains Mono(코드)를 사용하며, 짙은 파란색 배경에 시안 액센트 색상을 적용합니다.
{
"meta": {
"theme": {
"aesthetic": "brutalist tech",
"font": { "display": "Chakra Petch", "body": "Outfit" },
"color": { "accent": "#FF6B35", "bg": "#0A0A0A" },
"gradient": {
"hero": "radial-gradient(circle at 20% 30%, rgba(255,107,53,0.2) 0%, transparent 60%)"
}
}
}
}
meta.theme에서 Inter, Roboto, Arial을 사용하지 마세요. 이 폰트들은 범용/AI 생성 콘텐츠를 연상시키며, 독특한 미학 요구사항에 위배됩니다.
콘텐츠 디자인 규칙
권장 사항
- 이모지 없이 간결한 헤더를 사용하세요
- 불릿 포인트는 짧은 문구로 작성하세요 (최대 8단어), 슬라이드당 3–4개
- 슬라이드 타입을 다양하게 구성하세요: title, content, code, content — 단조로움을 피하세요
- 트랜지션을 섞어 사용하세요: fade, slide, wipe (같은 타입을 3회 이상 연속 반복하지 마세요)
- 코드 슬라이드에는 의사 코드가 아닌 실제 코드를 보여주세요
- 테마 미학을 선택한 후 전체에 일관되게 적용하세요
금지 사항
- 슬라이드 제목이나 헤더에 이모지 사용
- 단일 슬라이드에 5개 이상의 불릿 포인트
- "Key Features", "Getting Started", "Summary" 같은 범용적인 헤더
meta.theme에서 Inter, Roboto, Arial 폰트 사용
콘텐츠 밀도
캔버스가 크기 때문에 (1920x1080 또는 1080x1920) 콘텐츠가 적으면 빈 공간이 생깁니다. 폰트를 키우거나 패딩을 늘리지 말고 콘텐츠 블록을 추가하세요. 각 슬라이드는 캔버스 면적의 최소 70%를 활용해야 합니다.
| 슬라이드 타입 | 가로 모드 | 세로 모드 |
|---|---|---|
| Content | 불릿 포인트 3–4개 | 불릿 포인트 4–5개 |
| Code | 최소 4줄 + 주석 | 최소 6줄 + 주석 |
| Title | 항상 부제목을 포함하세요 | |
쇼츠 (Portrait-1080p)
- 60초 기준 최대 8–10개 요소
- 첫 슬라이드 = 훅 (최대 5단어) + 설명적인 부제목
- 마지막 슬라이드 = CTA 또는 인상적인 마무리 + 태그라인
- 콘텐츠 슬라이드당 불릿 5–6개, 코드 슬라이드에 6–10줄
- 모든 콘텐츠 슬라이드에서
content+bulletPoints를 함께 사용하세요
해상도 프리셋
기본값: Landscape-1080p. 에이전트가 키워드를 기반으로 자동 선택합니다 — "reels", "shorts", "TikTok"은 Portrait-1080p를 트리거하고, "Instagram"은 Square-1080p를 트리거합니다.
컴포넌트 라이브러리
Remotion 프로젝트에는 11개의 슬라이드 컴포넌트와 부가 기능이 포함되어 있습니다. 각 컴포넌트는 타임라인 JSON의 type 값에 매핑됩니다.
슬라이드 컴포넌트
| 컴포넌트 | 속성 | 용도 |
|---|---|---|
TitleSlide | title, subtitle, animation? | 오프닝 / 클로징 슬라이드 |
ContentSlide | header, content, bulletPoints, animation? | 본문 콘텐츠 |
CodeSlide | code, language, title, animation? | 코드 데모 |
DiagramSlide | src, title, caption, fit, animation? | 이미지 / 다이어그램 |
StatSlide | title, stats[] (value/suffix/label/trend/decimals) | KPI / 카운트업 |
QuoteSlide | quote, author?, source? | 인용문 |
ComparisonSlide | title, left{label,items,accent}, right{...} | 좌우 비교 |
VideoSlide | src, title?, startFrom?, playbackRate?, loop? | 인라인 비디오 |
GifSlide | src, title?, fit? | 애니메이션 GIF |
LottieSlide | src, title? | Lottie 애니메이션 |
ChartSlide | chartType, title, data{labels,datasets} | 막대 / 파이 / 꺾은선 차트 |
Caption | text, position, designTheme? | 타이밍 자막 |
기능
| 기능 | 세부 사항 |
|---|---|
| Surface Card | 콘텐츠 슬라이드에 글래스모피즘 래퍼를 적용합니다. meta.theme.card로 커스터마이즈할 수 있습니다. |
| 애니메이션 | 요소별 선택 사항: { enter: "scale-in", exit: "fade-out" }. 진입: scale-in, fade-in, slide-up, none. 퇴장: scale-out, slide-down, fade-out, none. |
| 트랜지션 | fade, slide, wipe, flip, clock-wipe. 선택적으로 timing: "spring" 사용 가능. slide/wipe는 direction을 받습니다. |
| 한국어 폰트 | NotoSansKR이 본문 기본 폰트로 로드됩니다. 스택: NotoSansKR, Outfit, sans-serif. |
| 차트 | bar (순차 증가), pie (스윕), line (드로우 온). 순수 SVG, 외부 라이브러리 불필요. |
| 오디오 | fadeInSec / fadeOutSec, loop, trimStartSec. |
TTS 통합
세 가지 TTS 제공자를 사용할 수 있습니다. 기본값은 Gemini입니다. 파이프라인은 타임라인 요소의 narration 필드를 자동 감지하여 컷별 오디오 파일을 생성합니다.
| 제공자 | ID | 기본 음성 | 장점 | 환경 변수 키 |
|---|---|---|---|---|
| Gemini | gemini | Kore | 30개 음성, 프롬프트로 톤 조절 | GEMINI_API_KEY |
| Supertone | supertone | Andrew | 6가지 감정 스타일, 최고 한국어 품질 | SUPERTONE_API_KEY |
| Supertonic | supertonic | M1 | 0.22초 생성, 무료, 오프라인 | 없음 |
초안-최종 워크플로우
timeline.draft.json에narration과 선택적voiceControl을 요소별로 작성합니다.- 파이프라인이 narration 필드를 자동 감지하여 컷별 오디오를 생성합니다.
audio[]항목과 보정된durationSec가 포함된timeline.final.json을 생성합니다.- 최종 타임라인이 동기화된 오디오와 함께 렌더링됩니다.
나레이션이 포함된 초안 타임라인
{
"elements": [
{
"id": "intro",
"type": "title",
"durationSec": 11,
"narration": "Welcome to the analysis report.",
"voiceControl": {
"tonePrompt": "Calm, professional news anchor tone"
},
"props": {
"title": "Tech Trends",
"subtitle": "2026 Edition"
}
}
]
}
재생 시간 추정
- 한국어: ~6.5자/초 —
Math.ceil(narration.length / 6.5) + 0.5 - 최종
durationSec는 TTS 생성 후 ffprobe 측정을 통해 자동 보정됩니다
렌더링 검증 — 3단계 게이트
렌더링이 성공으로 인정되려면 세 가지 게이트를 모두 통과해야 합니다.
| 게이트 | 검사 항목 | 역할 |
|---|---|---|
| 1 | 정책 — 로그에 금지된 엔진이 없는지 확인 | 보조 |
| 2 | 실행 — remotion render 종료 코드 0 | 주요 |
| 3 | 아티팩트 — ffprobe로 재생 시간, 코덱, 해상도 검증 | 최종 판정 |
node scripts/validate-artifact.mjs /tmp/remotion-render/TimelineVideo.mp4 --preset Landscape-1080p
remotion render가 종료 코드 0으로 완료되더라도, 아티팩트가 ffprobe 검증(올바른 해상도, 코덱, 재생 시간)을 통과해야 렌더링이 승인됩니다.
FFmpeg 패턴
FFmpeg는 Remotion 외부에서 확정적 컷, 일괄 처리, 전처리를 담당합니다. 이 패턴들은 비디오 파이프라인 내에서 사용할 수 있습니다.
타임스탬프로 구간 추출
ffmpeg -i raw.mp4 -ss 00:12:30 -to 00:15:45 -c copy segment_01.mp4
편집 결정 목록에서 일괄 컷
#!/bin/bash
# cuts.txt 형식: start,end,label
while IFS=, read -r start end label; do
ffmpeg -i raw.mp4 -ss "$start" -to "$end" -c copy "segments/${label}.mp4"
done < cuts.txt
구간 병합
for f in segments/*.mp4; do echo "file '$f'"; done > concat.txt
ffmpeg -f concat -safe 0 -i concat.txt -c copy assembled.mp4
빠른 편집을 위한 프록시 생성
ffmpeg -i raw.mp4 -vf "scale=960:-2" -c:v libx264 -preset ultrafast -crf 28 proxy.mp4
전사를 위한 오디오 추출
ffmpeg -i raw.mp4 -vn -acodec pcm_s16le -ar 16000 audio.wav
오디오 레벨 정규화
ffmpeg -i segment.mp4 -af loudnorm=I=-16:TP=-1.5:LRA=11 -c:v copy normalized.mp4
장면 감지
# 장면 전환 감지 (임계값 0.3 = 중간 감도)
ffmpeg -i input.mp4 -vf "select='gt(scene,0.3)',showinfo" -vsync vfr -f null - 2>&1 | grep showinfo
소셜 미디어 리프레이밍
# 16:9에서 9:16으로 (TikTok/Reels용 중앙 크롭)
ffmpeg -i input.mp4 -vf "crop=ih*9/16:ih,scale=1080:1920" vertical.mp4
# 16:9에서 1:1로 (Instagram용 중앙 크롭)
ffmpeg -i input.mp4 -vf "crop=ih:ih,scale=1080:1080" square.mp4
ElevenLabs 음성 (보조)
Remotion TTS 파이프라인 외부에서 전문 보이스오버가 필요한 경우, ElevenLabs를 직접 API로 사용할 수 있습니다. Gemini/Supertone이 제공하는 것 이상의 고품질 영어 나레이션, 음성 복제, 또는 감정 제어가 필요할 때 사용하세요. ELEVENLABS_API_KEY가 필요합니다.
import os, requests
resp = requests.post(
f"https://api.elevenlabs.io/v1/text-to-speech/<voice_id>",
headers={
"xi-api-key": os.environ["ELEVENLABS_API_KEY"],
"Content-Type": "application/json"
},
json={
"text": "Your narration text here",
"model_id": "eleven_turbo_v2_5",
"voice_settings": {"stability": 0.5, "similarity_boost": 0.75}
}
)
with open("voiceover.mp3", "wb") as f:
f.write(resp.content)
최종 폴리싱 (Descript / CapCut)
코드 기반 렌더링이 잘 처리하지 못하는 작업에 대해서는 전통적인 편집기를 마지막 단계에서 사용하세요:
- 페이싱 — 너무 빠르거나 느린 컷 조정
- 자막 — 자동 생성 후 수동 정리
- 색 보정 — 기본 보정 및 분위기 설정
- 최종 오디오 믹스 — 음성, 음악, 효과음 레벨 밸런스
- 내보내기 — 플랫폼별 형식 및 품질 설정
의존성
비디오 파이프라인에는 Node.js, pnpm, FFmpeg, 그리고 Chromium 바이너리(Remotion에 의해 자동 설치)가 필요합니다.
node --version
npm install -g pnpm
brew install ffmpeg
remotion browser ensure
ensure-remotion.mjs 부트스트랩 스크립트에 의해 자동 설치환경 변수
| 변수 | 용도 | 필수 여부 |
|---|---|---|
GEMINI_API_KEY | Gemini TTS 제공자 | 예 (기본 Gemini TTS 사용 시) |
SUPERTONE_API_KEY | Supertone TTS 제공자 | Supertone 사용 시에만 |
ELEVENLABS_API_KEY | ElevenLabs 보조 TTS | ElevenLabs 사용 시에만 |
GOOGLE_APPLICATION_CREDENTIALS | Vertex AI 인증 | gcloud auth의 대안 |
부트스트랩
# 최초 설정: 패키지 설치 및 Chromium 확인
node scripts/ensure-remotion.mjs
# 설정 확인
cd remotion-project && pnpm exec remotion studio
프로젝트 구조
skills_ref/video/
+-- SKILL.md
+-- reference/ # visual-quality.md, tts-integration.md, components.md
+-- scripts/
| +-- pipeline.mjs # CLI 진입점 (동기/비동기/TTS)
| +-- tts.mjs # TTS 오케스트레이터 (멀티 제공자)
| +-- tts-providers/ # gemini.mjs, supertone.mjs, supertonic.mjs
| +-- ensure-remotion.mjs # 런타임 부트스트랩
| +-- validate-artifact.mjs # 게이트 3: ffprobe 검증
| +-- presets.mjs # 해상도 프리셋 (ESM)
+-- remotion-project/
+-- public/example-timeline.json
+-- src/
+-- components/ # 11개 슬라이드 컴포넌트 + barrel
+-- timeline/ # JSON-to-React 엔진
"~해줘" 사용 예시
자연어로 비디오 작업을 요청하는 실제 예시입니다. 한국어와 영어 모두 사용할 수 있습니다.
/tmp/remotion-render/TimelineVideo.mp4.narration과 voiceControl 필드를 추가합니다. 기본 Gemini 제공자(음성: Kore)로 TTS 파이프라인을 실행하여 컷별 오디오를 생성하고, 동기화된 재생 시간이 포함된 timeline.final.json을 생성합니다.ffmpeg -i input.mp4 -vf "crop=ih*9/16:ih,scale=1080:1920" vertical.mp4.validate-artifact.mjs를 실행하여 ffprobe로 재생 시간, 코덱, 해상도를 예상 프리셋과 대조하여 검증합니다.문제 해결
Remotion Chromium을 찾을 수 없음
remotion render가 브라우저 오류로 실패하면, Chromium이 설치되어 있는지 확인하세요:
node scripts/ensure-remotion.mjs
# 또는 수동으로:
cd remotion-project && pnpm exec remotion browser ensure
FFmpeg를 찾을 수 없음
FFmpeg와 ffprobe를 설치하세요:
# macOS
brew install ffmpeg
# Ubuntu/Debian
sudo apt-get install -y ffmpeg
# 설치 확인
ffmpeg -version && ffprobe -version
TTS 인증 오류 발생
선택한 제공자에 맞는 환경 변수가 설정되어 있는지 확인하세요:
# Gemini (기본)
echo $GEMINI_API_KEY
# Supertone
echo $SUPERTONE_API_KEY
# Supertonic은 키가 필요 없습니다 (오프라인 실행)
렌더링 출력이 비어 있거나 손상됨
아티팩트 검증기를 실행하여 진단하세요:
node scripts/validate-artifact.mjs /tmp/remotion-render/TimelineVideo.mp4 --preset Landscape-1080p
게이트 3이 실패하면 Remotion 로그에서 렌더링 오류를 확인하세요. 일반적인 원인: 누락된 폰트, 잘못된 타임라인 JSON, 또는 대규모 컴포지션에서의 메모리 부족.
TTS 후 재생 시간 불일치
파이프라인은 TTS 생성 후 ffprobe 측정을 통해 durationSec를 자동 보정합니다. 재생 시간이 여전히 맞지 않는 경우, 나레이션 텍스트 길이가 추정 공식에 부합하는지 확인하세요: 한국어 텍스트의 경우 Math.ceil(text.length / 6.5) + 0.5.