Communitygithub.com

JaviMaligno/agilabs-video-studio

Remotion で記事の説明動画のシーンを構築します。承認済みのスクリプトから src/timeline.ts を作成し、アニメーションコンポーネント(Counter、BarCompare、FlowDiagram、KeyQuote、StatGrid)を選択・設定し、テスト済みの frameState を持つカスタムコンポーネントを追加します。縦の安全領域を守り、レンダリングされたスチルを目視で確認します。このプラグインを使用して動画のシーンを構成、変更、デバッグする際に使用してください。

agilabs-video-studio とは?

このスキルは、Remotion ベースの動画スタジオプラグインにおいて、記事説明動画の全シーンを構築・管理するためのものです。`src/timeline.ts` にシーンを定義し、イントロ、アニメーション、アウトロの3種類を組み合わせます。各シーンには、Counter や BarCompare など、事前定義されたアニメーションコンポーネントを割り当て、ナレーションラインと同期させることができます。また、カスタムコンポーネントを追加するための手順も含まれており、まず純粋な `frameState` 関数をテスト駆動で作成し、その後 React コンポーネントとして描画、最後にレジストリに登録します。安全領域(1080x1920 の縦型)を厳守し、すべてのスチルを目視チェックすることで、オーバーフローやテキストのクリッピングを防止します。対応プラットフォームは Remotion、CLI、および開発スタジオです。

対応~Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/JaviMaligno/agilabs-video-studio/tree/HEAD/skills/explainer-animation

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

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

ドキュメント

説明用アニメーション

動画は src/timeline.ts 内のシーンが順に並んだものです。3種類あります:

  • intro: フックカード。最初の行がフックで大きく表示され、読み上げられるにつれて単語が光ります(キャプションを兼ねます)。
  • anim: レジストリから1つのアニメーションコンポーネントを、シーンのナレーションラインに同期させて配置します。
  • outro: AGILabs バッジ、「javieraguilar.ai」、および SETTINGS.articleTitle の記事タイトルを表示する閉じカード。

タイムラインの作成

import type { Cuts } from './types.ts';
import { L, anim, intro, outro, say, videos } from './narrate.ts';

const build = (): Cuts => ({
  main: [
    intro('hook', [say(0.4, 'EN hook line.', 'ES hook line.')]),
    anim(
      'result',
      'BarCompare',
      { bars: [{ label: L('With the reason', 'Con el porqué'), value: 14, display: '14/20', highlight: true },
               { label: L('Without it', 'Sin él'), value: 4, display: '4/20' }], max: 20 },
      [say(0.3, 'First line.', 'Primera línea.'), say(0, 'Second line.', 'Segunda línea.')],
      { min: 4 },
    ),
    outro('outro', [say(0.4, 'More at javieraguilar.ai.', 'Más en javieraguilar.ai.')]),
  ],
});

export const VIDEOS = videos(build);
export const TIMELINE = VIDEOS.en.main;
  • say(at, en, es, spoken?): 1つのナレーション行。at は開始可能な最も早いシーン秒数です。行が重なることはありません(0.35 秒のギャップ)。シーンは最後の行が終了してから 0.8 秒後、または min の長さまで続きます。spoken ({ en?, es? }) は、キャプションテキストと異なる場合に TTS が読み上げる内容です(narration 参照)。
  • ビート. シーン内の各行の開始時間がビートです。コンポーネントはビート i でステップ i を再生します(バー i が成長、ノード i が出現、タイル i がポップイン)。したがって、表示したいステップごとに1行ずつ記述します。TTS 前は、ビートは長さの推定値から得られます。npm run tts の後は、実際の音声から得られるため、ナレーション後にスチルを再確認してください。
  • L(en, es): 画面上のバイリンガルラベル。プレーンな文字列は両方の言語で使用されます。
  • シーンIDは一意である必要があります。ラインキー(<scene>-01、...)は音声ファイルの名前となります。
  • anim の opts.chapter はシーンに保存されますが、まだどのコンポーネントでも描画されません。
  • 変更後は毎回 npm run lint を実行してください。targetSeconds に対する長さ(±20%)、キャプションキューが 0.8 秒未満または 17 文字/秒を超えていないか、レジストリにないコンポーネント名がないかをチェックします。

コンポーネントカタログ

すべてのコンポーネントは、シーンから t、beats、dur、lang、vertical を受け取ります。以下の props はタイムラインから渡されます。画面に表示される数字は、記事の正確な形式を使用します。記事に「14/20」「0.0018」「83%」と書かれている場合は、計算されたテキストではなく display / 文字列の value を優先してください。

コンポーネント用途Props
Counter1つの見出し数字をカウントアップし、その下にラベルを表示value: number, label: Label, prefix?, suffix?, decimals? (0-8), beat?(カウントを開始するビートのインデックス、デフォルト0)
BarCompare2〜5本の水平バーをビートごとに1本ずつ成長表示。ハイライトされたバーはアクセントグラデーションbars: { label: Label; value: number; display?: string; highlight?: boolean; at?: number }[], max?(スケールの上限、デフォルトは最大値), unit?(display がない場合に追加)
FlowDiagram順番に表示されるボックスと矢印。broken エッジは破線でミュートされ、ギャップありnodes: { id; label: Label; at?: number }[], edges: { from; to; label?: Label; broken?: boolean }[], `layout: 'vertical'
KeyQuoteキーセンテンスを単語ごとに表示。強調された単語はアクセントカラーで下線付きtext: Label, emphasis?: string[](単語またはフレーズ、大文字小文字と句読点を無視して一致), beat?
StatGrid2〜4つの数値タイルをビートごとに1つずつポップイン表示stats: { value: string; label: Label; at?: number }[]

バー、ノード、タイルの at は、その要素を自身のビートではなくシーン秒数に固定します。ビートや at がないステップは、前のステップから 0.6 秒後に続きます。すべてのコンポーネントはシーン終了までに終了するように調整されています。最後のフレームには常に完了状態が表示されます。

全ライブラリを確認するには: npm run studio を実行して Gallery-vertical を開くか、そのスチルをレンダリングします。

カスタムコンポーネントの追加

スクリプトがシーンを「bespoke」とフラグ付けした場合:

  1. まず状態を、テスト付きで作成。 props の型と、プレーンな数値と文字列を返す純粋な frameState(props, t, beats, dur) を含む src/anim/<Name>.state.ts を作成します。そこには Remotion や React のインポートはありません。src/anim/steps.ts(sceneTime、stepTimes、fit、progress、beatAt、easeOutCubic)上に構築し、以下の要件を満たします: 任意の t で有限値、progress フィールドは [0, 1] の範囲、最初のビートより前には何も表示されない、t = dur で終了状態になる。
  2. test/anim.test.ts の CASES にケースを追加し(および自身の動作をテストするテスト)、npm test を実行します。これは、t < 0、すべてのビート、dur、dur を超えた場合について、欠落、遅延、非常に短いビートを含む状態をチェックします。
  3. 描画 を src/anim/<Name>.tsx で行います: frameState を呼び出し、<Stage vertical={...}> 内に描画し、src/brand.ts のブランドトークン(C、GRADIENT、alpha)と Inter フォントを使用します。新しい色やフォントは追加しないでください。
  4. 登録 を src/anim/index.ts の ANIMS に行います。ANIMS は名前のプレーンなオブジェクトリテラルのままにしてください。npm run lint がソースから読み取ります。
  5. オプションでサンプルを src/Gallery.tsx に追加します。再利用可能な場合、プラグインのテンプレートに戻す必要があります。

生成画像. ほとんどのシーンはコード(ブランドトークンを使用した SVG と CSS)で描画する必要があります。シーンで本当に生成画像(背景、ベース画像、テクスチャ部分)が必要な場合、画像モデル(例: Codex CLI の画像生成)で作成できます。public/ の下に保存し、staticFile() で読み込み、ブランドパレット内に収め、スチルを確認します。

縦の安全領域 (1080x1920)

  • プラットフォーム UI は上部約 220 px と下部約 380 px をカバーします。側面は 72 px を確保します。
  • アニメーションはステージ内のみに描画されます: y = 280(AGILabs バッジの下)から y = 1280(2つのキャプション行の上)まで、幅 936 px。Stage / stageOf() でそのボックスを取得できます。
  • キャプションはステージの下に、最大2行、約32文字、幅約900 px 以内で配置されます。

スチル: 目視で確認

スチルをレンダリングし、動画をレンダリングする前に すべての PNG を読んで ください。クリーンな lint やビルドでは、オーバーフロー、クリッピングされたテキスト、誤った数字は表示されません。

npx remotion still src/index.ts Main-EN-vertical out/stills/f0150.png --frame=150

各シーンの最後のステップが再生された後に1枚、さらに約3秒ごと(30 fps で90フレームごと)に1枚のスチルを取得します。確認項目: AGILabs バッジ以外のブランディングがないこと、安全領域の外に何もないこと、テキストがボックスからあふれていないこと、すべての数値が記事と一致していること、画面上のキャプションがその瞬間のアニメーションと一致していること。

Individual skills in this repo

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

関連スキル