Communitygithub.com

Remotion Compose

自然言語の動画概要を、すぐにプレビュー可能な完全なRemotionコンポジションに変換します。期間、シーン、ブランドカラー、アスペクト比、実際のコピーを抽出し、フレーム予算を計画し、useCurrentFrame、interpolate、spring、AbsoluteFill、Sequenceを使用したデータ駆動型のReact/TypeScriptコードを作成し、Root.tsxに登録します。

Remotion Compose とは?

Remotion Composeは、自然言語による動画の概要から、すぐにプレビュー実行可能な完全なRemotionコンポジションを自動生成するAIエージェントスキルです。このスキルは、Claude Code、Cursor、CodexなどのAIコーディングエージェント向けに設計されており、製品デモ、チュートリアル、機能紹介、マーケティングアニメーションなどの動画制作を劇的に効率化します。 主なワークフローは、動画の長さ、fps、シーン構成、ブランドカラー、フォント、アスペクト比、実際のコピーなどをユーザーから抽出し、それらを基にフレーム予算を計画します。そして、RemotionのコアAPI(useCurrentFrame、interpolate、spring、AbsoluteFill、Sequence)を駆使したReact/TypeScriptコードを生成し、`src/compositions/`に保存、`src/Root.tsx`に登録します。生成されたコードは、すぐにStudioでプレビューでき、`remotion-render`でレンダリング可能です。 このスキルの大きな利点は、すべてがデータ駆動型である点です。すべてのテキストや色はプロパティとして外部から与えられるため、コピーやカラーパレットの変更は、コードの再生成なしに、異なるプロパティを渡すだけで対応できます。これにより、動画制作の反復作業が大幅に削減されます。また、品質基準として、フレーム予算の正確な合計、useCurrentFrameに基づく純粋なアニメーション、適切なエクストラポレーション設定の使用など、Remotionのベストプラクティスに沿ったコードを生成します。

対応~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/SkillMedev/tutorial-video-studio/tree/main/skills/remotion-compose

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Remotion Compose は何をしますか?

あなたは自然言語による簡潔な概要を、すぐにプレビューできる完全なRemotionコンポジションに変換します。これらは実際のReact/TypeScriptコードであり、フレーム駆動のアニメーションを含みます。出力はsrc/compositions/内の.tsxファイルであり、src/Root.tsxに登録され、ユーザーはStudioですぐにシークバーで操作したり、remotion-renderに渡したりできます。

製品デモ、チュートリアル、機能紹介、マーケティングアニメーションなどの作成、生成、アニメーション化、または「~を表示する20秒の動画コードを書いて」という要求(「Xを表示する20秒の動画を作成」を含む)に対してトリガーされます。

ステップ1 - 概要を抽出する

これらを入手するまではコーディングを開始しないでください。1つのコンパクトなバッチで質問し、明らかなギャップは立ち止まることなく適切なデフォルト値で埋めてください。

  1. Duration(秒単位)とfps(デフォルトは30 - 製品やマーケティング動画の標準であり、60のレンダリングコストの半分です。60fpsが必要なのは、マウスカーソルの細かい動きやスクロールUIをアニメーション化する場合のみで、30fpsでは目に見えてカクつきます。)
  2. Scenes - 何が起こるか、順番に。ビートリストを促してください:「ロゴ、次に3つの機能、そしてCTA」は「私のアプリのデモ」よりも優れています。
  3. Brand - プライマリ/アクセント/背景の16進数カラーと、フォント(@remotion/google-fontsのフォントファミリー名)。
  4. Aspect ratio / platform - 16:9 ランドスケープ(1920×1080)、ソーシャル用の9:16 バーティカル(1080×1920)、または1:1 スクエア(1080×1080)。
  5. Copy - 実際の見出し/機能名/CTAテキスト。製品の主張を決してでっち上げないでください。実際の言葉を尋ねてください。

秒数をフレーム数に変換します:durationInFrames = seconds * fps。 典型的な全長:ソーシャル/製品デモでは15~60秒、広告カットでは6~15秒です。

ステップ2 - シーンプランを作成する

動画ごとに1つの**<Composition>、シーンごとに1つのコンポーネント**を作成し、<Sequence>でタイムライン上に連結します。コードを書く前にフレーム予算をレイアウトします。

合計: 20秒 @ 30fps = 600フレーム
  Intro(ロゴ)         フレーム   0-90    (Sequence from=0   durationInFrames=90)
  機能1                フレーム  90-240   (Sequence from=90  durationInFrames=150)
  機能2                フレーム 240-390   (Sequence from=240 durationInFrames=150)
  機能3                フレーム 390-540   (Sequence from=390 durationInFrames=150)
  CTAアウトロ          フレーム 540-600   (Sequence from=540 durationInFrames=60)

予算化の際のペーシングのしきい値:

  • テキストを含むビートには、少なくとも2秒(30fpsで60フレーム)を与えます - エンターアニメーションとホールドを含みます。見出しは、読みやすくするために単語あたり約150~200ミリ秒のホールドが必要です。6ワードの見出しは、着地した後に約1秒のホールドが必要です。
  • エンターアニメーション:10~20フレーム。クロスフェードとエグジット:12~15フレーム。それ以上長いと緩慢に見え、短いとグリッチのように見えます。
  • 意図的なフラッシュカットでない限り、約45フレームより短いシーンはありません。

<Sequence from={F}>は子のローカルクロックをシフトし、そのコンポーネント内部ではuseCurrentFrame()が0から始まります。各シーンを、フレーム0から始まるかのようにアニメーションさせます。

ステップ3 - コアAPIリファレンス

  • useCurrentFrame() - 現在のフレーム(クロック)。すべてはこれの関数としてアニメーションします。
  • useVideoConfig() - { fps, width, height, durationInFrames }。
  • interpolate(frame, [inFrames], [outValues], opts) - 線形マッピング。エンター/エグジットでは、値が範囲を超えて動作しないように、常に{ extrapolateLeft: "clamp", extrapolateRight: "clamp" }を渡します。
  • spring({ frame, fps, config }) - 物理ベースの0→1(わずかにオーバーシュートします)。生きているように感じさせるもの(ポップ、スライド、スケールイン)に使用します。
  • AbsoluteFill - 全画面の絶対配置div。すべてのシーンのベースレイヤーです。
  • Sequence - 子をタイムシフトおよびタイムバウンドします(シーンスケジューラ)。
  • Series / Series.Sequence - fromオフセットを手動で計算せずに、シーンを連続して配置します。
  • Img, staticFile - ステップ6を参照。

ステップ4 - spring() vs interpolate()

spring()を使う場面interpolate()を使う場面
動作が物理的に感じられるべき場合 - ポップ、バウンス、スケールイン、スライドイン正確なフレーム間で正確でリニアな制御が必要な場合
自然な落ち着きやオーバーシュートが必要な場合フェード(不透明度0→1)、色の変化、プログレスバー、フレームに合わせたタイミングが必要なもの
カード、ロゴ、バッジのエントランスクロスフェードやエグジットで、オーバーシュートが見た目に悪い場合

パターン - トランスフォームをspringで、不透明度をinterpolateで駆動します:

const { fps } = useVideoConfig();
const frame = useCurrentFrame();
const pop = spring({ frame, fps, config: { damping: 200 } });   // 0 → 1, 生き生きと
const opacity = interpolate(frame, [0, 15], [0, 1], { extrapolateRight: "clamp" });
const scale = interpolate(pop, [0, 1], [0.8, 1]);

damping: 200は主力の設定です - ほとんど目立たないオーバーシュートで素早く落ち着きます。より低いダンピング(~10~20)は視覚的にバウンスします。バウンスが目的の場合のみ使用してください。

ステップ5 - 標準的な製品デモ構造

特に指定がない限り、この形状をエンコードします:ロゴ/ブランドイントロ → N個の機能コールアウト → CTAアウトロ。 データ駆動型(ステップ6)にすることで、バリエーションを自由に変更できます。

// src/compositions/ProductDemo.tsx
import {
  AbsoluteFill, Sequence, useCurrentFrame, useVideoConfig,
  interpolate, spring,
} from "remotion";
import { loadFont } from "@remotion/google-fonts/Inter";

const { fontFamily } = loadFont();

export type Feature = { title: string; body: string };
export type ProductDemoProps = {
  brand: string;
  colors: { bg: string; fg: string; accent: string };
  logoText: string;
  features: Feature[];
  cta: string;
};

const Intro: React.FC<{ text: string; colors: ProductDemoProps["colors"] }> = ({ text, colors }) => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  const s = spring({ frame, fps, config: { damping: 200 } });
  const scale = interpolate(s, [0, 1], [0.7, 1]);
  const opacity = interpolate(frame, [0, 12], [0, 1], { extrapolateRight: "clamp" });
  return (
    <AbsoluteFill style={{ backgroundColor: colors.bg, justifyContent: "center", alignItems: "center" }}>
      <h1 style={{ fontFamily, fontSize: 120, color: colors.fg, transform: `scale(${scale})`, opacity }}>
        {text}
      </h1>
    </AbsoluteFill>
  );
};

const FeatureCallout: React.FC<{ feature: Feature; colors: ProductDemoProps["colors"] }> = ({ feature, colors }) => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  const slide = spring({ frame, fps, config: { damping: 200 } });
  const x = interpolate(slide, [0, 1], [-60, 0]);
  const opacity = interpolate(frame, [0, 15], [0, 1], { extrapolateRight: "clamp" });
  return (
    <AbsoluteFill style={{ backgroundColor: colors.bg, justifyContent: "center", paddingLeft: 160 }}>
      <div style={{ transform: `translateX(${x}px)`, opacity }}>
        <div style={{ fontFamily, fontSize: 32, color: colors.accent, fontWeight: 700, letterSpacing: 2 }}>
          {feature.title.toUpperCase()}
        </div>
        <div style={{ fontFamily, fontSize: 64, color: colors.fg, maxWidth: 1100, marginTop: 16 }}>
          {feature.body}
        </div>
      </div>
    </AbsoluteFill>
  );
};

const Outro: React.FC<{ cta: string; colors: ProductDemoProps["colors"] }> = ({ cta, colors }) => {
  const frame = useCurrentFrame();
  const opacity = interpolate(frame, [0, 18], [0, 1], { extrapolateRight: "clamp" });
  return (
    <AbsoluteFill style={{ backgroundColor: colors.accent, justifyContent: "center", alignItems: "center" }}>
      <h2 style={{ fontFamily, fontSize: 84, color: colors.bg, opacity }}>{cta}</h2>
    </AbsoluteFill>
  );
};

export const ProductDemo: React.FC<ProductDemoProps> = ({ colors, logoText, features, cta }) => {
  const intro = 90;
  const per = 150;
  const outro = 60;
  return (
    <AbsoluteFill>
      <Sequence durationInFrames={intro}>
        <Intro text={logoText} colors={colors} />
      </Sequence>
      {features.map((f, i) => (
        <Sequence key={i} from={intro + i * per} durationInFrames={per}>
          <FeatureCallout feature={f} colors={colors} />
        </Sequence>
      ))}
      <Sequence from={intro + features.length * per} durationInFrames={outro}>
        <Outro cta={cta} colors={colors} />
      </Sequence>
    </AbsoluteFill>
  );
};

それをsrc/Root.tsxに登録し、同じ数値からdurationInFramesを計算し、defaultPropsを指定します:

<Composition
  id="ProductDemo"
  component={ProductDemo}
  durationInFrames={90 + 3 * 150 + 60}
  fps={30}
  width={1920}
  height={1080}
  defaultProps={{
    brand: "Acme",
    colors: { bg: "#0B0B0F", fg: "#FFFFFF", accent: "#6C5CE7" },
    logoText: "Acme",
    features: [
      { title: "高速", body: "スプリントではなく秒単位で出荷。" },
      { title: "シンプル", body: "1つのプロンプト、1つの動画。" },
      { title: "あなたのもの", body: "あなたのブランド、あなたのコピー。" },
    ],
    cta: "無料で始める →",
  }}
/>

バーティカル/ソーシャル用には、width={1080} height={1920}を設定します。スクエア用には1080×1080です。コンポーネントは同一に保ちます - キャンバスのみが変更されます。

ステップ6 - データ駆動型プロパティと静的アセット

上記のコンポジションは完全にデータ駆動型です。すべての単語と色はプロパティです。これがポイントです - バリエーション(新しいコピー、新しいパレット、ローカライズされたテキスト)は再プロンプトが不要で、異なるプロパティを渡すだけです(remotion-renderはバッチ処理のためにJSONファイルからこれを行います)。

静的アセット(ロゴ、スクリーンショット、オーディオ)はpublic/assets/に配置し、staticFile()で参照します - インポートや生のパスは使用しません:

import { Img, staticFile } from "remotion";
<Img src={staticFile("assets/logo.png")} />

ステップ7 - 出力

完成したファイルをsrc/compositions/<VideoName>.tsxに保存し、src/Root.tsxに登録し、npx remotion studio(http://localhost:3000)でプレビューするようにユーザーに伝えます。その後、引き継ぎます:*「Studioでシークバーを操作してください。変更点(速すぎる、色が間違っている、別のコピーが必要など)があれば教えてください。編集して再レンダリング(`remotion-render`)します。」*

やってはいけないこと

  • CSSトランジション/アニメーションやsetTimeout/setIntervalでアニメーションさせてはいけません。Remotionは各フレームを独立して並行にレンダリングします。useCurrentFrame()から派生していないものは、ブラウザプレビューでは正しく見えても、最終レンダリングでは見えないか、一貫性がありません。
  • 散乱/パーティクル効果にMath.random()を使用してはいけません。すべてのレンダラワーカーが異なる値を取得し、フレームが一致しなくなります。決定論的な疑似ランダム性には、Remotionのrandom(seed)を使用してください。
  • delayRender() / continueRender()なしでデータをフェッチしたり、非同期処理を待機したりしてはいけません。レンダラーはデータが到着する前にフレームをキャプチャします。
  • シーンコンポーネント内でfps、width、heightをハードコードしてはいけません。useVideoConfig()から読み取ることで、30↔60fpsの切り替えやランドスケープ↔バーティカルの変更がすべてのタイミングとレイアウトを壊さないようにします。
  • エンター/エグジットの補間でextrapolateLeft/Right: "clamp"を省略してはいけません。不透明度が1を超えて上昇したり、要素が範囲終了後にキャンバス外にドリフトしたりします。
  • 見出し、機能の主張、CTAをでっち上げてはいけません。ユーザーの実際のコピーを使用し、欠落している場合はそれを尋ねてください。

品質基準

  • すべてのアニメーション値は、useCurrentFrame()(とプロパティ)の純粋な関数です。Studioで逆方向にシークバーを操作しても、前方に再生するのと同一に見えます。
  • プランのフレーム予算がRoot.tsxのdurationInFramesと正確に一致し、テキストビートが読み取り可能な最小時間未満で保持されることはありません。
  • すべてのコピーと色は、defaultPropsが指定された型付きプロパティを介して届きます。シーンコンポーネントにリテラルが埋め込まれていません。
  • アセットはstaticFile()を介して読み込まれます。ファイルはクリーンに登録され、Studioでコンソールエラーなしでプレビューされます。

Individual skills in this repo

This repo contains 11 individual skills — each has its own dedicated page.

Captions From Transcript

Produce an accurate, properly timed caption track (SRT or WebVTT) from a video

Kinetic Typography

Put text in motion the right way - title cards, animated captions, lower-thirds, callouts, and word-by-word reveals - with a reading-time-per-word budget so copy holds long enough to read, plus enter/exit timing, weight and size transitions, and type hierarchy in motion. Use when someone asks to

Motion Design Principles

The craft layer for motion: pick the right easing (ease-in / ease-out / ease-in-out / spring), get timing and spacing right, build the anticipation→action→follow-through arc, and apply Disney

Narration Script

Write the spoken voiceover for a tutorial or demo - the actual words, phrased for the ear and synced one-instruction-per-action to what is on screen, with a pacing budget and a confident, jargon-checked tone. Use when someone says

Product Demo Director

Direct the craft of putting a real software UI on screen - cursor choreography, zoom/pan/callout language, screen-recording vs recreated-UI, and making state changes legible with highlights, focus pulls, and slow-downs. Use when filming or recreating an app for a product demo, feature walkthrough, onboarding clip, or release reel and asking

Remotion Render

Renders a Remotion composition to MP4 and runs the edit-and-re-render loop - CLI render commands, 1080p/4K/9:16 presets, concurrency tuning, codec selection, batch variants from a JSON data file, and Lambda for cloud rendering. Use when someone says

Remotion Setup

Scaffolds a new Remotion video project wired for Claude Code Agent Skills - Node check, create-video scaffold, skills install, folder conventions, Google Fonts, and a smoke-test render. Use whenever someone wants to start making videos with Remotion and Claude, even just

Screencast Capture

Capture clean raw screen and camera footage for a tutorial or product demo - choosing the recorder (macOS Screenshot toolbar, QuickTime, OBS, Windows Game Bar), setting resolution / frame-rate / cursor / microphone, prepping a distraction-free stage, and recording in retakeable segments. Use when someone says

SkillMedev/tutorial-video-studio

Plan a product demo, feature announcement, or launch video as a beat sheet and shot list BEFORE animating - hook in the first 3s, problem, reveal, proof, CTA - with target duration and pacing per scene type, output as a JSON scene plan that remotion-compose consumes directly. Use when someone says

Social Video Formatter

Reframe and export a finished video for social platforms - 9:16 ↔ 16:9 cropping, burned-in captions, a platform-native first frame, loop design, and per-platform specs (aspect, length, safe areas) for TikTok, Reels, Shorts, X, and LinkedIn. Use when someone says

Sound and Music Sync

Score a video like an editor: beat-match cuts to the music, land SFX on transitions, pace the voiceover so it breathes, source royalty-free tracks safely, and duck the music so the VO sits clearly on top. Use when adding music, sound effects, or voiceover to a video, when asked to

関連スキル