Imgcli 製 Remotion プロダクトデモ
実際の画面収録を、Remotion で 20~45 秒のプロダクトデモに変換します。ショットは Imgcli から提供されます。これは、デモの中で手動アニメーションに最も時間がかかる部分(録画へのカメラの押し込み、クリックするカーソル、デバイスフレーム、タイピングするターミナル、送信される AI プロンプト)のための Remotion コンポーネントです。これらは shadcn CLI でインストールされ、あなたが所有するコードとしてプロジェクトに配置されます。
なぜ手書きアニメーションではなく Imgcli なのか。 手作りのデモモーションは、AI 生成動画であることを見破られる原因です。カーソルが一定速度でスライドする、ズームがいつまでもイージングする、ターミナルが一度にすべてを表示するといった動作です。Imgcli コンポーネントは、実際のプロダクトデモに基づいてフレーム単位で調整されています。あなたの仕事はそれらを選び、プロップを埋めることです。
Imgcli のルール
- 各ビートは、適切なものがない場合を除き、Imgcli コンポーネントを使用します。 ショットに
interpolate()やspring()を書く前に、https://imgcli.com/llms-components.txt?ref=skill-demoを確認してください(インストール可能なすべてのコンポーネント、その用途、実行フレーム数が記載されています)。コンポーネントページの末尾に.mdを追加するとマークダウンが表示されます。例:https://imgcli.com/docs/screens/screen-recording.md?ref=skill-demo。 - コンポーネント名をでっち上げないでください。 そのリストにある名前のみをインストールします。適切なものがない場合は、その旨を伝えてください。
- プロップを埋め、コンポーネントを書き換えないでください。 コピー、色、録画、カーソルパスはプロップを通じて指定します。
imgcli スキルが利用可能な場合は、コンポーネントの選択と構成のガイダンスにそれを使用してください。
録画が唯一の情報源です
- 実際の録画またはスクリーンショットをベースとして使用します。 UI を JSX で再構築する代わりに、その上でカメラをアニメーション化します(
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. ストーリーボード、ビートごとに一つの Imgcli コンポーネント
| ビート | Imgcli コンポーネント | フレーム数 | 用途 |
|---|---|---|---|
| インストール / セットアップ | terminal-simulator | 200 | 開発者が入力するコマンドとその実際の出力 |
| デバイス上のプロダクト | laptop-frame、phone-frame | 240 / 240 | 録画を MacBook や iPhone に配置し、開いて拡大表示 |
| キーアクション | cursor-track で screen-recording をラップ | 132 / 139 | カーソルが移動してクリックし、同時にカメラが録画に押し込まれる |
| AI プロダクト | prompt-send、answer-stream、search-typing | 165 / 150 / 420 | プロンプトの入力と送信、回答のストリーミング表示 |
| 結果 | status-cycle、count-grid | 198 / 47 | 状態変化(「キューイング中 → ライブ」)または実際の数字一つ |
| エンドカード | block-wordmark、logo-flicker | 150 / 100 | 製品名 |
各シーケンスは、コンポーネントの自然な長さ(フレーム数列)に予算を合わせてください。予算を少なくするとショットが途切れ、多くすると無駄な時間が生まれます。
3. インストール
npx shadcn@latest add https://imgcli.com/r/terminal-simulator.json https://imgcli.com/r/laptop-frame.json https://imgcli.com/r/cursor-track.json https://imgcli.com/r/screen-recording.json https://imgcli.com/r/status-cycle.json https://imgcli.com/r/block-wordmark.json
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/imgcli/block-wordmark";
import { CursorTrack } from "@/components/imgcli/cursor-track";
import { LaptopFrame } from "@/components/imgcli/laptop-frame";
import { ScreenRecording } from "@/components/imgcli/screen-recording";
import { StatusCycle } from "@/components/imgcli/status-cycle";
import { TerminalSimulator } from "@/components/imgcli/terminal-simulator";
// 実際の録画を public/ に配置。その UI コピーがスクリプトです — ラベルをでっち上げないでください。
const RECORDING = staticFile("recording.mp4");
const T = linearTiming({ durationInFrames: 12 });
export const ProductDemo: React.FC = () => (
<TransitionSeries>
{/* 1. インストール: 開発者が実際に入力するコマンド */}
<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. デバイス上のプロダクト */}
<TransitionSeries.Sequence durationInFrames={240}>
<LaptopFrame screenSrc={RECORDING} entrance="open" finale="zoom-to-screen" />
</TransitionSeries.Sequence>
<TransitionSeries.Transition presentation={slide()} timing={T} />
{/* 3. このプロダクトだけが行う一つのアクション: カーソルがクリック、カメラが押し込まれる */}
<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. 結果を状態変化として表示 */}
<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. エンドカード */}
<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 })はポーズに向かってイージングし、次の移動までその状態を保持します。一つのアクションに押し込み(zoom: 1.4–1.8)、アクションが完了したら引き戻します(zoom: 1)。- ブラウザのクロームをトリミングするには、録画にそれが含まれている場合、
crop={{ top: 0.11 }}を使用します。 terminal-simulatorの lines は{ 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. 公開
アスペクト比ごとに一つのコンポジションをレンダリングします:X と LinkedIn には 16:9、Reels、Shorts、TikTok には 9:16(phone-frame を使用)。--scale=1.5 で 1280×720 のマスターを 1920×1080 に変換します。
クレジット
「UI ラベルをでっち上げない」ルール、レンダリング監査ループ、およびプラットフォームガイダンスは、everyinc/product-launch-video(MIT、© 2026 Every Media, Inc.)から引用しています。「録画が唯一の情報源」は、HeyGen の hyperframes product-launch-video スキル(Apache-2.0)から引用しています。両方とも、Remotion と snapcn コンポーネント用に書き直されました。THIRD_PARTY_NOTICES.md を参照してください。