숏폼 비디오 (Short-Form Video)
스와이프를 견디는 9:16 비디오를 설계하세요. 숏폼은 작은 론칭 필름이 아니라 **유지 기계(Retention Machine)**입니다: 첫 1초를 획득하는 후크(Hook), 몇 초마다 주의를 재설정하는 패턴 인터럽트(Pattern Interrupt), 그리고 종종 100% 이상의 시청 시간을 벌어주는 루프(Loop)로 구성됩니다. 핵심은 완성도(Timing)이지 정교함(Polish)이 아닙니다.
사용 시점
- Reels / TikTok / YouTube Shorts (7–60초, 세로 9:16).
- 유지율 편집(Retention Editing): 이탈 지점 수정, 패턴 인터럽트 추가, 템포 조정.
- 후크, 매끄러운 루프, 재사용 가능한 숏폼 템플릿 (하나의 디자인으로 여러 주제).
스토리 구조 (유지율 계약, The Retention Contract)
숏폼 스토리텔링은 시청자의 엄지손가락과의 계약입니다: 매 초마다 다음 1초를 다시 벌어야 합니다. 내러티브는 인트로에서 앞으로 나아가는 것이 아니라 유지율 곡선에서 거꾸로 설계됩니다. 타임라인을 건드리기 전에 다음 사항들을 확정하세요.
- 비디오당 하나의 아이디어. 숏폼은 정확히 하나의 페이오프를 전달합니다. 두 번째 아이디어는 주의를 분산시키고 곡선이 중간에 처지게 만듭니다. 그러면 두 번째 비디오로 만드세요. 한 문장으로 핵심을 말할 수 없다면 아직 숏폼이 준비되지 않은 것입니다.
- 처음 약 3초 안에 루프를 열고, 마지막에 닫으세요. 후크는 질문이나 갭(열린 루프)을 제기하고, 페이오프가 그에 답합니다. 시청자는 루프가 열려 있기 때문에 머물러 있습니다. 그러니 절대 일찍 답하지 말고, 설정 아래에 페이오프를 묻지 마세요.
- 데드 에어(Dead air) 없음. 모든 비트는 아이디어를 발전시키거나 주의를 재설정해야 합니다. 둘 다 하지 않는 것은 모두 잘라내세요. 침묵, 느린 램프, 목을 풀고 시작하는 인트로("안녕하세요 여러분, 이 비디오에서는…")는 시청자가 스와이프하는 지점입니다.
- 왜 '컷'이 아니라 '곡선'이 작업 단위인가. 알고리즘은 초당 유지율 곡선을 평평하게 유지하는 모든 것을 배포합니다. 곡선을 평평하게 만드는 "좋은" 편집은 곡선을 유지하는 못생긴 편집보다 못합니다. 당신은 곡선을 편집하는 것이며, 후크는 그 이후의 모든 것을 좌우합니다. 후크를 먼저 수정하세요.
내러티브 척추(후크 → 설정 → 본문 → 페이오프/루프 아크, 아래 표에서 예산 배정):
| 단계 | 스토리 역할 | 놓칠 때의 실패 |
|---|---|---|
| 후크(Hook) | 루프 열기, 페이오프 약속 | 처음 3초 내 스와이프 |
| 긴장 유지(Tension hold) | 본문 전체에 갭 유지 | 중간 지루함, 중간 이탈 |
| 페이오프(Payoff) | 루프 닫기 — 전달된 하나의 아이디어 | "시간 낭비", 공유 없음 |
| 루프/CTA | 프레임 0으로 피드백 또는 하나의 명확한 요청 | 재시청 없음, 행동 없음 |
(유지율 아크 표는 아래에서 각 단계에 초를 할당합니다. 이 섹션은 그 뒤에 있는 내러티브 논리와 순서입니다. 후크 문법은 후크 유형을 나열합니다.)
모든 것을 움직이는 하나의 지표
유지율이지, 제작 가치(Production value)가 아닙니다. 알고리즘은 시청자를 붙잡는 것을 배포합니다. 약 87%는 3초 안에 머물거나 스와이프하기로 결정하며, 배포 기준은 70% 이상의 평균 시청 완료율 근처에 있습니다 (Shorts 약 73%, TikTok 약 78%, Reels 약 65%). 아래의 모든 결정은 그 곡선과 트레이드오프 관계에 있습니다. 0:04에 지루하게 만드는 완벽한 샷은 시청자를 붙잡는 못생긴 샷에 패배합니다.
유지율 아크 (The Retention Arc)
| 비트 | 역할 | 예산 (20초 숏폼 기준) |
|---|---|---|
| 후크 (0–1초) | 열린 루프를 만드는 한 프레임 + 한 대사 | 0–1초 |
| 설정 | 왜 봐야 하는지 설명 — 약속, 이해관계, 또는 갭 | 1–4초 |
| 본문 | 비트 단위로 가치 전달; 비트당 하나의 아이디어 | 4–17초 |
| 페이오프/루프 | 루프 닫기 — 또는 프레임 0으로 피드백 | 17–20초 |
본문만 확장하고, 후크는 절대 확장하지 마세요. 60초 숏폼은 더 긴 본문과 더 많은 비트를 갖습니다. 동일한 1초 후크를 유지합니다.
후크 문법 (첫 약 1초)
후크는 뇌가 닫아야 하는 호기심 갭을 여는 문장과 시각물의 조합입니다. 하나의 패턴을 선택하고 확정하세요:
| 후크 유형 | 형태 | 가장 적합한 경우 |
|---|---|---|
| 열린 루프(Open loop) | "당신의 X가 계속 Y하는 이유는…" (답변 지연) | 대부분의 콘텐츠 |
| 직접 약속(Direct promise) | "30초 안에 ___하는 3가지 방법" | 교육 / 리스트 |
| 패턴 인터럽트(Pattern interrupt) | 프레임 1에서 스냅줌 / 휩팬 / 시각적 불일치 | 엔터테인먼트 |
| 부정(Negation) | "___ 하지 마세요" / "당신은 ___가 틀렸습니다" | 강한 의견 |
두 가지 규칙: 후크 대사는 프레임 1까지 화면에 텍스트로 표시되어야 하고 (85%가 음소거 시청), 가장 눈에 띄는 시각물도 첫 프레임이어야 합니다. 절대 느린 페이드인을 사용하지 마세요. 강한 시작 프레임을 유지하고, 검은 화면에서 페이드 업하지 마세요.
패턴 인터럽트 및 컷 리듬
패턴 인터럽트는 주의를 재설정하는 모든 변화입니다: 하드 컷, 줌 펀치, B-롤 삽입, 음향 효과, 캡션 팝, 또는 앵글 변화. 숏폼에서는 밀도가 높습니다 — 약 2~4초마다 시각적 변화. 약 4초마다 인터럽트가 있는 비디오는 약 58% 유지율을 보이는 반면, 정적인 토킹 헤드는 약 41%입니다. 치명적인 것은 평평한 중간 구간입니다: TikTok은 시청 완료 곡선이 평평해지면 배포를 제한하므로, 절대 에너지가 낮은 테이크로 본문을 연결하지 마세요.
// 모든 인터럽트를 벽시계가 아닌 FRAME 기준으로 구동합니다. 결정론적으로 렌더링됩니다.
import { useCurrentFrame } from "remotion";
const fps = 30;
const cuts = [0, 1.2, 3.0, 5.4, 8.0, 11.2, 14.0]; // 초 — 의도적으로 불규칙하게
const frame = useCurrentFrame();
const shot = cuts.findIndex((t, i) => frame < (cuts[i + 1] ?? Infinity) * fps);
간격을 다양하게 하세요. 메트로놈은 지루함으로 읽히고, 불규칙한 컷은 추진력으로 읽힙니다. 펀치인 줌은 새로운 푸티지가 필요 없는 가장 저렴한 인터럽트입니다:
import { useCurrentFrame, interpolate, spring, useVideoConfig } from "remotion";
const PunchIn = ({ at, children }) => {
const frame = useCurrentFrame(); const { fps } = useVideoConfig();
const s = spring({ frame: frame - at * fps, fps, config: { damping: 12, stiffness: 200 } });
const scale = interpolate(s, [0, 1], [1, 1.12]); // 비트에 맞춰 112%로 스냅
return <div style={{ transform: `scale(${scale})`, transformOrigin: "50% 45%" }}>{children}</div>;
};
자막 (Captions)
대부분의 시청자가 음소거 상태로 시청하므로, 화면 자막은 선택이 아닌 필수입니다. 자막은 콘텐츠를 전달하고 각 구문이 팝인될 때 패턴 인터럽트로도 작용합니다. 줄당 4–7단어, 높은 대비, 안전 영역 내에 유지하세요. 여기서 자막 애니메이션을 다시 구현하지 마세요 — 단어별 타이밍, 노래방 하이라이트, 스타일링을 위해 caption-animation 스킬을 사용하세요. 이 스킬은 자막을 유지율 타임라인과 9:16 안전 영역 내에만 배치합니다.
루프 및 재시청
매끄러운 루프는 각 재시청을 새로운 시청 시간으로 계산합니다. 깔끔한 8초 루프를 3번 시청하면 300% 시청 완료율로, 가장 강력한 신호입니다. 두 가지 기술: 마지막 프레임을 첫 번째 프레임과 일치시키고 (동일한 구도, 위치, 색상) 컷이 보이지 않게 하며, 문장 루프를 작성합니다. 후크가 프레임 0으로 다시 피드백되도록 구성합니다 ("…그래서 내가 절대 그러지 않는 이유는 — " → 시작 부분으로 루프). 재시청에 가장 좋은 길이는 약 7–15초입니다.
9:16 안전 영역
플랫폼 UI가 텍스트나 얼굴을 가리지 않도록 범용 안전 영역 안에 구성하세요.
| 영역 | 픽셀 (1080×1920) | 피할 것 |
|---|---|---|
| 범용 안전 (모든 플랫폼) | 중앙 900×1400 | 그 밖의 중요한 모든 것 |
| 상단 | 약 120px 확보 | 프로필 / 사운드 UI |
| 하단 | 약 320px 확보 | 자막, CTA, 해시태그, 오디오 바 |
| 오른쪽 | 약 120px 확보 | 좋아요 / 댓글 / 공유 레일 |
후크 텍스트와 주요 피사체를 중앙 900×1400 상자 안에 넣으세요. 편집기에서 비어 보이더라도 하단 약 320px는 확보하세요. 플랫폼이 자체 자막과 버튼을 그리는 영역입니다.
출력 체크리스트
- 후크 대사가 프레임 1까지 화면 텍스트로 표시됨; 가장 강력한 시각물이 첫 프레임 (페이드 인 없음).
- 처음 약 4초 내에 하나의 열린 루프/약속 설정.
- 약 2~4초마다 시각적 패턴 인터럽트; 간격이 불규칙함; 평평한 중간 없음.
- 자막 있음 (
caption-animation을 통해), 4–7단어, 안전 영역 내부. - 루프 닫힘 — 첫 번째/마지막 프레임 일치 또는 프레임 0으로 피드백되는 문장.
- 중앙 900×1400 상자 내부에 구성됨; 하단 320px / 상단 120px / 오른쪽 120px 확보.
- 모든 애니메이션 값이
useCurrentFrame()에서 파생됨 — CSS/라이브러리 타이머 없음.
전달 및 검증 (렌더링된 스틸 → MP4)
패키징된 도우미 (
scripts/):scripts/contact-sheet.sh sheet.png f-hook.png f-mid.png f-end.png로 스틸을 타일링한 다음,scripts/probe-mp4.sh out.mp4 [WxH] [fps]로 인코딩을 확인하세요.scripts/README.md를 참조하세요.
숏폼은 Remotion 컴포지션(<Composition> + zod schema + defaultProps)으로 제공됩니다. 모든 컷, 펀치인, 인터럽트는 Date.now() / Math.random() / 타이머가 아닌 useCurrentFrame()으로 구동됩니다. 결과물 = out/*.mp4 + 프로젝트 (주제별 재렌더링). 9:16 세로 (1080×1920)가 기본입니다.
루프 검증 — 스틸 렌더링 → 검사 → 인코딩. 세 가지 프레임이 유지율을 좌우하는 세 가지를 테스트합니다: 후크, 페이싱, 루프 이음새.
# 후크 / 본문 중간 / 마지막 프레임에서 스틸 — SHIPPED PROPS 사용 (기본값이 아닌 실제 주제)
npx remotion still Short out/f-hook.png --frame=10 --props='{"topic":"...","hook":"..."}' # ~처음 3초가 즉시 읽혀야 함
npx remotion still Short out/f-mid.png --frame=N --props='{"topic":"...","hook":"..."}'
npx remotion still Short out/f-end.png --frame=L --props='{"topic":"...","hook":"..."}' # L = durationInFrames-1
# 각 PNG 검사:
# - HOOK 프레임 (~프레임 0 / 처음 3초): 후크 대사가 화면 텍스트로 즉시 읽혀야 함; 가장 강력한 시각물이 이미 올라와 있어야 함 (페이드 업 없음)
# - LOOP 이음새: f-hook(프레임 0)과 f-end(마지막 프레임) 비교 — 보이지 않는 루프 컷을 위해 동일한 구도/위치/색상
# - 9:16 안전 영역: 후크 + 주요 피사체가 중앙 900x1400 상자 안에 있음; 상단 약 12%, 하단 약 20-35%(자막/CTA/오디오), 오른쪽 액션 레일에서 비어 있음
npx remotion render Short out/short.mp4 --props='{"topic":"...","hook":"..."}' # 스틸이 검증되면 한 번 인코딩
npx remotion render Short out/demo.gif --codec=gif # README 증명 클립
주제별 / 배치별: 모든 주제를 렌더링하기 전에 하나의 주제를 스틸로 검증하세요. durationInFrames/fps 값을 위해 npx remotion compositions를 사용하여 중간 및 마지막 프레임을 선택하세요.
마치기 전에:
- 스틸이 후크, 중간, 마지막 프레임에서 깔끔하게 렌더링됨 — 오류 없음.
- 후크 프레임이 즉시 읽힘 (화면 텍스트 + 가장 강력한 시각물이 앞쪽에, 페이드 업 없음); 첫 프레임과 마지막 프레임이 깔끔한 루프 이음새를 위해 일치함.
- 모든 확인된 프레임에서 후크 + 피사체 + 자막이 9:16 중앙 900×1400 안전 상자 안에 있음.
- 프레임 기반만 사용 —
Date.now()/Math.random()/ 타이머 없음; 컷이 불규칙하고, 평평한 중간 없음. - 실제 주제의 전달된 속성(Shipped props,
defaultProps아님)이 올바르게 렌더링됨; MP4 인코딩, GIF는 선택 사항.
참고 파일
references/retention-pacing.md— 완전히 실행 가능한 Remotion<Short>컴포지션: 불규칙한 컷이 있는 프레임 기반 샷 스케줄러, PunchIn 패턴 인터럽트, 화면 후크, 9:16 안전 영역 오버레이, 매끄러운 첫/마지막 프레임 루프. 후크 패턴 라이브러리, 유지율 곡선 디버깅 방법, 플랫폼별 안전 영역 맵, 템플릿×주제 배치 렌더링 패턴 포함.