短影片
工程化一個 9:16 的影片,讓它能在滑動中存活下來。短影片不是一個小型宣傳影片——它是一台留存機器:一個能贏得第一秒的鉤子、每隔幾秒就重置注意力的模式中斷,以及一個能讓觀看時間超過 100% 的循環。這門手藝講究的是時機,而非精緻度。
使用時機
- Reels / TikTok / YouTube Shorts(7–60 秒,垂直 9:16)。
- 留存率剪輯:修正流失點、加入模式中斷、緊湊節奏。
- 鉤子、無縫循環、可重複使用的短影片模板(一個設計,多個主題)。
故事結構(留存契約)
短影片的說故事是一份與觀眾拇指的契約:每一秒都必須重新贏得下一秒。敘事是從留存曲線反向建構的,而不是從開場白向前推進。在觸碰時間軸之前,先鎖定這些原則。
- 一個影片只有一個想法。 一支短片只承載一個回報。第二個想法會分散注意力,使曲線在中段下滑——改做成另一支影片。如果你無法用一句話說出唯一的重點,那它還不是一支短片。
- 在前 3 秒內開啟一個循環,並在最後關閉它。 鉤子提出一個問題或缺口(開放循環);回報則回答它。觀眾會留下來是因為循環是開放的——所以絕不要過早回答它,也絕不要把回報埋在鋪陳之下。
- 沒有留白。 每個節拍要不是推進想法,就是重置注意力。剪掉任何兩者都不是的內容。寂靜、緩慢的過渡、開場白(「嗨大家,在這支影片中…」)都是觀眾滑走的地方。
- 為什麼曲線,而不是剪輯,是工作的單位。 演算法會分發任何能維持每秒留存曲線平坦的內容;一個讓曲線變平的「好」剪輯,會輸給一個能讓曲線保持上升的醜陋剪輯。你在編輯的是曲線,而鉤子決定了之後的一切——先修正它。
敘事主線(鉤子 → 鋪陳 → 主體 → 回報/循環 的弧線)預算分配如下表:
| 階段 | 故事任務 | 失敗的後果 |
|---|---|---|
| 鉤子 | 開啟循環;承諾回報 | 在前 3 秒內被滑走 |
| 張力維持 | 在主體中保持缺口開放 | 中段平淡,中段流失 |
| 回報 | 關閉循環——唯一想法,確實傳達 | 「浪費我時間」,不分享 |
| 循環 / 行動呼籲 | 回到第 0 幀,或提出一個明確要求 | 沒有重播,沒有行動 |
(留存曲線 表為每個階段分配秒數;本節是背後的故事邏輯與順序。鉤子語法 列出了鉤子的原型。)
驅動一切的單一指標
留存率,而非製作價值。 演算法會分發任何能留住觀眾的內容;約有 87% 的觀眾在 3 秒內決定停留或滑走,而獲得分發的門檻接近 70% 以上的平均觀看完成率(Shorts 約 73%,TikTok 約 78%,Reels 約 65%)。以下的每個決定都是為了這個曲線。一個在 0:04 讓人無聊的完美鏡頭,會輸給一個能留住觀眾的醜陋鏡頭。
留存曲線
| 節拍 | 任務 | 預算(以 20 秒短片為例) |
|---|---|---|
| 鉤子(0–1 秒) | 一個畫面 + 一句話,創造一個開放循環 | 0–1 秒 |
| 鋪陳 | 兌現為什麼要看——承諾、利害關係、或缺口 | 1–4 秒 |
| 主體 | 以節拍傳遞價值;一個節拍一個想法 | 4–17 秒 |
| 回報 / 循環 | 關閉循環——或將其導回第 0 幀 | 17–20 秒 |
只擴展主體,絕不擴展鉤子。一支 60 秒的短片有更長的主體和更多節拍——但鉤子同樣是 1 秒。
鉤子語法(前 ~1 秒)
鉤子是一個句子 + 一個視覺元素,能開啟大腦需要關閉的好奇心缺口。選擇一種模式並堅持使用:
| 鉤子類型 | 形式 | 最適合 |
|---|---|---|
| 開放循環 | 「你的 X 一直 Y 的原因是…」(答案延遲) | 大多數內容 |
| 直接承諾 | 「3 種在 30 秒內 ___ 的方法」 | 教育 / 列表式 |
| 模式中斷 | 快放大 / 快速搖攝 / 第一個畫面中的視覺不匹配 | 娛樂 |
| 否定 | 「停止做 ___」 / 「你 ___ 錯了」 | 強烈觀點 |
兩個規則:鉤子句子要在第 1 幀就作為文字顯示在螢幕上(85% 的觀眾在靜音下觀看),而且最引人注目的視覺也必須是第一個畫面——絕不使用緩慢的淡入。保持一個有力的開場畫面;不要從黑色淡入。
模式中斷與剪輯節奏
模式中斷是指任何能重置注意力的變化:硬剪輯、縮放、插入 B-roll、音效、字幕彈出、或鏡頭角度變化。在短影片中,密度很高——每 ~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>;
};
字幕
大多數觀眾在靜音下觀看,因此螢幕上的字幕是必須的——它們承載內容,並在每個短語彈出時扮演模式中斷的角色。每行保持 4–7 個單詞,高對比度,並位於安全區域內。不要在實作字幕動畫——請使用 caption-animation 技能來處理逐字時機、卡拉 OK 高亮和樣式;此技能僅將字幕放置在留存時間軸和 9:16 安全區域內。
循環與重播
一個無縫循環會將每次重複觀看計為新的觀看時間——一個乾淨的 8 秒循環被觀看 3 次就是 300% 的觀看完成率,這是最強的信號。兩種技巧:將最後一幀與第一幀匹配(相同的構圖、位置、顏色),使剪輯不可見;並寫一個句子循環——將鉤子措辭成回報可以導回第 0 幀(「…這就是為什麼我從不 — 」→ 循環回到開頭)。最佳的重播長度約為 7–15 秒。
9:16 安全區域
在通用安全區域內構圖,避免平台 UI 遮蓋文字或人臉。
| 區域 | 像素(1080×1920) | 避免 |
|---|---|---|
| 通用安全(所有平台) | 中心 900×1400 | 任何重要內容在其之外 |
| 頂部 | 保持約 120px 空白 | 個人資料 / 音效 UI |
| 底部 | 保持約 320px 空白 | 字幕、行動呼籲、標籤、音訊列 |
| 右側 | 保持約 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)交付——每個剪輯、放大和中斷都由 useCurrentFrame() 驅動,絕不使用 Date.now() / Math.random() / 計時器。可交付成果 = out/*.mp4 + 專案(每個主題重新渲染)。預設為 9:16 垂直(1080×1920)。
驗證循環——渲染靜止幀 → 檢查 → 編碼。 三個幀測試決定留存率的三個要素:鉤子、節奏和循環接縫。
# 在鉤子 / 主體中部 / 最後一幀的靜止幀——使用已交付的 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%(字幕/行動呼籲/音訊)、右側操作欄
npx remotion render Short out/short.mp4 --props='{"topic":"...","hook":"..."}' # 靜止幀驗證後再編碼
npx remotion render Short out/demo.gif --codec=gif # README 證明片段
每個主題 / 批次:在渲染所有主題之前,先用靜止幀驗證 ONE 個主題。使用 npx remotion compositions 取得 durationInFrames/fps 來選擇中間和最後的幀。
在你完成之前:
- 靜止幀在鉤子、中間和最後一幀處都能順利渲染——沒有錯誤。
- 鉤子幀即時可讀(螢幕上的文字 + 最強的視覺在前,沒有淡入);第一幀與最後一幀匹配,以實現乾淨的循環接縫。
- 在每個檢查的幀中,鉤子 + 主體 + 字幕都位於 9:16 中心 900×1400 安全方塊內。
- 僅由幀驅動——沒有
Date.now()/Math.random()/ 計時器;剪輯不均勻,沒有平淡的中段。 - 真實主題的已交付 props(非
defaultProps)能正確渲染;MP4 已編碼,GIF 可選。
參考檔案
references/retention-pacing.md— 一個完整的可執行 Remotion<Short>組合:一個由幀驅動的鏡頭排程器,具有不均勻的剪輯、PunchIn 模式中斷、螢幕上的鉤子、9:16 安全區域覆蓋層、以及無縫的第一/最後一幀循環。此外還有鉤子模式函式庫、留存曲線除錯方法、每個平台的安全區域對應、以及模板×主題批次渲染模式。