React

Remotion × Claude Code でアプリのプロモ動画を作った話

個人開発アプリのプロモ動画を Remotion(React で動画を作るライブラリ)で作りました。

After Effects も Premiere も使わずに SNS 用のプロモ動画が作れます。そして Remotion が React で書けるということは、Claude Code に任せられるということでもあります。シーン構成を日本語で伝えるだけで、アニメーションのコードが生成されます。

作ったもの

単価いくら

tankaikura-promo

単価計算アプリのプロモ。オープニング → 課題提示 → デモ → CTA という構成。

色揃える

soroeru-promo

写真のトーンを揃えるアプリ。ビフォーアフターの 3×3 グリッドで機能を視覚的に伝えています。アプリのブランドカラー(ダーク系 + ゴールド)をそのまま動画に持ち込みました。


セットアップ

pnpm create video@latest

テンプレートを選んでプロジェクトを作成します。Remotion Studio(ブラウザで再生しながら開発できる環境)が立ち上がります。

pnpm dev  # http://localhost:3000 で Studio が開く

Studio 上でフレームをスクラブしながら確認できるので、After Effects のタイムライン操作に近い感覚で開発できます。


基本構造

Remotion の動画は React コンポーネントです。

import { AbsoluteFill, useCurrentFrame, useVideoConfig } from 'remotion';

export const MyComposition: React.FC = () => {
  const frame = useCurrentFrame();       // 現在のフレーム番号
  const { fps, durationInFrames } = useVideoConfig(); // 動画設定

  return (
    <AbsoluteFill style={{ backgroundColor: '#1a1a2e' }}>
      <h1 style={{ opacity: frame / 30 }}>アプリ名</h1>
    </AbsoluteFill>
  );
};

useCurrentFrame() で現在のフレーム番号が取れるので、それを使って opacity・transform などを計算します。

コンポジション(動画の設定)は Root.tsx に登録します。

export const RemotionRoot: React.FC = () => {
  return (
    <Composition
      id="MyComposition"
      component={MyComposition}
      durationInFrames={450}  // 15秒 × 30fps
      fps={30}
      width={1080}
      height={1080}
    />
  );
};

アプリのスクリーンショットを動画に入れる

既存のスクショを動画に使うには public/ フォルダに置いて staticFile() で参照します。

import { Img, staticFile } from 'remotion';

// public/screenshots/home.png を参照
<Img src={staticFile('screenshots/home.png')} />

<img> ではなく <Img> を使うのが重要です。 Remotion の <Img> は画像の読み込みを待ってからフレームを進める仕組みになっています。<img> を使うと読み込み前にレンダリングが走り、真っ白なフレームが出力されてしまいます。


アニメーションのコツ

spring() で物理ベースのアニメーション

Remotion 組み込みの spring() を使うと、バウンスや弾性のある動きが簡単に作れます。

import { spring, useCurrentFrame, useVideoConfig } from 'remotion';

const frame = useCurrentFrame();
const { fps } = useVideoConfig();

const scale = spring({
  frame,
  fps,
  config: {
    damping: 8,    // 小さいほど弾む
    stiffness: 80, // 大きいほど素早い
    mass: 1,
  },
});

return <Img src={staticFile('icon.png')} style={{ transform: `scale(${scale})` }} />;

アイコンの入場演出は damping: 8 ぐらいが自然に見えました。

interpolate() でフレームを値に変換する

interpolate() はフレーム範囲を任意の値範囲に変換するユーティリティです。

import { interpolate } from 'remotion';

// フレーム 0〜30 の間で opacity が 0 → 1 になる
const opacity = interpolate(frame, [0, 30], [0, 1], {
  extrapolateLeft: 'clamp',
  extrapolateRight: 'clamp',
});

extrapolateLeft/Right: 'clamp' を指定しないと、範囲外のフレームで値が外挿されてマイナスになったりします。ほぼ必須のオプションです。

<Sequence> でシーンを分割する

ひとつのコンポーネントに全部書くと管理が大変になります。<Sequence> でシーンを分割するのがおすすめです。

import { Sequence } from 'remotion';

export const MyComposition = () => (
  <AbsoluteFill>
    <Sequence from={0} durationInFrames={90}>
      <OpeningScene />   {/* 0〜90フレーム */}
    </Sequence>
    <Sequence from={90} durationInFrames={120}>
      <DemoScene />      {/* 90〜210フレーム */}
    </Sequence>
    <Sequence from={210}>
      <CtaScene />       {/* 210フレーム〜終わりまで */}
    </Sequence>
  </AbsoluteFill>
);

各シーンコンポーネント内では useCurrentFrame() が Sequence のローカルフレーム(0 始まり)を返すので、シーンごとに独立してアニメーションを設計できます。


レンダリング

pnpm exec remotion render MyComposition out/my-video.mp4

ファイルサイズが大きい場合は --crf で圧縮率を調整します。

pnpm exec remotion render MyComposition out/my-video.mp4 --crf 28

CRF はデフォルト 18(高品質)で、数値が大きいほど圧縮が強くなります。SNS 投稿用なら 28〜32 でも十分な画質です。今回は 10MB 超だったものを --crf 28 で 7MB 台まで下げました。


Claude Code との組み合わせが強い

Remotion の最大のメリットは「React = コード = AI が生成できる」という点です。

今回の動画はほぼ Claude Code に書かせました。プロンプトの例:

アプリのプロモ動画を作りたい。構成は以下の通り:

1. オープニング(3秒): アイコンがバウンスで登場、アプリ名がフェードイン
2. 課題提示(4秒): 「毎回計算が面倒」というテキストが中央に表示
3. デモ(5秒): スクリーンショット screenshots/home.png がスライドイン
4. CTA(3秒): 「App Store で入手」ボタン

カラーパレット: 背景 #1a1a2e, テキスト #ffffff, アクセント #e94560
サイズ: 1080×1080, 30fps

この指示で <Sequence> で分割された各シーンのコンポーネントが生成されます。

Remotion Studio でフレームをスクラブしながら「このアニメーションもう少し遅く」「テキストの位置を下に」といった修正を Claude Code に伝えると、数値が調整されたコードが返ってきます。After Effects の GUI でパラメータを触る代わりに、コードで会話しながら仕上げていく感覚です。


Claude Code スキルで精度を上げる

Claude Code にはスキルという仕組みがあり、ドメイン固有の知識を事前に読み込ませることができます。Remotion との組み合わせでは 2 種類のスキルを使いました。

1. 公式スキル(remotion-best-practices)

Remotion 公式が提供するスキルで、API の使い方・よくあるパターン・注意点が詰まっています。プロジェクトに追加するには .agents/ フォルダに配置します。

your-remotion-project/
└── .agents/
    └── skills/
        └── remotion-best-practices/
            └── SKILL.md   ← エントリーポイント

これを置いておくと、Claude Code が Remotion のコードを書く際に自動で参照します。spring()interpolate() の使い方、<Img> vs <img> の違いなど、Remotion 固有の知識をプロンプトに書かなくても正しく扱ってくれるようになります。

2. プロジェクト固有のスキル(自作)

公式スキルではカバーされない「自分のプロジェクトでハマったこと」を .claude/skills/ に追加できます。

your-remotion-project/
└── .claude/
    └── skills/
        └── my-remotion-tips/
            ├── SKILL.md
            └── rules/
                ├── gotchas.md     ← 過去に踏んだバグ
                ├── fonts.md       ← 使うフォントの決まり
                └── format-presets.md  ← SNS別サイズ設定

SKILL.md のフォーマット:

---
name: my-remotion-tips
description: このプロジェクト固有のRemotion Tips
---

## When to use
新しい動画を作るとき、このスキルを読み込むこと。

## ルール
- [rules/gotchas.md](rules/gotchas.md) — 過去にハマったポイント一覧
- [rules/fonts.md](rules/fonts.md) — 日本語フォントの選び方
- [rules/format-presets.md](rules/format-presets.md) — SNS別フォーマット設定

実際に入れておくと便利な内容:

  • 過去にハマったポイントと解決策(同じところで詰まらなくなる)
  • 使うフォントの一覧(毎回フォント名を調べなくていい)
  • SNS 別の推奨サイズ(1080×1080, 9:16 など)
  • アプリのカラーパレット(毎回カラーコードを渡さなくていい)
  • アセットの命名規則(public/ に置くファイル名のルール)

スキルに書いておくことで、プロンプトが短くなります。「単価いくらのプロモ動画を作って」という一言だけで、アプリのブランドカラーやアセットのパスを Claude Code が自分で参照して作ってくれます。


まとめ

ポイント内容
画像は <Img> を使う<img> だと白フレームが出る
interpolate() は clamp 必須範囲外で値が暴れる
シーンは <Sequence> で分割各シーンが 0 フレーム始まりになる
ファイルサイズ調整--crf 28〜32 でSNS用に最適化

React が書ければ After Effects なしでプロモ動画が作れます。個人開発でデザインにリソースをかけられない場合の選択肢として十分実用的でした。