mcpField
S
stitch-remotion

stitch-remotion

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

stitch-remotion について

Stitch のアプリデザインを Remotion のウォークスルー動画にするワークフロースキルです。画面の取得、素材の準備、コンポジション構築、トランジションやテキストの追加、プレビュー、レンダリングを案内します。

主な機能

  1. 01Stitch の画面とスクリーンショットを取得
  2. 02画面マニフェストと素材を準備
  3. 03トランジション付き Remotion スライドを構築
  4. 04ズーム効果とテキストを追加
  5. 05動画をプレビューしてレンダリング

活用シーン

  1. 01アプリ画面からデモを作成
  2. 02機能紹介のウォークスルー動画を制作
  3. 03デザイン資料を動画化

MCP 対応

list_projects、list_screens、get_screen などの Stitch MCP ツールでデザインを探し、スクリーンショット URL を取得します。その素材を使って Remotion 動画を作成します。

インストール

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

$npx skills add https://github.com/gabelul/stitch-kit --skill stitch-remotion

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

詳細

Stitch → Remotion のウォークスルー動画

制約: ユーザーが「Stitch」とウォークスルー動画、デモ、または Remotion に明示的に言及した場合に限り、このスキルを使用してください。

Stitch のアプリデザインからウォークスルー動画を制作する動画制作のスペシャリストです。Stitch のスクリーンショットを取得し、スライド遷移、ズームアニメーション、テキストオーバーレイを備えた Remotion コンポジションを作成します。

前提条件

  • Stitch MCP Server(または既知の画面 ID)
  • Node.js 18+ と npm
  • Remotion CLI(npm install -g remotion、または npx 経由で使用)

ステップ 1:Stitch のアセットを収集する

画面を見つける
  1. list_tools を実行 → Stitch MCP のプレフィックスを確認
  2. [prefix]:list_projects を呼び出す → プロジェクトを選択
  3. projects/[projectId] を指定して [prefix]:list_screens を呼び出す → すべての画面を一覧表示
  4. 動画に使用する各画面について、数値 ID を指定して [prefix]:get_screen を呼び出す
スクリーンショットをダウンロードする

各画面について:

# Download screenshot to assets directory
curl -L "[screenshot.downloadUrl]" -o "video/public/assets/[screen-name].png"

または、フェッチスクリプトを使用します:

bash scripts/fetch-stitch.sh "[htmlCode.downloadUrl]" "temp/[screen-name].html"
# Screenshots are separate — download via curl with the screenshot URL
画面マニフェストを作成する

動画を記述する screens.json を作成します:

{
  "projectName": "My App",
  "fps": 30,
  "screens": [
    {
      "id": "home",
      "title": "Home Screen",
      "description": "Main dashboard with key metrics",
      "imagePath": "./public/assets/home.png",
      "width": 390,
      "height": 844,
      "durationSeconds": 4
    },
    {
      "id": "profile",
      "title": "User Profile",
      "description": "Settings and account management",
      "imagePath": "./public/assets/profile.png",
      "width": 390,
      "height": 844,
      "durationSeconds": 3
    }
  ]
}

ステップ 2:Remotion プロジェクトをセットアップする

# Create new Remotion project inside the working directory
cd video
npm create video@latest -- --blank
cd walkthrough-video
npm install @remotion/transitions

ステップ 3:コンポジションを作成する

ScreenSlide コンポーネント
// video/src/ScreenSlide.tsx
import { AbsoluteFill, Img, interpolate, spring, useCurrentFrame, useVideoConfig } from 'remotion'

interface ScreenSlideProps {
  /** Path to the screenshot image */
  imagePath: string
  /** Screen title displayed as overlay */
  title: string
  /** Supporting description text */
  description: string
  /** Whether to zoom in slightly during display */
  withZoom?: boolean
}

/**
 * Single screen slide with optional zoom effect and text overlay.
 * Fades in, holds, then fades out.
 */
export function ScreenSlide({ imagePath, title, description, withZoom = true }: ScreenSlideProps) {
  const frame = useCurrentFrame()
  const { fps, durationInFrames } = useVideoConfig()

  // Fade in over first 15 frames
  const fadeIn = spring({ fps, frame, config: { damping: 200 } })

  // Subtle zoom: 100% → 105% over the duration
  const scale = withZoom
    ? interpolate(frame, [0, durationInFrames], [1, 1.05], { extrapolateRight: 'clamp' })
    : 1

  return (
    <AbsoluteFill style={{ backgroundColor: '#000' }}>
      {/* Screenshot */}
      <AbsoluteFill style={{ opacity: fadeIn, transform: `scale(${scale})`, transformOrigin: 'center' }}>
        <Img src={imagePath} style={{ width: '100%', height: '100%', objectFit: 'contain' }} />
      </AbsoluteFill>

      {/* Bottom text overlay */}
      <AbsoluteFill
        style={{
          justifyContent: 'flex-end',
          padding: '40px 60px',
          background: 'linear-gradient(transparent, rgba(0,0,0,0.7))',
          opacity: fadeIn,
        }}
      >
        <h2 style={{ color: '#fff', fontSize: 36, fontWeight: 700, margin: 0 }}>{title}</h2>
        {description ? (
          <p style={{ color: 'rgba(255,255,255,0.8)', fontSize: 20, margin: '8px 0 0' }}>
            {description}
          </p>
        ) : null}
      </AbsoluteFill>
    </AbsoluteFill>
  )
}
ウォークスルーコンポジション
// video/src/WalkthroughComposition.tsx
import { Series, TransitionSeries } from '@remotion/transitions'
import { fade } from '@remotion/transitions/fade'
import { slide } from '@remotion/transitions/slide'
import screensData from '../../screens.json'
import { ScreenSlide } from './ScreenSlide'

const TRANSITION_FRAMES = 15  // 0.5s at 30fps

/**
 * Main walkthrough composition — one screen per slide, fade/slide transitions.
 */
export function WalkthroughComposition() {
  return (
    <TransitionSeries>
      {screensData.screens.map((screen, i) => (
        <>
          <TransitionSeries.Sequence
            key={screen.id}
            durationInFrames={screen.durationSeconds * screensData.fps}
          >
            <ScreenSlide
              imagePath={screen.imagePath}
              title={screen.title}
              description={screen.description}
            />
          </TransitionSeries.Sequence>
          {/* Add transition between screens (except after the last) */}
          {i < screensData.screens.length - 1 && (
            <TransitionSeries.Transition
              key={`t-${screen.id}`}
              timing={fade({ durationInFrames: TRANSITION_FRAMES })}
            />
          )}
        </>
      ))}
    </TransitionSeries>
  )
}
Root.tsx に登録する
// video/src/Root.tsx
import { Composition } from 'remotion'
import { WalkthroughComposition } from './WalkthroughComposition'
import screensData from '../../screens.json'

const TOTAL_FRAMES = screensData.screens.reduce(
  (acc, s) => acc + s.durationSeconds * screensData.fps,
  0
)

export const RemotionRoot = () => (
  <>
    <Composition
      id="Walkthrough"
      component={WalkthroughComposition}
      durationInFrames={TOTAL_FRAMES}
      fps={screensData.fps}
      width={screensData.screens[0]?.width ?? 390}
      height={screensData.screens[0]?.height ?? 844}
    />
  </>
)

ステップ 4:プレビューしてレンダリングする

# Preview in browser
cd video/walkthrough-video
npm run dev

# Render to MP4
npx remotion render Walkthrough output.mp4

# Higher quality render
npx remotion render Walkthrough output.mp4 --jpeg-quality 95 --concurrency 4

よくある動画スタイル

スタイル設定
クイックデモ(1~2 分)画面ごとに 2~3 秒、フェード遷移、タイトルのみ
機能のウォークスルー画面ごとに 4~5 秒、ズーム+スライド、タイトル+説明
プレゼンテーション資料画面ごとに 5~8 秒、フェードのみ、説明全体をオーバーレイ表示
ソーシャルメディアクリップ画面ごとに 1~2 秒、素早いカット、音楽トラック

ファイル構成

project/
├── screens.json             ← Screen manifest
├── scripts/fetch-stitch.sh  ← GCS downloader
└── video/
    ├── public/
    │   └── assets/          ← Downloaded screenshots
    └── walkthrough-video/
        ├── src/
        │   ├── WalkthroughComposition.tsx
        │   ├── ScreenSlide.tsx
        │   └── Root.tsx
        ├── remotion.config.ts
        └── package.json

トラブルシューティング

問題対処方法
スクリーンショットがぼやけるフル解像度でダウンロードします。サムネイルではなく、スクリーンショットの URL を直接使用してください
レイアウトが一致しないget_screen で取得した画面の width と height に合わせて、Remotion コンポジションのサイズを設定します
遷移が不自然TRANSITION_FRAMES を増やすか、slide から fade に切り替えます
ESM でビルドに失敗するpackage.json に "type": "module" を追加し、Remotion のバージョン互換性を確認します
MP4 が再生されないFFmpeg がインストールされていることを確認します:ffmpeg -version

参考資料

  • Remotion のドキュメント:https://www.remotion.dev/docs/
  • Remotion のトランジション:https://www.remotion.dev/docs/transitions
  • scripts/fetch-stitch.sh — 信頼性の高い GCS ダウンローダー
  • stitch-mcp-list-screens — Stitch プロジェクト内の画面を見つける
  • stitch-mcp-get-screen — スクリーンショットのダウンロード URL を取得する

コメント