* Add remotion-video skill Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019yhnsd9RDz7jDSUUX7oEcH * Add Phase 2 templates to remotion-video skill Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019yhnsd9RDz7jDSUUX7oEcH * Fix captions template background; document browser flag after test render Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019yhnsd9RDz7jDSUUX7oEcH * Add audio/voiceover template (Phase 3), tested with real render Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019yhnsd9RDz7jDSUUX7oEcH * Document font loading and its network requirement; captions-over-video verified Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019yhnsd9RDz7jDSUUX7oEcH --------- Co-authored-by: Claude <noreply@anthropic.com>
4.6 KiB
4.6 KiB
name, description
| name | description |
|---|---|
| remotion-video | Create videos from React code with Remotion. Use when the user asks to make, animate, preview, or render a video, motion graphic, intro, caption, or social clip using code. |
Remotion Video
Remotion makes videos out of React components. Each frame is a web page. Render them in order and you get an MP4.
Core ideas
- Composition: one video. Has
width,height,fps,durationInFrames. - Frame:
useCurrentFrame()returns the current frame number. All animation is a function of the frame. interpolate: maps a frame range to a value range (fade, slide).spring: natural bouncy motion.Sequence: shows children only during a frame range.AbsoluteFill: full-screen layer; stack them for backgrounds.Audio/OffthreadVideo/Img: media. Put files inpublic/and load withstaticFile("name.mp3").
Workflow
- Plan first. Ask or decide: length (seconds), size (1920x1080, or 1080x1920 for vertical), fps (30), and the scenes. Keep scenes to a short list.
- Set up (skip if the project exists):
npx create-video@latest cd <project> && npm install - Write compositions in
src/, register them insrc/Root.tsx. - Preview:
npm run dev(opens Remotion Studio). - Render:
npx remotion render <CompositionId> out/video.mp4Still frame:npx remotion still <CompositionId> out/frame.png --frame=30 - Verify: render one still first, check it looks right, then render the full video.
Starter example
src/Root.tsx
import { Composition } from "remotion";
import { Hello } from "./Hello";
export const RemotionRoot = () => (
<Composition
id="Hello"
component={Hello}
durationInFrames={150}
fps={30}
width={1920}
height={1080}
defaultProps={{ title: "Hello, world" }}
/>
);
src/Hello.tsx
import { AbsoluteFill, interpolate, spring, useCurrentFrame, useVideoConfig } from "remotion";
export const Hello = ({ title }: { title: string }) => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
const opacity = interpolate(frame, [0, 30], [0, 1], { extrapolateRight: "clamp" });
const scale = spring({ frame, fps, config: { damping: 12 } });
return (
<AbsoluteFill style={{ backgroundColor: "#0b1020", justifyContent: "center", alignItems: "center" }}>
<h1 style={{ color: "white", fontSize: 120, opacity, transform: `scale(${scale})` }}>{title}</h1>
</AbsoluteFill>
);
};
Rules of thumb
- Never animate with CSS transitions,
setTimeout, or CSS animations. They don't render per frame. Drive everything fromuseCurrentFrame(). - Always pass
extrapolateRight: "clamp"tointerpolateunless you want values to keep growing. - Seconds to frames:
seconds * fps. - Use
<Sequence from={..} durationInFrames={..}>to order scenes;<Series>to chain them. - Load fonts with
@remotion/google-fontsso they are ready before rendering. - Keep props in
defaultPropsso the user can edit text in the Studio. - Rendering needs Chromium and ffmpeg (Remotion installs/handles these); first render can be slow.
Fonts
Google Fonts: npm i @remotion/google-fonts, then
import { loadFont } from "@remotion/google-fonts/Inter";
const { fontFamily } = loadFont(); // use as style={{ fontFamily }}
It downloads the font while rendering, so the machine needs internet access to fonts.googleapis.com. If the render fails with "Failed to load font", the network is blocking it: use a local font file in public/ with @remotion/fonts (loadFont({ family, url: staticFile("x.woff2") })) or a system font. (Not verified in the sandbox where this skill was tested, which had no access to Google.)
Common problems
- Can't download the browser (no internet / locked-down machine): point Remotion at an installed Chromium:
npx remotion render <Id> out/video.mp4 --browser-executable=/path/to/chromium --chrome-mode=chrome-for-testing - Blank/white frames: an asset path is wrong; use
staticFile(). - Flicker: an image or font not loaded; use
<Img>and@remotion/google-fonts. - Slow render: lower resolution/fps while testing, or use
--concurrency.
Templates
Copy-paste starting points. Read the one that fits:
templates/captions.md- words highlighted in time with speechtemplates/charts.md- animated bar charttemplates/intro-outro.md- title card + chaining scenes withSeriestemplates/audio-voiceover.md- background music, voiceover, auto video lengthtemplates/vertical.md- 1080x1920 clips for Reels/TikTok/Shorts