Loading...
Loading...
Make an explainer video in Remotion: a narrated 30–90s video that explains a product, feature, idea or process, with a voiceover and burned-in captions. Script → voiceover → word timings → one snapcn scene per beat → captions → render. Uses snapcn's Remotion components (@snapcn/punch-lines, status-cycle, count-grid, laptop-frame, word-captions, karaoke-captions and more) for every beat instead of hand-animated slides. Triggers: explainer video, animated explainer, how it works video, product explainer, narrated video, voiceover video, "explain my product in a video", "make an explainer in Remotion".
npx skill4agent add shadcn-labs/snapcn remotion-explainer-videohttps://snapcn.dev/llms-components.txt?ref=skill-explainerhttps://snapcn.dev/docs/captions/word-captions.md?ref=skill-explainernpx skills add snapcndev/snapcn --skill snapcn| Beat | What it says | snapcn scene | Frames |
|---|---|---|---|
| Hook | The problem, in the viewer's words | | 144 / 94 |
| How it works | 2–3 steps or states | | 198 / 180 / 108 |
| Show it | The product doing it | | 240 / 240 / 139 |
| Proof | One real number | | 47 |
| Close | The name | | 66 / 150 |
public/voiceover.mp3{ text, startMs, endMs }[]@remotion/captions@remotion/install-whisper-cppword-captionscaptionspresetaspect="9:16"karaoke-captionsnpx shadcn@latest add @snapcn/punch-lines @snapcn/status-cycle @snapcn/count-grid @snapcn/wordmark-cut @snapcn/word-captionspublic/voiceover.mp3import { AbsoluteFill, Audio, Series, staticFile } from "remotion";
import { CountGrid } from "@/components/snap-cn/count-grid";
import { PunchLines } from "@/components/snap-cn/punch-lines";
import { StatusCycle } from "@/components/snap-cn/status-cycle";
import { WordCaptions } from "@/components/snap-cn/word-captions";
import { WordmarkCut } from "@/components/snap-cn/wordmark-cut";
// Word-level timings from Whisper (or @remotion/captions): { text, startMs, endMs }[].
const captions = [
{ text: "Closing", startMs: 0, endMs: 400 },
{ text: "the", startMs: 400, endMs: 550 },
{ text: "books", startMs: 550, endMs: 1000 },
{ text: "takes", startMs: 1000, endMs: 1350 },
{ text: "a", startMs: 1350, endMs: 1450 },
{ text: "week.", startMs: 1450, endMs: 2100 },
];
// Real product screenshots in public/. Scenes fall back to snapcn sample images without them.
const shots = ["shot-1.jpg", "shot-2.jpg", "shot-3.jpg", "shot-4.jpg"].map((f) => staticFile(f));
// ~15s explainer: problem → how it works → result → name, narrated, captions burned in.
export const Explainer: React.FC = () => (
<AbsoluteFill>
<Series>
<Series.Sequence durationInFrames={144}>
<PunchLines script="Closing the books / takes a week. | Acme / does it overnight." />
</Series.Sequence>
<Series.Sequence durationInFrames={198}>
<StatusCycle
prefix="Every invoice gets"
statuses={["imported", "matched", "reconciled"]}
chips={["Stripe", "QuickBooks", "Xero"]}
/>
</Series.Sequence>
<Series.Sequence durationInFrames={60}>
<CountGrid from="5" to="500" noun="teams" cards={shots} />
</Series.Sequence>
<Series.Sequence durationInFrames={66}>
<WordmarkCut word="acme." />
</Series.Sequence>
</Series>
<WordCaptions captions={captions} />
<Audio src={staticFile("voiceover.mp3")} />
</AbsoluteFill>
);durationInFrames={468}fps={30}width={1280}height={720}npx remotion still Explainer out/beat.png --frame=250
npx remotion render Explainer out/explainer.mp4 --codec=h264 --crf=18maxWordsorbit-flowproof-linehex-tallymetric-morphread-throughclaude mcp add snapcn -- npx -y @snapcn/mcp@latest SNAPCN_API_KEY=YOUR_KEYcomponents.jsonTHIRD_PARTY_NOTICES.md