mcpField
R
remotion-video

remotion-video

github.com/tushaarmehtaaクリエイティブ・メディア1242 回インストール2 週間前に更新
リポジトリ

remotion-video について

remotion-videoは、映像のブリーフからRemotionプロジェクトを構築するスキルです。複数の画角、アニメーション、音声のタイミング、再利用可能なビジュアル部品を組み込み、Remotion Studioで開ける形にします。

主な機能

  1. 013種類の画角のコンポジション
  2. 02springベースのシーンアニメーション
  3. 03シーンの時間設定とクロスフェード
  4. 04シーンに連動する音量制御
  5. 05再利用可能なシーンとビジュアル部品
  6. 06モバイル向けのサイズ調整

活用シーン

  1. 01製品デモ動画のプロジェクト構築
  2. 02デスクトップとモバイル向け動画の作成
  3. 03時間に沿ったシーン構成の作成
  4. 04動くテキストやターミナル演出の追加

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/tushaarmehtaa/tushar-skills --skill remotion-video

インストール後、Claude Code で/remotion-videoを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
audio.md
cheatsheet.md
primitives.md

詳細

Remotion の動画プロジェクトを、複数フォーマットのコンポジション、スプリングアニメーション、ビートに同期した音声、再利用可能なシーンプリミティブとともにスキャフォールドします。すぐに npx remotion studio を実行できるプロジェクトを出力します。

フェーズ 1:概要を確認する

コードを書く前に、不足している情報を質問します。

I'll scaffold a Remotion video project. Quick decisions:

1. Product name? (used for composition IDs and file names)
2. One-line pitch? (the core message of the video)
3. Scene ideas? (3-8 scenes — what story does each beat tell?)
4. Color vibe?
   a) Dark + amber accent (#d97706) — warm, editorial
   b) Dark + monochrome — clean, minimal
   c) Custom — give me bg, text, and accent hex values
5. BPM of your music track? (default: 115)
6. Font? (default: system stack — or provide .woff2 files for Geist/custom)

ユーザーが会話の中ですでに動画について説明している場合は、質問する前に回答を読み取ります。すでにわかっていることは質問しません。

ユーザーが回答を省略した場合のデフォルト: 25 秒、30fps、6 シーン、ダーク+アンバー、115 BPM、システムフォントスタック。

フェーズ 2:プロジェクトをスキャフォールドする

次のファイルツリーを正確に作成します。

[name]-video/
├── package.json
├── tsconfig.json
├── src/
│   ├── index.ts
│   ├── Root.tsx
│   ├── [Name]Demo.tsx        # orchestrator
│   └── [Name]Scenes.tsx      # scenes + tokens + primitives
├── public/
│   ├── audio/                # user drops .mp3 here
│   └── fonts/                # .woff2 files if custom font
└── out/
package.json
{
  "name": "[name]-video",
  "type": "commonjs",
  "dependencies": {
    "@remotion/cli": "^4.0.421",
    "@types/react": "^19.2.13",
    "react": "^19.2.4",
    "react-dom": "^19.2.4",
    "remotion": "^4.0.421",
    "typescript": "^5.9.3"
  }
}

ローカルのフォントファイルを読み込む場合に限り、@remotion/fonts: "^4.0.434" を追加します。 それ以外の場合は含めません。

"type": "commonjs" が必要です。 ESM は Remotion のバンドラーで問題を引き起こします。

tsconfig.json
{
  "compilerOptions": {
    "target": "ES2018",
    "module": "commonjs",
    "jsx": "react-jsx",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "outDir": "./dist",
    "rootDir": "./src"
  },
  "include": ["src/**/*"]
}
src/index.ts

常に同じ内容にします。

import { registerRoot } from "remotion";
import { RemotionRoot } from "./Root";
registerRoot(RemotionRoot);

フェーズ 3:コンポジション(Root.tsx)

3 つのコンポジションを登録します。同じコンポーネントですべてをレンダリングし、アスペクト比の検出はコンポーネント内で行います。

import { Composition } from "remotion";
import { Demo } from "./[Name]Demo";

export const RemotionRoot = () => (
  <>
    <Composition id="[Name]Demo" component={Demo} durationInFrames={750} fps={30} width={1920} height={1080} />
    <Composition id="[Name]DemoMobile" component={Demo} durationInFrames={750} fps={30} width={1080} height={1920} />
    <Composition id="[Name]DemoMobileLandscape" component={Demo} durationInFrames={750} fps={30} width={1334} height={750} />
  </>
);

30fps で 750 フレーム = 25 秒です。 ユーザーが異なる長さを指定した場合は調整します。

モバイル用のコンポーネントを個別に作成してはいけません。 コンポーネント内でフォーマットを検出します。

const { width, height, fps } = useVideoConfig();
const isPhone = height > width;
const isMobileLandscape = width > height && width <= 1400;
const globalScale = isPhone ? 1.14 : isMobileLandscape ? 1.08 : 1;

シーン領域全体を、globalScale を使ってスケーリングした <AbsoluteFill> で囲みます。

カスタムフォントを読み込む場合は、コンポジションより前の Root.tsx のモジュールレベルでフォントローダーを呼び出します。

フェーズ 4:シーンアーキテクチャ(オーケストレーター)

オーケストレーターファイル([Name]Demo.tsx)では、タイミングの定義、音声の接続、シーケンスの配置の 3 つを行います。

シーンのタイミングオブジェクト
const scenes = {
  hook:   { from: 0,   dur: 90 },
  xfade1: { from: 86,  dur: 10 },
  pain:   { from: 90,  dur: 120 },
  xfade2: { from: 206, dur: 10 },
  // ... continue for each scene
} as const;

ルール:

  • クロスフェードは直前のシーンと 4 フレーム重ねます(from = prev scene end - 4)
  • クロスフェードの長さ:10~16 フレーム
  • シーンの長さ:60~195 フレーム(2~6.5 秒)。短めにします。どのシーンも長すぎてはいけません。
  • TypeScript が値をリテラルとして扱うには as const が必要です
シーケンスの配置

すべてのシーン+クロスフェードのペアで繰り返すパターン:

const frame = useCurrentFrame();

<Sequence from={scenes.hook.from} durationInFrames={scenes.hook.dur}>
  <SceneHook frame={frame - scenes.hook.from} duration={scenes.hook.dur} />
</Sequence>
<Sequence from={scenes.xfade1.from} durationInFrames={scenes.xfade1.dur}>
  <CrossfadeTransition frame={frame - scenes.xfade1.from} dur={scenes.xfade1.dur} />
</Sequence>

各シーンにローカルフレーム 0 から始まるフレームを渡すため、必ず frame - scenes.X.from を渡します。 シーンでグローバルフレームを参照してはいけません。

音声
<Audio src={staticFile("audio/music.mp3")} volume={(f) => getMusicVolume(f)} />

references/audio.md にある 5 層システムを使って getMusicVolume を構築します。scenes オブジェクトとトランジションのフレーム番号を渡します。

フェーズ 5:シーンを作成する

すべてのシーンコンポーネント、デザイントークン、プリミティブを [Name]Scenes.tsx に配置します。

デザイントークン

ユーザーが選んだ色に基づいて設定します。

ダーク+アンバーアクセント:

export const colors = {
  bg: "#000000", surface: "#080808", surfaceRaised: "#111111",
  border: "#191919", borderHover: "#333333", muted: "#555555",
  text: "#999999", heading: "#ffffff",
  accent: "#d97706", accentDim: "rgba(217,119,6,0.19)",
  accentGlow: "rgba(217,119,6,0.07)", accentBright: "rgba(217,119,6,0.35)",
};

ダーク+モノクロ:

export const colors = {
  bg: "#09090b", surface: "#18181b", border: "#27272a",
  textPrimary: "#e4e4e7", textSecondary: "#c2c2cb",
  textMuted: "#ababb5", textDim: "#9595a0", accent: "#e4e4e7",
};
次のプリミティブを含める

references/primitives.md からコピーします。

  1. SceneWrap — すべてのシーンで使用します。非単調な inputRange ガードを備えたフェードイン/フェードアウトを処理します。
  2. SlamText — 単語ごとのスプリング表示。見出しに使用します。
  3. CrossfadeTransition — シーン間で不透明度を高めます。zIndex: 100 が必須です。
  4. TypingEffect — 点滅するカーソルを備えたターミナル/入力シミュレーションです。
  5. GrainOverlay — SVG ノイズテクスチャ(アンバーの雰囲気の場合のみ)。opacity: 0.035、zIndex: 50。
  6. StageLight + AmbientGlow — ゆっくり動く放射状グラデーション(アンバーの雰囲気の場合のみ)。
シーンのプレイブック

ユーザーの要望に応じて、このメニューからシーンを選びます。

シーンの種類長さ目的
フック2-4.5sSlamText の見出し+スプリングアニメーションのサブテキスト。注目を集めます。
ペイン/問題4-5s古いやり方をターミナルのタイピングで表示します。「新しいセッション」のフラッシュでリセットします。
スナップ/解決策2-3s1 つのコマンドを入力し、結果を表示して、光のパルスとともに「完了。」と表示します。
読み込み中1.5-2s絵文字+揺れ+プログレスバー。期待感を高めます。
結果/カード4-6.5sアイテムがさまざまな方向から飛び込んできます。出力の品質を示します。
機能グリッド2-3s2x3 または 3x2 のグリッドで、スプリングアニメーションを使って順番に登場します。
フィードバック/チャット3-4sチャットバブル:ユーザーの質問は右にスライドし、AI の応答は左にスライドします。
スクロール/カルーセル5-6.5sアイテムが入場・退出のトランジションとともに中央を順番に通過します。
インストール3s見出し+インストールコマンドのタイピングアニメーション+「完了。」
CTA3sSlamText +脈打つボタン+URL。fadeOut: 0(フェードなしで動画を終了)。

シーン内でよく使うパターン:

  • すべてのテキスト要素の登場には spring() を使い、動きに interpolate() を直接使わないでください。
  • 順番に登場させる場合:各アイテムに 3-6 フレームの遅延を設定します。
  • 完了時の光のパルス:interpolate(Math.sin(frame * 0.1), [-1, 1], [0.03, 0.12])
  • 控えめなズームドリフト:interpolate(frame, [0, duration], [1, 1.03])
レスポンシブなサイズ設定

すべてのサイズ定数で isPhone に応じた分岐を設定します。

const fontSize = isPhone ? 148 : 88;      // headlines
const subSize = isPhone ? 72 : 46;        // subtext
const cmdSize = isPhone ? 72 : 48;        // terminal commands
const panelW = isPhone ? 920 : 800;       // UI panels
const borderRadius = isPhone ? 20 : 14;   // card corners

スマートフォン向けのサイズは、デスクトップ向けの約 1.4-2 倍です。線形スケールではありません。

スプリング設定の一覧、レスポンシブ値、レンダーコマンドについては、references/cheatsheet.md を参照してください。

フェーズ 6:注意点

次の点を見落とすと、動画に気づきにくい不具合が発生します。

  1. 外挿は必ずクランプしてください。 すべての interpolate() 呼び出しに { extrapolateLeft: "clamp", extrapolateRight: "clamp" } が必要です。指定しないと、値が 0/1 を超えて大きくなります。
  2. 入力範囲が単調でない場合のクラッシュ。 SceneWrap で fadeOut=0 にすると、inputRange に重複した値が設定されます。プリミティブにある safeEnd = Math.max(duration - fadeOut, fadeIn + 1) のガードで修正されます。
  3. レンダリング時のフォントのタイムアウト。 フォントの読み込みに使う delayRender() は、700 を超えるフレームでタイムアウトする場合があります。--timeout=60000 を使用してください。
  4. クロスフェードでの zIndex。 クロスフェードのオーバーレイがシーンのコンテンツより上に表示されるよう、zIndex: 100 を設定する必要があります。
  5. ローカルフレームとグローバルフレーム。 シーンコンポーネントには、必ず frame - scenes.X.from を渡してください。
  6. シーンオブジェクトに as const を指定する。 TypeScript が値をリテラルとして扱うために必要です。
  7. remotion.config.ts は不要です。 CLI のデフォルト設定で問題なく動作します。
  8. package.json の type: "commonjs"。 必須です。ESM では Remotion のバンドラーが動作しません。
  9. SceneWrap の背景色。 AbsoluteFill に backgroundColor: colors.bg を設定してください。背景が透明だと、クロスフェード中に前のシーンが見えてしまいます。
  10. カーソルの点滅速度。 非対称のしきい値 [-1, -0.2, 0.2, 1] → [0, 0, 1, 1] とともに Math.sin(frame * 0.25) を使うと、60% の表示率でリアルな点滅になります。

検証

[ ] npm install completes without errors
[ ] npx remotion studio opens and shows all 3 compositions
[ ] Desktop composition (1920x1080) renders without crashes
[ ] Mobile portrait composition (1080x1920) renders — text is readable
[ ] Mobile landscape composition (1334x750) renders
[ ] No interpolate() calls without extrapolation clamping
[ ] SceneWrap has the safeEnd/safeDur guard for fadeOut=0
[ ] Every scene component receives local frame (frame - scenes.X.from)
[ ] Crossfade overlays have zIndex: 100
[ ] Audio plays with volume changes across transitions
[ ] Full render completes: npx remotion render [Id] out/video.mp4 --timeout=60000

コメント