簡報影片 是做什麼的?
將簡報或投影片大綱轉換為配有旁白、自動播放的動畫影片。每張投影片皆重建為動態圖像 — 包含逐步元素揭示、真實轉場,以及與旁白鎖定的時間控制 — 而非錄製某人點擊 PowerPoint 的螢幕畫面。
使用時機
- 需製作成自動播放影片的募資簡報、網路研討會或課程單元。
- 需要轉換為附旁白動畫投影片的要點式大綱。
- 投影片時間必須與旁白精確對齊(自動播放,無需點擊)的簡報。
重建,而非錄製
螢幕錄製會繼承簡報的靜態樣貌、滑鼠抖動及突兀的投影片切換。使用程式碼重建(Remotion)則能獲得:逐格確定的揭示效果、真正流暢的轉場、在任何解析度下都清晰的文字,以及由音訊長度驅動的投影片持續時間。簡報成為腳本;影片則是全新的產出物。
敘事流程:簡報是一個論點,而非 N 張投影片
在處理時間與動畫之前,先修正故事。自動播放的簡報影片沒有簡報者來補救中斷的論述 — 結構必須自行承載邏輯。先建立主軸;投影片只是其上的節拍。
- 一條主線(主軸)。 用一句話說明簡報的唯一重點。每張投影片都必須推進這句重點;如果某張投影片無法推進,就刪除它或移至附錄。觀看者應能在看過一次後,複述出這條主線。
- 每張投影片一個訊息。 一張投影片只傳達一個觀點 — 其標題就是那個觀點,以主張句呈現(例如「流失才是我們真正的成長稅」),而非標籤(例如「流失」)。兩個構想表示需要兩張投影片。
- 轉場承載邏輯,而不只是動畫。 投影片之間的切換應回答「然後呢?」— 因此、但是、也就是說、這是證據。讓動畫搭配邏輯動作:安靜的淡入用於「而且」,較大的章節推動用於「新的一幕」。沒有標記邏輯步驟的轉場只是裝飾。
- 以鉤子開場,以行動呼籲結尾。 第一張投影片需在約 5 秒內吸引注意力 — 一個尖銳的問題、驚人的數據、利害關係 — 而不是議程或商標展示。最後一張投影片明確說明你希望採取的一個行動(例如「開始試點」、「投資 200 萬美元換取 15% 股權」),並作為結論畫面靜止不動。
張力 → 解決(募資簡報主軸)
募資簡報是一齣戲劇,而非功能列表。按張力升高、然後解決的順序安排 — 每幕為下一幕鋪墊。
| 幕 | 節拍 | 任務 |
|---|---|---|
| 問題 | 「這裡出了什麼問題 / 有什麼風險」 | 創造讓觀看者感受到的張力 |
| 洞察 | 「這是大家都忽略的事」 | 非顯而易見的轉折;贏得解決方案的出場 |
| 解決方案 | 「這是我們的答案」 | 解決問題所建立的張力 |
| 證據 | 「這是它有效的原因」 | 進展、展示、數字 |
| 請求 | 「這是我們想要的」 | 一個具體的行動呼籲 |
在問題尚未確立之前,不要揭露解決方案 — 未經鋪墊的解決方案感覺像個功能,而非解脫。將你的投影片對應到這些幕;如果缺少某一幕,論點就有漏洞。
節奏:讓建構與旁白同步
主軸在時間中展開,因此螢幕上的建構與旁白必須同步推進 — 旁白掌握時鐘(下一節),揭示則根據它來安排,讓觀看者在旁白講述的同時閱讀台詞,絕不超前。每張投影片一個訊息讓這變得自然:一張投影片為一個觀點停留的時間,恰好等於旁白論述它的長度,然後轉場標記下一個邏輯步驟。如果某個觀點的旁白過長,就拆分投影片,而不是加速建構。
唯一規則:旁白掌握時鐘
每張投影片的長度,恰好等於其旁白音訊的時長,加上一點緩衝。 測量每個配音片段實際的持續時間,轉換為影格數,並以此作為投影片的長度。切勿憑感覺判斷「這張投影片大約 5 秒」— 這樣總是會偏移,導致音訊被截斷或過早結束。
import { getAudioDurationInSeconds } from "@remotion/media-utils";
// 在 Remotion 的 calculateMetadata() / 建構步驟中,每張投影片:
const sec = await getAudioDurationInSeconds(slide.audioUrl);
const HANDLE = 0.4; // 配音結束後的喘息空間
slide.durationInFrames = Math.ceil((sec + HANDLE) * fps);
接著,投影片內部的揭示也根據這個持續時間來安排 — 要點在旁白講到時出現,而非固定在時間網格上。
建構揭示:動畫用於揭示,而非裝飾
建構的目的是節奏:在旁白進行到該元素時才顯示它,讓觀看者閱讀的是正在被朗讀的台詞,而不是提前看到三行。讓元素逐一入場;保持標題、標誌和背景形狀靜止不動。
| 選擇 | 建議 | 原因 |
|---|---|---|
| 入場動畫 | 淡入 + 12–24px 上升 | 精緻、平靜;給人「到達」的感覺 |
| 每個元素持續時間 | 0.25–0.5 秒 | 快得足以流暢,慢得足以被察覺 |
| 要點間交錯 | 0.15–0.4 秒 | 依序出現,而非一大片文字 |
| 避免 | 飛入、旋轉、彈跳、打字機效果 | 感覺像裝飾;與旁白競爭 |
使用 useCurrentFrame() 來驅動交錯效果,使其與渲染的音訊保持同步(完整元件請參閱 references/slide-components.md)。
import { useCurrentFrame, interpolate, spring, useVideoConfig } from "remotion";
const Bullet: React.FC<{ index: number; children: React.ReactNode }> = ({ index, children }) => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
const STAGGER = 8; // 要點之間的影格數(30fps 下約 0.27 秒)
const enter = frame - index * STAGGER; // 每個要點較晚開始
const p = spring({ frame: enter, fps, config: { damping: 200 }, durationInFrames: 12 });
return (
<li style={{ opacity: p, transform: `translateY(${interpolate(p, [0, 1], [18, 0])}px)` }}>
{children}
</li>
);
};
投影片間轉場
使用 @remotion/transitions 的 <TransitionSeries> 來串聯投影片。每張投影片是一個帶有旁白衍生 durationInFrames 的 Sequence;Transition 則位於它們之間。保持轉場低調(短暫的淡入或溫和的滑動)— 內容才是主角,過於花俏的畫面切換很快就會讓人厭倦。
import { TransitionSeries, linearTiming } from "@remotion/transitions";
import { fade } from "@remotion/transitions/fade";
<TransitionSeries>
{slides.map((s, i) => (
<React.Fragment key={s.id}>
<TransitionSeries.Sequence durationInFrames={s.durationInFrames}>
<Slide {...s} />
</TransitionSeries.Sequence>
{i < slides.length - 1 && (
<TransitionSeries.Transition
timing={linearTiming({ durationInFrames: 15 })}
presentation={fade()}
/>
)}
</React.Fragment>
))}
</TransitionSeries>
僅在章節分隔時保留較大的轉場(滑動/推動)— 它標示「新主題」並值得額外的動畫。轉場會從相鄰兩張投影片借用影格,因此如果某張投影片的旁白必須完整播放,請將轉場長度加回投影片的預算中。請參閱 references/sequencing.md。
標題與章節分隔
標題卡和章節分隔為影片帶來節奏,並讓觀看者在資訊密集的投影片之間有喘息空間。將分隔頁視為其自身的短「投影片」:一個大的章節編號/字詞、章節標題、約 1.5–2 秒的停留,以及兩側更明顯的轉場。保持分隔頁的視覺語言(顏色、字型)一致,使其讀起來像是標點符號,而不是另一部不同的影片。
保持文字清晰易讀且符合品牌
投影片文字密集,因此可讀性是關鍵。
- 字級比例,而非簡報比例。 在筆記型電腦上觀看的簡報 ≠ 在資訊流中觀看的影片。在 1080p 解析度下,將主體文字提升至 ≥ 28–32px;標題則為 56–80px。如果一張投影片需要 16px 的註腳才能容納,則表示它需要被拆分為兩張投影片。
- 每張投影片一個想法。 如果某張投影片的旁白過長,請拆分它 — 切勿為了容納而縮小字型。
- 對比度 + 安全邊距。 維持 ≥ 4.5:1 的對比度;將所有內容保持在中心 90% 區域內,以確保能承受平台裁切。
- 將品牌鎖定在一個主題物件中。 顏色、字型、標誌和間距都放在一個
theme裡,這樣每張投影片都保持一致,而重新設計品牌也只需更改一行。
export const theme = {
bg: "#0B0B12", fg: "#F5F5F7", accent: "#6C5CE7",
font: "Inter, system-ui, sans-serif",
titlePx: 72, bodyPx: 30, maxWidthPct: 90,
} as const;
工作流程
- 大綱 → 腳本。 一張投影片 = 一個想法 + 確切的旁白台詞。這是最終的依據來源。
- 為每張投影片生成/錄製旁白。 每張投影片一個音訊檔案(TTS 或錄製)。
- 測量音訊 → 設定投影片持續時間。
getAudioDurationInSeconds→ 影格數(上述的規則)。 - 建構投影片元件,包含與
useCurrentFrame()同步的逐步揭示效果。 - 使用
<TransitionSeries>串聯;加入標題與章節分隔頁。 - 將每張投影片的音訊掛載在其
Sequence內部,這樣旁白與視覺效果就永遠不會不同步。 - 可讀性/品牌檢查,然後渲染為 MP4。
輸出檢查清單
- 每張投影片的
durationInFrames皆由其旁白音訊衍生而來,而非猜測。 - 每張投影片的音訊都已掛載在其自身的
Sequence內(視覺效果與旁白鎖定在一起)。 - 要點透過
useCurrentFrame()依序揭示;標題/標誌保持靜止。 - 揭示效果為淡入+上升,0.25–0.5 秒,無裝飾性效果。
- 投影片間轉場低調;僅在章節分隔頁使用較大的轉場。
- 主體文字於 1080p 下 ≥ 28px,對比度 ≥ 4.5:1,內容位於中心 90% 區域內。
- 每張投影片一個想法;旁白過長時應拆分投影片,而非縮小字型。
交付與驗證(渲染靜止幀 → 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 是逐格確定的 — 每個要點建構、轉場和投影片位置都是 useCurrentFrame() 的純函數,因此你可以在無需搜尋機制的頭部模式(headless)下渲染任何精確影格。最終產出物是附旁白的 MP4,因此檢查靜止幀可以在你浪費一次完整編碼之前,就發現被裁切的標題、不符合品牌的顏色,或溢出邊界的要點。
輸出合約:
- 一個 Remotion 專案,包含註冊的簡報(
<Composition>+ zodschema+defaultProps),所有動畫皆由影格驅動(無計時器 /Date.now()/Math.random());每張投影片的音訊掛載在其自身的Sequence內。 - 最終產出物 = 渲染後的
out/*.mp4(加上專案,以便使用者可以使用新的投影片/旁話重新渲染)。 - 投影片持續時間由旁白衍生 — 在
calculateMetadata中計算總計和每張投影片的durationInFrames(它會測量每個音訊片段),絕不手動設定。
驗證循環 — 渲染靜止幀 → 檢查 → 編碼。 先渲染單一影格(成本低,無需影片編碼),然後只在每張投影片的建構和閱讀都正確無誤時,才進行一次編碼。
# 1. 影格精確的靜止幀 — 使用 SHIPPED 屬性。爲每張投影片的穩定狀態渲染一張:
npx remotion still Deck out/f-title.png --frame=20 --props='{"slides":[...]}' # 標題卡穩定
npx remotion still Deck out/f-mid.png --frame=240 --props='{"slides":[...]}' # 內容投影片,要點已建構
npx remotion still Deck out/f-end.png --frame=899 --props='{"slides":[...]}' # 最後一幀 = durationInFrames - 1
# 2. 檢查每張 PNG — 正確性(投影片文字精確、數字/標籤正確、品牌顏色/字型已套用)
# 以及瑕疵(文字溢出、主體文字過小、內容超出中心 90% 安全裁切區域、缺少字型、
# 對比度不足、在投影片應已穩定的狀態下,要點卻處於建構中途)。
# 3. 只有在靜止幀檢查通過後,才進行編碼:
npx remotion render Deck out/deck.mp4 --props='{"slides":[...]}'
- 使用
npx remotion compositions讀取簡報的durationInFrames/fps並選取結束影格;在每張投影片的停留期間(而非轉場期間)抽樣一個靜止幀,以判斷其建構狀態。 - 資料驅動/批次:在渲染每個變體之前,先用一個代表性的簡報(真實投影片 + 旁白)透過靜止幀進行驗證 — 一次性找到字級或溢出的錯誤,而不是每個簡報都找一次。
- 獲得免費的 README 示範 GIF:
npx remotion render Deck out/demo.gif --codec=gif。
在你完成之前:
npx remotion still能在標題卡、一張內容投影片以及最後一幀處順利渲染 — 無錯誤,無缺少字型。- 投影片文字精確,主體文字在 1080p 下 ≥ 28px,對比度 ≥ 4.5:1,所有內容在每個影格都位於中心 90% 區域內。
- 僅由影格驅動 — 無
Date.now()/Math.random()/ 函式庫計時器(確定性在 CI 中保持成立)。 - 發佈的屬性(而非僅
defaultProps)能正確渲染 — 正確的投影片、已掛載的旁白、從音訊衍生的持續時間。 - 完整 MP4 已編碼且可播放(旁白 + 視覺效果鎖定);(可選)已為 README 渲染 GIF。
參考檔案
references/slide-components.md— 完整可執行的 RemotionSlide、交錯BulletList、動畫TitleCard和SectionDivider元件,包含共享主題以及透過<Audio>掛載的每張投影片旁白。references/sequencing.md— 完整的簡報序列器:測量每個旁白片段並設定總時長及每張投影片時長的calculateMetadata、<TransitionSeries>組合、轉場影格預算計算,以及 JSON 簡報 schema 到影片的資料流程。