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

08134-ik4zw85f4h.png

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

https://www.remotion.dev/

10540-hb3bn97lpcd.png

安裝好之後如下

02171-m0tc28m4ucj.png

初始化

npm i

初始化

npx remotion init

71779-y224omf6oga.png

npm run dev
94177-egvma2xvmg.png

將 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}
      />
    </>
  );
};

切換到頁面如下

35183-mx0y7fb9ma8.png

執行渲染成 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(遊戲過場)

89894-847svyx4rv.png

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經驗難以繼承的問題,確實是個好項目。

無標籤

關注作者:

新增評論