使用 remotion 生成影片
今天在 X 上面看到的 Remotion 使用 React 生成影片,最後效果畫面如下

下面我們就來具體姐說下安裝、使用、跟生成影片,再説明下 React 生成的好處

安裝好之後如下

初始化
npm i
初始化
npx remotion init

npm run dev

將 src\Composition.tsx 修改如下
import { useCurrentFrame } from "remotion";
export const MyComp = () => {
const frame = useCurrentFrame();
return (
<div
style={{
background: "black",
width: "100%",
height: "100%",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<h1 style={{ color: "white", fontSize: 80 }}>
第 {frame} 幀
</h1>
</div>
);
};
Root.tsx 修改如下
import "./index.css";
import { Composition } from "remotion";
import { MyComp } from "./Composition";
export const RemotionRoot: React.FC = () => {
return (
<>
<Composition
id="MyComp"
component={MyComp}
durationInFrames={60}
fps={30}
width={1280}
height={720}
/>
</>
);
};
切換到頁面如下

執行渲染成 MP4(簡報影片)
npx remotion render src/index.ts PresentationVideo out/presentation.mp4
Downloading from: https://storage.googleapis.com/chrome-for-testing-public/149.0.7790.0/win64/chrome-headless-shell-win64.zip
Got Headless Shell ━━━━━━━━━━━━━━━━━━ 5553ms
Bundled code ━━━━━━━━━━━━━━━━━━ 5507ms
⚡️ Cached bundle. Subsequent renders will be faster.
Composition PresentationVideo
Codec h264
Output out/presentation.mp4
Concurrency 6x
Rendered frames ━━━━━━━━━━━━━━━━━━ 4385ms
Encoded video ━━━━━━━━━━━━━━━━━━ 251ms
+ out/presentation.mp4 750.6 kB
影片: https://youtu.be/Z3P4DQbgsV4
執行渲染成 MP4(遊戲過場)

npx remotion render src/index.ts GameCutscene out/game.mp4
Bundled code ━━━━━━━━━━━━━━━━━━ 1360ms
Composition GameCutscene
Codec h264
Output out/game.mp4
Concurrency 6x
Rendered frames ━━━━━━━━━━━━━━━━━━ 8417ms
Encoded video ━━━━━━━━━━━━━━━━━━ 718ms
+ out/game.mp4 1.5 MB
影片: https://youtu.be/u_ZFEPvKQVo
我們來解析下 PPT present 的内容是怎麽寫的,從 src\PresentationVideo.tsx 可以看到
// ── 主組件 ────────────────────────────────────────────────
export const PresentationVideo: React.FC = () => {
return (
<AbsoluteFill>
<Sequence from={0} durationInFrames={90}>
<Slide1 />
</Sequence>
<Sequence from={90} durationInFrames={100}>
<Slide2 />
</Sequence>
<Sequence from={190} durationInFrames={80}>
<Slide3 />
</Sequence>
</AbsoluteFill>
);
};
生成的三段内容如下:
Slide1 — 封面
- 兩個 radial-gradient 圓做背景暈染、四角金線裝飾
- 副標「2025 年度報告」用
interpolate淡入 - 主標「品牌成長 / 策略報告」用
spring從 Y=80 彈到 0,同時透明度淡入 - 中間金色漸層分隔線寬度從 0 → 340px 拉開
Slide2 — 數據統計
- 抽出
StatBar子組件:每個指標的進度條寬度從 0 動畫到目標 % (45 frames),數字同步跟著Math.round(w)跳動 - 四條 bar 用遞增的
delay(20/35/50/65)做依序出現的瀑布效果 - 指標:市佔 78%、滿意度 92%、營收成長 65%、品牌知名度 84%
Slide3 — 結尾 CTA
- 整塊內容用
spring從 scale 0.7 彈到 1 並淡入 - ✦ 符號的
drop-shadow模糊半徑用glowOpacity * 30漸亮,做出延遲的金色光暈 - 顯示「謝謝聆聽 / LET'S BUILD THE FUTURE TOGETHER」
額外的細節或是動畫手法重點
interpolate處理線性的淡入/寬度延展spring處理有彈性的位移/縮放(封面標題彈入、結尾整體放大)delay參數透過調整 interpolate 的輸入區間來錯開元素出場時間
看起來能夠調整的細節多了,至於掌控程度還必須仔細測試才知道,不過思考下爲什麽用 React 寫影片呢,大概也清楚了,相對於 Prompt 生成有幾個好處,如下:
- 版本控制
- 可重複利用
- 程式化編排設計
Remotion 的本質公式
React (描述 UI 的能力)
+ Headless Chromium (把 DOM 變成像素)
+ FFmpeg (把像素序列變成 mp4)
+ 「frame 是純函數參數」這個 idea
─────────────────────────────────
= 用程式碼寫影片
能力邊界:能做什麼
凡是 Chromium 能畫的,都能進影片:
| 類別 | 範例 |
|---|---|
| HTML/CSS | flexbox、漸層、shadow、filter、transform、SVG、Canvas |
| React 生態 | 任何 npm 套件(D3、Three.js via react-three-fiber、Lottie、Framer Motion 的 motion values) |
| 媒體素材 | <Video>、<Audio>、<Img>、<OffthreadVideo> 嵌入既有影片 |
| 資料驅動 | 從 API/JSON/CSV 讀資料動態生成圖表影片 |
| WebGL/Shader | three.js、pixi.js、自寫 shader 都行 |
| 字幕/語音 | Whisper 轉寫 + TTS 自動字幕影片 |
能力邊界:做不到 / 很痛
1. 真正的物理模擬 / 互動
- 粒子系統若要「碰撞、流體、剛體」,得自己每 frame 算座標(或塞 matter.js 之類,但要確保是 deterministic 的,因為渲染時每 frame 都會「重置」狀態)
useState在渲染時不可靠——Chromium 每幀可能是新 page context,狀態不會跨 frame 累積- 規則:所有狀態必須能從
frame純函數推導出來
2. 即時性的東西
- 使用者輸入、滑鼠互動、即時串流——不存在,因為輸出是 mp4
- WebSocket 拉資料這類在渲染期可以,但要等資料到齊
3. 計算量大的逐幀運算
- 每幀都重新 render 整棵 React 樹,複雜場景渲染 1 分鐘影片可能要好幾分鐘
- 大量 DOM 元素(>1000 顆 particle)會卡,這時應該改用
<Canvas>或 WebGL
4. 隨機性需要 seed
Math.random()在每 frame 結果不同 → 同一顆粒子下一幀就跳到別的位置- 要用
random(seed)(Remotion 自帶 deterministic random)或基於frame算
5. CSS animation / transition / keyframes
- 寫了也沒效果!因為 Chromium 是被「凍結在某個 frame」截圖的,CSS 動畫的「時間」對它不存在
- 必須改寫成
interpolate(frame, ...)或spring({frame, fps, ...})
6. 字型/圖片載入時序
- 必須用 Remotion 的
delayRender()/continueRender()等資源就緒,否則會截到「字型還沒載好的醜畫面」
7. 影片內嵌的限制
<Video>對 codec 挑剔,長影片用<OffthreadVideo>才不會卡- 倒帶/倍速播放 source video 要小心 seeking 成本
Three.js / D3 / Lottie / Framer Motion / Pixi / 任何能跑在瀏覽器的東西,都可以套用上,那麽 對於前面提到的版本控制、可重複利用、程式化設計大概懂了,確實避開了 LLM 生成素材穩定性跟Prompt經驗難以繼承的問題,確實是個好項目。