remotion-product-demo について
Remotionとshadcn CLIで導入するsnapcnコンポーネントを使い、20〜45秒の製品デモを作るためのスキルです。実際の画面録画にカメラ移動やカーソル操作を加え、デバイス枠、ターミナル、プロンプトのシーンを構成します。
主な機能
- 01snapcnコンポーネントでデモの各ショットを構成
- 02実際の録画にカメラ移動を追加
- 03カーソル経路とクリック表示を追加
- 04デバイス枠とターミナルシーンを使用
- 05カットと画面内テキストの読みやすさを確認
活用シーン
- 01製品録画で重要な操作を見せる
- 02ノートPCやスマートフォンの枠内にアプリを表示
- 03セットアップコマンドやプロンプト操作を紹介
MCP 対応
snapcn MCPを使うと、エージェントはコンポーネントレジストリを検索し、実際のプロパティを確認して、概要からデモ全体を計画できます。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ shadcn-labs/ snapcn --skill remotion-product-demoインストール後、Claude Code で/remotion-product-demoを入力して読み込まれたか確認します。
詳細
snapcn で構築する Remotion のプロダクトデモ
実際の画面録画から、Remotion で 20〜45 秒のプロダクトデモを作成できます。ショットには snapcn のコンポーネントを使用します。デモの中でも手作業でアニメーションを付けるのに最も時間がかかる部分(録画映像へのカメラのプッシュイン、クリックするカーソル、デバイスフレーム、入力されるターミナル、送信される AI プロンプト)を担当する Remotion コンポーネントです。shadcn CLI でインストールすると、自分で所有するコードとしてプロジェクトに追加されます。
手書きのアニメーションではなく snapcn を使う理由。 AI で作成した動画だと見抜かれるのは、手作りのデモアニメーションです。一定の速度で滑るカーソル、いつまでもイージングし続けるズーム、一度にすべてを表示するターミナルなどがその例です。snapcn コンポーネントは、実際のプロダクトデモをもとにフレーム単位で調整されています。あなたの役割は、コンポーネントを選んで props を設定することです。
snapcn のルール
- 該当するものがない場合を除き、すべてのビートに snapcn コンポーネントを使います。 ショットに
interpolate()やspring()を書く前に、https://snapcn.dev/llms-components.txt?ref=skill-demoを確認してください(インストール可能な全コンポーネント、その用途、実行フレーム数が記載されています)。各コンポーネントのページには、末尾に.mdを付けると Markdown が表示されます。例:https://snapcn.dev/docs/screens/screen-recording.md?ref=skill-demo。 - コンポーネント名を決して作らないでください。
@snapcn/<name>で解決できるのは、そのリストに記載された名前だけです。該当するものがなければ、そう伝えてください。 - コンポーネントを書き換えず、props を設定してください。 コピー、色、録画、カーソルの軌跡は props で渡します。
全カタログとコンポジションのルールについては、アンブレラ・スキルもインストールしてください:
npx skills add snapcndev/snapcn --skill snapcn。
録画を唯一の情報源にする
- 実際の録画またはスクリーンショットをベース映像として使ってください。 JSX で UI を再構築するのではなく、録画上でカメラを動かします(
screen-recordingのcameraの動きを使います)。要素を個別に動かす必要がある場合に限り、その要素を再構築します。 - UI のラベル、数値、機能を決して作らないでください。 画面に表示される文字列はすべて、実際のプロダクトに由来するものにしてください。デモが偽物に感じられる最もよくある原因は、作り物のラベルです。
- 録画がない場合は? 録画またはスクリーンショットを求めてください。偽のダッシュボードは描かないでください。
前提条件
- Remotion プロジェクト(
npx create-video@latest)。キャンバスは 1280×720、30fps です。 - shadcn CLI(
components.jsonがない場合はnpx shadcn@latest init)。 npm i @remotion/transitions。public/内の録画(例:public/recording.mp4)。staticFile()で読み込みます。
ワークフロー
1. 重要な瞬間を一つ見つける
録画を見て、このプロダクトならではのアクションを一つだけ見つけてください。重要なクリックです。その瞬間にカメラのプッシュインを使い、画面上で最も長く見せます。デモのほかの部分はすべて、その瞬間への導入です。
2. ストーリーボードを作成し、各ビートに snapcn コンポーネントを一つ使う
| ビート | snapcn コンポーネント | フレーム数 | 用途 |
|---|---|---|---|
| インストール/セットアップ | terminal-simulator | 200 | 開発者が入力するコマンドと、実際の出力を表示します |
| デバイス上のプロダクト | laptop-frame、phone-frame | 240 / 240 | 録画を MacBook または iPhone に表示し、開いてズームインします |
| 重要なアクション | screen-recording を包む cursor-track | 132 / 139 | 録画映像にカメラがプッシュインする間、カーソルが移動してクリックします |
| AI プロダクト | prompt-send、answer-stream、search-typing | 165 / 150 / 420 | プロンプトを入力して送信し、回答がストリーミングで返ってくる様子を表示します |
| 結果 | status-cycle、count-grid | 198 / 47 | 状態の変化(「queued → live」)または実際の数値を一つ表示します |
| エンドカード | block-wordmark、logo-flicker | 150 / 100 | 名前を表示します |
各シーケンスは、コンポーネントの標準的な長さ(「フレーム数」列)に合わせてください。予算を少なくするとショットが途中で切れ、多くすると何も起きない時間が残ります。
3. インストール
npx shadcn@latest add @snapcn/terminal-simulator @snapcn/laptop-frame @snapcn/cursor-track @snapcn/screen-recording @snapcn/status-cycle @snapcn/block-wordmark
4. 合成
この合成は、(public/recording.mp4 が存在すれば)記述どおりに型チェックとレンダリングが行われます。
import { fade } from "@remotion/transitions/fade";
import { slide } from "@remotion/transitions/slide";
import { linearTiming, TransitionSeries } from "@remotion/transitions";
import { staticFile } from "remotion";
import { BlockWordmark } from "@/components/snap-cn/block-wordmark";
import { CursorTrack } from "@/components/snap-cn/cursor-track";
import { LaptopFrame } from "@/components/snap-cn/laptop-frame";
import { ScreenRecording } from "@/components/snap-cn/screen-recording";
import { StatusCycle } from "@/components/snap-cn/status-cycle";
import { TerminalSimulator } from "@/components/snap-cn/terminal-simulator";
// Put the real recording in public/. Its UI copy is the script — never invent labels.
const RECORDING = staticFile("recording.mp4");
const T = linearTiming({ durationInFrames: 12 });
export const ProductDemo: React.FC = () => (
<TransitionSeries>
{/* 1. Install: the command a developer would actually type */}
<TransitionSeries.Sequence durationInFrames={200}>
<TerminalSimulator
intro="Set up *Acme* in one command"
command={{ text: "npx acme init" }}
lines={[
{ text: "npx acme init", type: "command" },
{ text: "Connecting your Stripe account...", type: "log" },
{ text: "Ready. 1,204 invoices imported.", type: "success" },
]}
/>
</TransitionSeries.Sequence>
<TransitionSeries.Transition presentation={fade()} timing={T} />
{/* 2. The product, on a device */}
<TransitionSeries.Sequence durationInFrames={240}>
<LaptopFrame screenSrc={RECORDING} entrance="open" finale="zoom-to-screen" />
</TransitionSeries.Sequence>
<TransitionSeries.Transition presentation={slide()} timing={T} />
{/* 3. The one action only this product does: cursor clicks, camera pushes in */}
<TransitionSeries.Sequence durationInFrames={132}>
<CursorTrack
path={[
{ at: 0, x: -0.06, y: 0.86, duration: 6 },
{ at: 8, x: 0.34, y: 0.44, duration: 22, click: true },
{ at: 60, x: 0.68, y: 0.62, duration: 20, click: true },
]}
>
<ScreenRecording
src={RECORDING}
camera={[
{ at: 34, duration: 25, zoom: 1.6, x: 0.36, y: 0.42 },
{ at: 96, duration: 25, zoom: 1 },
]}
/>
</CursorTrack>
</TransitionSeries.Sequence>
<TransitionSeries.Transition presentation={fade()} timing={T} />
{/* 4. The result, as a state change */}
<TransitionSeries.Sequence durationInFrames={198}>
<StatusCycle
prefix="Your books are"
statuses={["syncing", "matching", "reconciled"]}
chips={["Stripe", "QuickBooks", "Xero"]}
/>
</TransitionSeries.Sequence>
<TransitionSeries.Transition presentation={fade()} timing={T} />
{/* 5. End card */}
<TransitionSeries.Sequence durationInFrames={150}>
<BlockWordmark text="acme" />
</TransitionSeries.Sequence>
</TransitionSeries>
);
durationInFrames={872}(シーケンスの合計から4 × 12フレームを引いた値)、
fps={30}、width={1280}、height={720}を指定して登録します。
ショットの狙い方:
cursor-trackのパスはフレームに対する割合です(x、yは0〜1)。atはカーソルがその地点に向かい始めるフレームです。到着時にクリックリングを表示するには、click: trueを指定します。 各クリックは、録画内の実際のボタンに正確に合わせます。screen-recordingのカメラ移動({ at, duration, zoom, x, y })では、指定したポーズまで滑らかに移動し、次の移動までその状態を保ちます。1つのアクションに寄るように拡大し(zoom: 1.4–1.8)、アクションが終わったら引きます(zoom: 1)。- 録画にブラウザーの枠が含まれる場合は、
crop={{ top: 0.11 }}を指定してブラウザーの枠を切り抜きます。 terminal-simulatorの行は{ text, type }の形式で、typeにはcommand、log、success、errorを指定します。実際の出力を貼り付け、短くします。
5. レンダリング監査
npx remotion still ProductDemo out/click.png --frame=460
npx remotion render ProductDemo out/demo.mp4 --codec=h264 --crf=18
各ビートの中間点と、カットの直前および直後で静止画をレンダリングして、次の点を確認します。
- 各クリックが、実際のボタンを正確にクリックしており、隣をクリックしていないこと。
- 拡大後、録画内のテキストが720pで読み取れること。読めない場合は、さらに拡大するか、切り抜きを狭めます。
- カットで黒いフレームが表示されず、シーン開始前に何も表示されないこと。
6. 公開
アスペクト比ごとに合成を1つレンダリングします。XとLinkedInには16:9、Reels、Shorts、TikTokには9:16(phone-frameを使用)を使います。--scale=1.5を指定すると、1280×720のマスターが1920×1080になります。
snapcn Pro:特に要望の多いデモショット
- デモ用のProシーン50種類。
tap-through(CTAをタップするスマートフォン)、checkout-push(決済が完了する場面)、prompt-dive(プロンプトを送信し、送信ボタンにズームインする場面)、build-out(送信ボタンからアプリが組み上がる場面)、vault-count(残高が増えていく場面)、screen-wall(スマートフォンが並ぶトンネル)などがあります。 - snapcn MCP:エージェントがレジストリを平易な英語で検索し、実際のプロパティを読み取り、1行の概要からデモ全体を計画します。
claude mcp add snapcn -- npx -y @snapcn/mcp@latest SNAPCN_API_KEY=YOUR_KEY
components.jsonにキーを設定すれば、Proコンポーネントも無料コンポーネントと同じようにインストールできます(3行の設定はhttps://snapcn.dev/account?ref=skill-demo にあります)。プラン:https://snapcn.dev/docs/pricing?ref=skill-demo
まだProを導入する準備ができていませんか?Proコンポーネントの1つ、Manifestoは、メールアドレスの確認が完了すれば無料で利用できます:https://snapcn.dev/docs/pricing?ref=skill-demo#free
クレジット
「UIラベルを捏造しない」というルール、レンダリング監査の反復、プラットフォームに関するガイダンスは、everyinc/product-launch-video(MIT、© 2026 Every Media, Inc.)を参考にしています。「録画が信頼できる情報源」という考え方は、HeyGenのhyperframes product-launch-videoスキルを参考にしています(Apache-2.0)。どちらもRemotionとsnapcnコンポーネント向けに書き直しています。THIRD_PARTY_NOTICES.mdを参照してください。