Remotion モーショングラフィックス
Remotion は React コンポーネントを1フレームずつ動画にレンダリングします。コードの品質はボトルネックではありません — モーションデザインの職人技が鍵です。未調整の生成では、線形イージング、不透明度のみのフェード、同時出現、フラットな色、テクスチャの欠如が生じます。それが「AI生成動画っぽい」見た目です。このスキルはそれを防ぐために存在します。
非交渉ルール(すべてのコンポジションに適用)
- 線形補間は絶対に使わない。 すべての
interpolate()にはイージングカーブを設定し、すべてのエントランスはspring()を優先します。常にextrapolateLeft/Right: "clamp"を指定すること。 - エントランスは2~3のプロパティを同時にアニメーションさせる(不透明度 + translateY + スケール)。単独のフェードは禁止です。
- すべてをスタガリングする。 リスト、単語、光線、カード:3~6フレームのオフセットを設定し、同時に出現させないこと。
- 終了アニメーションは存在し、エントランスより速くする(約10フレーム vs 約20フレーム)。
- すべてのシーンに5層のレイヤー(下から上へ:背景メッシュ → アセット → グラフィック/タイポグラフィ → カラーグレード → グレイン + ビネット)。フラットな単色背景は禁止。
- すべての静止画像にケンバーンズ効果を適用(スローなスケール 1→1.08 + パン)。すべての動画アセットには
<OffthreadVideo>を使用し、<Video>は使わないこと。 - アイドル状態の要素は動き続ける: 画面に2秒以上表示される要素にはサイン波のマイクロモーションを加えること。
- すべてのタイミングは
fpsからuseVideoConfig()を使って派生させる。 マジックナンバーのフレーム指定は禁止。 - プロジェクトの先頭に1つのテーマオブジェクト(カラー、イージング、スプリングプリセット、フォント)を定義する。コンポーネント内に16進数カラーやイージングをインラインで書かないこと。
- レンダリングし、フレームを抽出し、 目で確認し、修正し、再レンダリングする。未確認のレンダリングを納品してはならない。 このループは必須です — 下記の「検証」を参照。
ワークフロー
ステップ 1 — スコープ決定
以下の項目を決める:長さ、fps(デフォルト30;激しい高速モーションの場合のみ60)、寸法(リール/ショートは1080×1920、ランドスケープは1920×1080)、どのアセットが存在するか(画像、映像、音声、ロゴ)、そしてこれが新しいコンポジションか既存プロジェクトの編集か。
既存プロジェクトの編集の場合:まず src/ を完全に読み、テーマを見つける(なければ作成する)、上記ルールの違反をリファクタリングしてから機能を追加すること。
ステップ 2 — セットアップ
新しいプロジェクト:
npm install remotion @remotion/cli react react-dom
# オプション: @remotion/transitions @remotion/motion-blur @remotion/google-fonts
このスキルから assets/theme.ts を src/theme.ts にコピーし、パレットをユーザーのブランドに合わせて調整する。構造:src/index.ts(registerRoot)→ src/Root.tsx(Composition、duration/fps/size)→ src/scenes/*.tsx → src/components/*.tsx。ユーザーアセットは public/ に配置し、staticFile() で読み込む。
ステップ 3 — 構築
references/motion-patterns.md を読んで、再利用可能なコンポーネント実装(BgMesh、Grade、Grain、Vignette、KenBurns、WordReveal、Stagger、Counter、Spark、トランジション、パララックス)を把握する。それらのパターンからシーンを構成する。テンポ、リズム、タイポグラフィ、カラーパレット、サウンドデザインのルールについては references/design-rules.md を読むこと。
シーンのリズム:HIT → ホールド(15~20フレーム静止) → ビルド → HIT。最初の15フレーム以内に何かが動いていなければならない。新しい視覚要素なしに90フレームを超えてはならない。
ステップ 4 — レンダリング
npx remotion render src/index.ts <CompId> out/video.mp4 --codec h264 --crf 17
Remotion には Chromium バイナリが必要です。自動ダウンロードが失敗する場合(サンドボックス、オフラインCI)、バイナリを見つけて明示的に指定します:
which chromium chromium-browser google-chrome 2>/dev/null
ls /opt/pw-browsers 2>/dev/null # Playwright のインストール先
npx remotion render ... --browser-executable=<パス>
フル Chrome で「Old Headless mode has been removed」エラーが出る場合は、代わりに headless_shell バイナリを使用します(Playwright が chromium_headless_shell-*/chrome-linux/headless_shell として同梱しています)。
ステップ 5 — 検証(必須、絶対にスキップしない)
キーフレームでフレームを抽出し、それぞれを目視で検査する。ポータブルな方法 — システムに ffmpeg がなくても動作し、正確なフレームをレンダリングします:
for f in 15 45 90 150; do
npx remotion still src/index.ts <CompId> out/check_$f.png --frame $f --overwrite
done
システム ffmpeg が利用可能な場合、完成した mp4 から抽出することでエンコード自体も検証できます(-ss シークは select= フィルターよりも移植性が高く、select= はシェルや Remotion バンドル版 ffmpeg で引用符の問題が発生することがあります):
ffmpeg -v error -ss 1.5 -i out/video.mp4 -frames:v 1 check_1.png
頻度順に、以下の問題を探して修正する:
- スペーシングのバグ:
gap/marginをemで指定すると、親のフォントサイズ(多くの場合16px)に対して解決され、テキストサイズに対してではありません — 大きなタイポグラフィの周りのフレックスコンテナでは px 値を使用すること。 - テキストのオーバーフローやフレーム端への接触(9:16では重要なコンテンツを垂直方向の中央75%に収めること — プラットフォームUIが上部/下部を覆います)。
- エントランス前や終了後に要素が表示されている(
clampの欠如)。 - 色/コントラストの問題:1フレーム内でヒーローカラーが複数の要素に使われている、薄暗いテキストがグレードの上で読めない。
- レイヤー順の間違い(グレイン/ビネットは最前面、グレードはコンテンツの上)。
修正 → 再レンダリング → 再抽出 → 再検査。クリーンなパスが確認できた場合のみ納品する。その後、references/design-rules.md の末尾にある最終チェックリストを実行する。
ユーザーの既存映像を編集する
既存の mp4 をゼロから構築するのではなく強化する場合(キャプション、グレード、イントロ/アウトロ):ファイルを public/ に配置し、アセットレイヤーとして <OffthreadVideo src={staticFile("clip.mp4")} /> でレンダリングし、コンポジションの長さをクリップの長さに設定し、その上にグラフィック/グレード/グレインをスタックします。コンポジションを設定する前に、ffprobe でクリップの長さとfpsを取得すること。音声に同期したワードキャプションについては、references/motion-patterns.md のキャプションセクションを参照。
リファレンスファイル
references/motion-patterns.md— コピペ可能なコンポーネントライブラリ:背景、グレード/グレイン/ビネット、ケンバーンズ、テキストリビール、カウンター、トランジション、パララックス、オーディオ同期、キャプション。コンポーネントを書く前に読むこと。references/design-rules.md— パレット、タイポグラフィルール、シーン構成、サウンドデザイン、納品前チェックリスト。シーンをデザインする前と最終納品前に読むこと。assets/theme.ts— すべてのプロジェクトにコピーするテーマテンプレート。
積極的に避けるべきよくある失敗
- 絵文字をアイコンとして使う。 絵文字はフルカラーのプラットフォームグリフ(緑の ✳️、青の 🌐)としてレンダリングされ、パレットを無視して1ヒーローカラールールを静かに破り、さらに任意の背景の上に配置される(オレンジのマスコットがオレンジのタイルの上で見えなくなる)。CSS/SVGでテーマカラーのグリフを描画するか、抽出したフレームですべての絵文字を確認すること。
- SFXアセットがないからといって無音で納品しない。 Nodeスクリプトで最小限のキットを16ビットWAVとして合成し(ノイズバーストのシューッという音、ピッチドロップのポップ、サイン波の太鼓/バス、デチューンサインのパッド)、
public/sfx/に配置する — リポジトリのexamples/scripts/を参照。ダウンロード不要、完全に決定論的。 - テーマ化された再利用可能な部品ではなく、1つの巨大なコンポーネントを生成すること。
durationInFramesが Composition とシーンコンテンツで一致しない(無音の間ができる)。- 再レンダリング時に
--overwriteを忘れ、古いファイルを検査してしまう。 - フォント:ヒーローテキストにシステムデフォルトを頼らない。
@remotion/google-fontsまたは@font-face+staticFileでディスプレイフォントを読み込むこと。 - レンダリングして確認する代わりに、結果をユーザーに「説明」しようとすること。