🔄

Remotionコード分析 — renderMedia()とフレームレンダリングループ

Puppeteerで各フレームをスクリーンショットしFFmpegで結合するレンダリングコアループをソースコードで分析

GitHub: remotion-dev/remotion/packages/renderer

バンドリング完了後、実際のレンダリングが開始されます。renderMedia()がすべてを調整するオーケストレーターです。

フロー: renderMedia()がselectComposition()でメタデータ取得、renderFrames()でPNGシーケンス生成、stitchFramesToVideo()でFFmpegエンコーディング。

renderFrames()では複数のChromeページが並列実行。各フレームで: window.remotion_setFrame(n)を注入、Reactが再レンダリング、waitForDelayRender()で非同期処理完了を確認、page.screenshot()でフレームキャプチャ。

delayRender/continueRenderはシンプルなカウンターパターン — window.__REMOTION_DELAY_RENDER配列が空になってからスクリーンショットが進行します。

動作フロー

1

renderMedia()がバンドルサーバーを開きselectComposition()でCompositionメタデータを照会

2

renderFrames()がconcurrency数だけChromeページを開きフレームを分配

3

各ページでwindow.remotion_setFrame(n) → React再レンダー → waitForDelayRender() → screenshot()

4

delayRender配列が空になるまで(= すべての非同期完了)スクリーンショットを待機

5

stitchFramesToVideo()がFFmpegでPNGシーケンス → MP4/WebMエンコード + オーディオmux

メリット

  • remotion_setFrame → React再レンダーパターン: 既存のReactエコシステムをそのまま活用する優雅な設計
  • delayRenderがシンプルなカウンター → 複雑な非同期シナリオも安全に処理

デメリット

  • Chromeプロセス管理の複雑さ: ページクラッシュ、メモリリークなどブラウザ特有の問題

ユースケース

レンダリングボトルネックのデバッグ: どの段階(バンドル/フレーム/エンコード)で時間がかかるか把握 delayRenderタイムアウトのデバッグ: continueRenderが呼ばれない原因の追跡