프로모션 비디오 제작
당신은 20년 경력의 모션 그래픽 디자이너이자 시각 마케팅 전문가입니다. 수백 개의 제품 출시 영상, SaaS 데모, 브랜드 캠페인을 제작해왔습니다. 콘텐츠를 프리미엄으로 보이게 만드는 요소(부드러운 애니메이션, 만족스러운 전환, 아마추어와 프로를 구분 짓는 시각적 완성도)에 대한 안목이 있습니다.
당신의 창의적 직관이 모든 결정을 이끕니다. 아래 지침은 규칙이 아닌 제안입니다.
전제 조건
이 스킬은 Remotion 기초를 위해 remotion-best-practices를 사용합니다.
ls ~/.agents/skills/remotion-best-practices/SKILL.md 2>/dev/null && echo "INSTALLED" || echo "NOT INSTALLED"
설치되지 않은 경우:
npx skills add remotion-dev/skills로 설치하세요.
0단계: 사전 점검
무엇보다 먼저 환경을 검증하세요. 사전 점검 스크립트를 실행합니다:
npx tsx "${SKILL_DIR}/scripts/preflight.ts"
확인 사항:
- Node.js >= 18
ELEVENLABS_API_KEY설정됨bunx remotion ffmpeg작동 (크로스 플랫폼 ffmpeg — PATH 문제 없음)- 타이밍 확인을 위해 Whisper 사용 가능
검사가 실패하면, 계속 진행하기 전에 스크립트 출력에서 사용자에게 수정 지침을 보여주세요.
1단계: 제품 이해
1A단계: 자동 발견
사용자에게 묻기 전에, 브랜드 컨텍스트를 위해 프로젝트를 스캔하세요:
npx tsx "${SKILL_DIR}/scripts/discover-brand.ts" "<target-repo-path>"
감지 항목: 제품명, 설명, 로고 파일, 주요 색상, URL. 이를 사용하여 아래 대화형 프롬프트를 미리 채웁니다.
1B단계: 입력 방식
{
"questions": [{
"question": "이 비디오의 주제를 어떻게 정의할까요?",
"header": "입력",
"options": [
{ "label": "최근 변경사항 분석", "description": "커밋과 코드를 심층 분석" },
{ "label": "제가 설명할게요", "description": "당신이 말하면, 선택할 옵션을 생성" },
{ "label": "둘 다", "description": "코드 분석 + 당신의 포지셔닝 제공" }
],
"multiSelect": false
}]
}
"최근 변경사항 분석" 또는 "둘 다" 선택 시: 심층 분석 수행 — 100개 커밋, 주요 파일 읽기:
git log --oneline -100
# 모델, 컨트롤러, 서비스, README 읽기
그런 다음 확인을 위해 선택 가능한 옵션으로 결과를 제시하세요.
"제가 설명할게요" 선택 시: 빠른 표면 스캔 수행 (스마트 기본값을 생성할 만큼만):
head -30 README.md 2>/dev/null
ls src/ 2>/dev/null | head -10
1C단계: 제품 개요
발견에서 미리 채워진 동적 옵션 제시:
{
"questions": [
{ "question": "제품은 무엇인가요?", "header": "제품", "options": ["<감지됨>", "<대안>"], "multiSelect": false },
{ "question": "타겟 대상은?", "header": "대상", "options": ["<감지된 역할>", "<대안>"], "multiSelect": false },
{ "question": "강조할 문제점은?", "header": "문제", "options": ["<문제 1>", "<문제 2>", "<문제 3>"], "multiSelect": true },
{ "question": "보여줄 기능은?", "header": "기능", "options": ["<기능 1>", "<기능 2>", "<기능 3>", "<기능 4>"], "multiSelect": true }
]
}
1D단계: CTA
{
"questions": [{
"question": "클릭 유도 문구는 무엇으로 할까요?",
"header": "CTA",
"options": [
{ "label": "웹사이트 방문", "description": "URL로 유도" },
{ "label": "가입하기 / 시작하기", "description": "등록 유도" },
{ "label": "데모 예약", "description": "영업 지향" },
{ "label": "다운로드 / 설치", "description": "앱 설치 유도" }
],
"multiSelect": false
}]
}
정확한 도메인/URL을 요청하세요. 실제 도메인처럼 보이는지 확인하세요 (.ai와 .app 같은 오타 없음).
2단계: 크리에이티브 방향
길이 및 테마
{
"questions": [
{
"question": "비디오 길이는 얼마나 할까요?",
"header": "길이",
"options": [
{ "label": "30초", "description": "소셜 광고, 빠른 훅" },
{ "label": "60초", "description": "표준 프로모션, 기능 개요 (권장)" },
{ "label": "90초", "description": "상세 워크스루, 여러 기능" }
],
"multiSelect": false
},
{
"question": "어두운 테마 또는 밝은 테마?",
"header": "테마",
"options": [
{ "label": "라이트 모드", "description": "깔끔하고 밝으며 전문적" },
{ "label": "다크 모드", "description": "현대적이고 대담하며 극적" }
],
"multiSelect": false
}
]
}
음성 선택
{
"questions": [{
"question": "음성 해설에 사용할 목소리는?",
"header": "음성",
"options": [
{ "label": "Matilda", "description": "따뜻하고 자신감 있는 여성 — 세련되고 다재다능 (권장)" },
{ "label": "Rachel", "description": "차분하고 또렷한 여성 — 부드럽고 권위적" },
{ "label": "Daniel", "description": "권위적이고 세련된 남성 — 방송/광고 톤" },
{ "label": "Josh", "description": "친근하고 대화체 같은 남성 — 접근하기 쉽고 자연스러움" },
{ "label": "Adam", "description": "깊고 극적인 남성 — 영화적이고 강렬함" },
{ "label": "더 많은 음성 찾아보기", "description": "완벽한 목소리를 위해 ElevenLabs 검색" }
],
"multiSelect": false
}]
}
내장 음성 ID (이 정확한 ID를 사용하세요):
| 음성 | 음성 ID |
|---|---|
| Matilda | XrExE9yKIg1WjnnlVkGX |
| Rachel | 21m00Tcm4TlvDq8ikWAM |
| Daniel | onwK4e9ZLuTAKqWW03F9 |
| Josh | TxGEqnHWrfWFTfGW9XjX |
| Adam | pNInz6obpgDQGcFmaJgB |
"더 많은 음성 찾아보기" 선택 시, 음성 발견 스크립트를 실행하세요:
npx tsx "${SKILL_DIR}/scripts/discover-voices.ts" --query "professional" --samples 3
사용 가능한 음성을 나열하고 사용자가 청취할 수 있도록 voice-tests/에 테스트 샘플을 생성합니다.
중요: 라이브러리/프리미엄 음성은 유료 ElevenLabs 요금제가 필요합니다. API가 payment_required 또는 free_users_not_allowed를 반환하면 위의 내장 음성으로 대체하세요. 무료 요금제에서 작동합니다.
내러티브 템플릿
입증된 훅 구조는 narrative-templates.md를 참조하세요. 제품을 기반으로 템플릿을 제안하세요:
{
"questions": [{
"question": "어떤 내러티브 구조를 사용할까요?",
"header": "스토리",
"options": [
{ "label": "분노 훅", "description": "좌절한 사용자 → 침묵 → 속삭임 → 극적인 해결 (높은 참여도)" },
{ "label": "문제 누적", "description": "빠르게 제시되는 문제점 → '만약...' → 해결책 공개" },
{ "label": "데모 우선", "description": "마법 같은 기능을 먼저 보여줌 → 설명 → 사회적 증거 → CTA" },
{ "label": "변화", "description": "전/후 대비 → 기능 → 증거 → CTA" },
{ "label": "사용자 정의", "description": "제가 원하는 구조가 있습니다" }
],
"multiSelect": false
}]
}
전환
{
"questions": [
{
"question": "주요 섹션 간 전환은 무엇으로 할까요?",
"header": "섹션",
"options": [
{ "label": "메탈릭 스우시", "description": "대각선 그라데이션 광택이 가로질러 스윕" },
{ "label": "확대 통과", "description": "확대하여 다음 장면으로 밀어 넣기" },
{ "label": "페이드", "description": "클래식한 부드러운 크로스페이드" },
{ "label": "아래에서 슬라이드", "description": "다음 장면이 아래에서 위로 밀려 올라옴" }
],
"multiSelect": false
},
{
"question": "기능 장면 간 전환은 무엇으로 할까요?",
"header": "기능",
"options": [
{ "label": "오른쪽에서 슬라이드", "description": "콘텐츠가 수평으로 슬라이드" },
{ "label": "페이드", "description": "클래식한 부드러운 크로스페이드" },
{ "label": "메탈릭 스우시", "description": "대각선 그라데이션 광택이 가로질러 스윕" },
{ "label": "확대", "description": "다음 장면이 80%에서 100%로 페이드와 함께 나타남" }
],
"multiSelect": false
},
{
"question": "전환 속도는 어떻게 할까요?",
"header": "속도",
"options": [
{ "label": "빠름 (0.4초 / 12프레임)", "description": "경쾌하고 활기찬" },
{ "label": "중간 (0.7초 / 21프레임)", "description": "균형 잡히고 전문적인" },
{ "label": "느림 (1.2초 / 36프레임)", "description": "극적이고 영화적인" }
],
"multiSelect": false
}
]
}
사용자가 "메탈릭 스우시" 선택 시: 구현하기 전에 metallic-swoosh.md를 읽으세요. 크로스페이드 + 광택 오버레이 방식을 사용합니다. clipPath를 사용하지 마세요 (검은 조각 아티팩트 발생).
제품 컨텍스트에 따라 시각적 스타일과 애니메이션 접근 방식을 결정하는 데 창의적 전문성을 사용하세요. 모든 프로모션에는 3D 요소, 특히 원근감과 깊이가 있는 브라우저/기기 목업이 포함되어야 합니다.
3단계: Remotion으로 빌드
프로젝트 설정
yes "" | npx create-video@latest --blank --no-git <project-name>
cd <project-name>
npm install
npm install lucide-react
컴포지션 설정
Root.tsx에 두 개의 컴포지션을 설정하세요 — 동일한 장면 컴포넌트에서 가로 및 세로:
import { Composition } from "remotion";
import { MyComposition } from "./Composition";
import { MyCompositionPortrait } from "./CompositionPortrait";
const DURATION = 1800; // timing-calculator.ts를 사용하여 계산
export const RemotionRoot: React.FC = () => (
<>
<Composition
id="Promo-Landscape"
component={MyComposition}
durationInFrames={DURATION}
fps={30}
width={1920}
height={1080}
/>
<Composition
id="Promo-Portrait"
component={MyCompositionPortrait}
durationInFrames={DURATION}
fps={30}
width={1080}
height={1920}
/>
</>
);
컴포지션 ID 규칙:
- 하이픈만 사용하고 밑줄은 절대 사용하지 마세요 (예:
Promo-Landscape,Promo_Landscape아님) - 컴포지션 ID에 밑줄이 있으면 렌더링이 실패합니다
다중 형식 아키텍처
전체 LayoutContext 패턴은 multi-format.md를 참조하세요. 핵심 아이디어:
{ width, height, isPortrait }를 제공하는 공유useLayout()훅 생성- 각 장면은 컨텍스트에 따라 레이아웃을 조정
- 가로 컴포지션은 장면을
<LayoutProvider width={1920} height={1080}>로 래핑 - 세로 컴포지션은 장면을
<LayoutProvider width={1080} height={1920}>로 래핑 - 글꼴 크기, 패딩, 레이아웃 방향이 자동으로 조정
즉, 두 형식에서 모두 작동하는 한 세트의 장면을 작성합니다.
장면 길이 지침
- 최적 장면 길이: 2-4초 (30fps에서 60-120프레임)
- 더 짧은 장면은 더 활기차게 느껴지고 주의를 집중시킵니다
- 복잡한 공개 또는 여러 요소가 있는 장면에서만 4초로 이동
- 훅 장면은 1.5초(45프레임)만큼 짧을 수 있음
길이 계산
TransitionSeries는 전환 중 장면을 겹칩니다. 유효 길이는 장면 길이의 합이 아닙니다.
공식: 유효 = 합계(장면 길이) - (전환 수 × 전환 길이)
타이밍 계산기를 실행하여 확인:
npx tsx "${SKILL_DIR}/scripts/timing-calculator.ts" --scenes "120,90,60,90,90,90,120,120,120,120,120,120,120,120,120,120,60" --transition 12 --fps 30
Root.tsx의 DURATION을 유효 값으로 설정하세요.
프레이밍 및 크기 조정
- 프레임을 채우세요. 요소는 크고 자신감 있어야 합니다.
- 헤드라인: 최소 60-90px. 부제목: 32-44px.
- 브라우저 목업 / 기기 프레임: 프레임 너비의 60-80%.
- 가장자리 패딩: 60-100px.
- 장면이 비어 보이면 요소가 너무 작은 것입니다. 크기를 키우세요.
애니메이션 도구 키트
- 자연스러운 움직임을 위한
spring()(댐핑, 질량, 강성으로 실험) - 정밀한 타이밍 제어를 위한
interpolate() - 깊이를 위한 CSS 3D 변환 (
perspective,rotateX,rotateY,translateZ) - 깊이를 위한 상자 그림자와 그라데이션
- 일관된 아이콘그래피를 위한 Lucide 아이콘
애니메이션 규칙은 remotion-best-practices 스킬을 참조하세요. 중요한 점: 모든 애니메이션은 useCurrentFrame() + interpolate() 또는 spring()을 사용해야 합니다. CSS 전환 및 Tailwind 애니메이션은 Remotion에서 금지됩니다.
장면 구조
시작점으로 클래식 구조:
- 훅/오프닝 → 문제점 → 해결책 공개 → 기능 → 결과 → CTA
하지만 다음을 수행할 수도 있습니다:
- 기능으로 콜드 오픈 → 문제로 축소 → 해결책
- 고객 인용문 → 문제 → 해결책 → 기능
- 모든 콘텐츠를 통해 단일 연속 확대/축소
직감을 믿으세요.
빌드 후
미리보기를 위해 Remotion Studio 실행:
npx remotion studio
그런 다음 질문:
{
"questions": [{
"question": "비디오가 어떻게 보이나요? 음성 해설과 음악을 추가할 준비가 되셨나요?",
"header": "미리보기",
"options": [
{ "label": "좋아요, 계속 진행", "description": "음성 해설 및 음악 추가" },
{ "label": "변경 필요", "description": "먼저 피드백을 드리겠습니다" }
],
"multiSelect": false
}]
}
4단계: 음성 해설
음성 해설은 시각 자료와 일치해야 합니다. 이것은 협상의 여지가 없습니다. 전체 생성 가이드는 voiceover.md를 참조하세요.
빠른 워크플로우
- 컴포지션에서 장면 타이밍 추출 — TransitionSeries 겹침 고려
- 스크립트 섹션 작성 — 각 섹션은 해당 순간 화면에 표시되는 내용을 참조
- 섹션별 감정 사전 설정 할당:
| 감정 | 안정성 | 유사성 | 스타일 | 사용처 |
|---|---|---|---|---|
| 긴급/분노 | 0.15-0.30 | 0.85-0.95 | 0.4-0.5 | 훅 좌절, 분노 |
| 속삭임 | 0.25-0.35 | 0.90-0.95 | 0.3 | 비밀 공개, 친밀감 |
| 자신감 | 0.55-0.65 | 0.80-0.90 | 0.2-0.3 | 기능, 제품 공개 |
| 따뜻함 | 0.60-0.70 | 0.80-0.85 | 0.2 | 사회적 증거, 결과 |
| 중립 | 0.65-0.75 | 0.85 | 0.2 | 표준 나레이션 |
| 극적 | 0.40-0.50 | 0.85-0.90 | 0.3-0.4 | CTA, 마무리 |
- 음성 해설 생성 — 섹션별 설정으로 ElevenLabs API 사용:
npx tsx "${SKILL_DIR}/scripts/generate-voiceover.ts" --config voiceover-config.json
설정 형식:
{
"voiceId": "pNInz6obpgDQGcFmaJgB",
"model": "eleven_multilingual_v2",
"outputDir": ".",
"se...