Requirements
- Target platform
- OpenClaw
- Install method
- Manual import
- Extraction
- Extract archive
- Prerequisites
- OpenClaw
- Primary doc
- SKILL.md
AI video production workflow using Remotion. Use when creating videos, short films, commercials, or motion graphics. Triggers on requests to make promotional...
AI video production workflow using Remotion. Use when creating videos, short films, commercials, or motion graphics. Triggers on requests to make promotional...
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete.
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run.
"Create professional motion graphics videos programmatically with React and Remotion."
Source: Superskills - Video Generator (Remotion) Author: Riley Brown / VibeCode Community
Firecrawl replaced with Scrapling for brand data extraction Uses Python scrapling library instead of Firecrawl API Added comprehensive troubleshooting for Remotion v4 API
Remotion: https://www.remotion.dev/ Scrapling: https://github.com/D4Vinci/Scrapling React: https://react.dev/
OpenClaw promotional video - successfully rendered! π
# Run the scrapling script to get brand colors, logo, tagline bash skills/remotion-video-generator/scripts/scrapling.sh "https://brand-website.com" This extracts: brandName, tagline, logoUrl, faviconUrl, primaryColors, ogImageUrl, screenshotUrl
mkdir -p public/images/brand curl -sL "https://brand.com/logo.svg" -o public/images/brand/logo.svg curl -sL "https://brand.com/og-image.png" -o public/images/brand/og-image.png curl -sL "https://image.thum.io/get/width/1200/crop/800/https://brand.com" -o screenshot.png
mkdir -p my-video/src my-video/public/images/brand my-video/public/audio
{ "name": "my-video", "scripts": { "dev": "npx remotion studio", "build": "npx remotion bundle" }, "dependencies": { "@remotion/cli": "^4.0.0", "react": "^18.2.0", "react-dom": "^18.2.0", "remotion": "^4.0.0", "lucide-react": "^0.300.0" } }
cd my-video && npm install
Create src/MyVideo.tsx with: AbsoluteFill for full-screen layout Sequence components for scene timing useCurrentFrame, useVideoConfig, interpolate, spring for animations
Create src/index.tsx - MUST use .tsx extension: import { registerRoot, Composition } from "remotion"; import { AbsoluteFill, Sequence, useCurrentFrame, useVideoConfig, interpolate, spring } from "remotion"; const MyVideo = () => { const frame = useCurrentFrame(); const { fps } = useVideoConfig(); // Animations - ALWAYS pass fps to spring() const scale = spring({ frame, fps, from: 0.8, to: 1 }); return ( <AbsoluteFill style={{ backgroundColor: "#000" }}> <Sequence from={0} durationInFrames={90}> <h1>Hello World</h1> </Sequence> </AbsoluteFill> ); }; registerRoot(() => { return ( <Composition id="MyVideo" component={MyVideo} durationInFrames={240} fps={30} width={1920} height={1080} /> ); }); β οΈ CRITICAL Remotion v4 Rules: Use .tsx extension (NOT .ts) for files with JSX MUST use registerRoot + Composition API ALWAYS pass fps to spring(): spring({ frame, fps, from: 0.8, to: 1 }) Use useVideoConfig() to get fps: const { fps } = useVideoConfig() Render with composition name: npx remotion render MyVideo out/video.mp4
cd my-video && npm run dev Server runs on http://localhost:3000
Open browser to preview Edit source files - hot-reloads automatically User reviews and requests changes
npx remotion render index out/final-video.mp4
Original Skill: https://superskills.vibecode.run/ Modified: Firecrawl replaced with Scrapling for brand data extraction Remotion: https://www.remotion.dev/
# Install Remotion globally npm install -g remotion # Install dependencies for video projects npm install lucide-react # Install Scrapling (already in workspace skills) pip install scrapling
Use this skill when: Creating promotional videos Making product demos Social media video content Animated explainers Commercials Any programmatic video content Do NOT use for: Simple slideshows (use other tools) Video editing of existing footage Live streaming
Scrape brand data (if featuring a product) using Scrapling (NOT Firecrawl) Create the project in output/<project-name>/ Build all scenes with proper motion graphics Install dependencies with npm install Fix package.json scripts to use npx remotion (not bun): "scripts": { "dev": "npx remotion studio", "build": "npx remotion bundle" } Start Remotion Studio as a background process: cd output/<project-name> && npm run dev Expose via Cloudflare tunnel so user can access: bash skills/cloudflare-tunnel/scripts/tunnel.sh start 3000 Send the user the public URL (e.g. https://xxx.trycloudflare.com) The user will preview in their browser, request changes, and you edit the source files. Remotion hot-reloads automatically.
cd output/<project-name> npx remotion render CompositionName out/video.mp4
# Scaffold project cd output && npx --yes create-video@latest my-video --template blank cd my-video && npm install # Add motion libraries npm install lucide-react # Fix scripts in package.json (replace any "bun" references with "npx remotion") # Start dev server npm run dev # Expose publicly bash skills/cloudflare-tunnel/scripts/tunnel.sh start 3000
MANDATORY: When a video mentions or features any product/company, use Scrapling to scrape the product's website for brand data, colors, screenshots, and copy BEFORE designing the video. This ensures visual accuracy and brand consistency.
# Run the brand data extraction script bash skills/remotion-video-generator/scripts/scrapling.sh "https://example.com" This returns structured brand data: brandName, tagline, headline, description, features, logoUrl, faviconUrl, primaryColors, ctaText, socialLinks, plus screenshot URL and OG image URL.
If the script isn't available, use Python directly: import json from scrapling.fetchers import StealthyFetcher from urllib.parse import urljoin import re url = 'https://brand.com' page = StealthyFetcher.fetch(url, headless=True) html = page.text def resolve(u): return urljoin(url, u) if u and not u.startswith('http') else u colors = list(set(re.findall(r'#(?:[0-9a-fA-F]{3}){1,2}', html)))[:5] data = { 'brandName': page.css('[property="og:site_name"]::text').get() or page.title(), 'tagline': page.css('[property="og:description"]::text').get(), 'headline': page.css('h1::text').get(), 'description': page.css('[property="og:description"]::text').get(), 'logoUrl': resolve(page.css('[rel="icon"]::attr(href)').get()), 'faviconUrl': resolve(page.css('[rel="icon"]::attr(href)').get()), 'primaryColors': colors, 'ctaText': page.css('a[href*="signup"]::text').get(), 'ogImageUrl': resolve(page.css('[property="og:image"]::attr(content)').get()), 'screenshotUrl': f"https://image.thum.io/get/width/1200/crop/800/{url}" } print(json.dumps(data, indent=2))
mkdir -p public/images/brand curl -s "https://example.com/favicon.ico" -o public/images/brand/favicon.ico curl -s "${OG_IMAGE_URL}" -o public/images/brand/og-image.png curl -sL "${SCREENSHOT_URL}" -o public/images/brand/screenshot.png Note: Some S3 buckets block direct access. Use thum.io screenshot service as fallback.
Use scene-based architecture with proper transitions: const SCENE_DURATIONS: Record<string, number> = { intro: 3000, // 3s hook problem: 4000, // 4s dramatic solution: 3500, // 3.5s reveal features: 5000, // 5s showcase cta: 3000, // 3s close };
import { AbsoluteFill, Sequence, useCurrentFrame, useVideoConfig, interpolate, spring, Img, staticFile, Audio } from "remotion"; export const MyVideo = () => { const frame = useCurrentFrame(); const { fps, durationInFrames } = useVideoConfig(); return ( <AbsoluteFill> {/* Background music */} <Audio src={staticFile("audio/bg-music.mp3")} volume={0.35} /> {/* Persistent background layer - OUTSIDE sequences */} <AnimatedBackground frame={frame} /> {/* Scene sequences */} <Sequence from={0} durationInFrames={90}> <IntroScene /> </Sequence> <Sequence from={90} durationInFrames={120}> <FeatureScene /> </Sequence> </AbsoluteFill> ); };
Fading to black between scenes Centered text on solid backgrounds Same transition for everything Linear/robotic animations Static screens Emoji icons β NEVER use emoji, always use Lucide React icons
Overlapping transitions (next starts BEFORE current ends) Layered compositions (background/midground/foreground) Spring physics for organic motion Varied timing (2-5s scenes, mixed rhythms) Continuous visual elements across scenes Custom transitions with clipPath, 3D transforms, morphs Lucide React for ALL icons (npm install lucide-react) β never emoji
TechniqueDescriptionMorph/ScaleElement scales up to fill screen, becomes next scene's backgroundWipeColored shape sweeps across, revealing next sceneZoom-throughCamera pushes into element, emerges into new sceneClip-path revealCircle/polygon grows from point to revealPersistent anchorOne element stays while surroundings changeDirectional flowScene 1 exits right, Scene 2 enters from rightSplit/unfoldScreen divides, panels slide apartPerspective flipScene rotates on Y-axis in 3D
// Timing values (in seconds) const timing = { micro: 0.1-0.2, // Small shifts, subtle feedback snappy: 0.2-0.4, // Element entrances, position changes standard: 0.5-0.8, // Scene transitions, major reveals dramatic: 1.0-1.5, // Hero moments, cinematic reveals }; // Spring configs const springs = { snappy: { stiffness: 400, damping: 30 }, bouncy: { stiffness: 300, damping: 15 }, smooth: { stiffness: 120, damping: 25 }, };
One display font + one body font max Massive headlines, tight tracking Mix weights for hierarchy Keep text SHORT (viewers can't pause)
Use brand colors from Scrapling scrape as the primary palette β match the product's actual look Avoid purple/indigo gradients unless the brand uses them or the user explicitly requests them Simple, clean backgrounds are generally best β a single dark tone or subtle gradient beats layered textures Intentional accent colors pulled from the brand
Use asymmetric layouts, off-center type Edge-aligned elements create visual tension Generous whitespace as design element Use depth sparingly β a subtle backdrop blur or single gradient, not stacked textures
const opacity = interpolate(frame, [0, 30], [0, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp" }); const scale = spring({ frame, fps, from: 0.8, to: 1, durationInFrames: 30, config: { damping: 12 } });
<Sequence from={0} durationInFrames={100}> <Scene1 /> </Sequence> <Sequence from={80} durationInFrames={100}> <Scene2 /> </Sequence>
Place persistent elements OUTSIDE Sequence blocks: const PersistentShape = ({ currentScene }: { currentScene: number }) => { const positions = { 0: { x: 100, y: 100, scale: 1, opacity: 0.3 }, 1: { x: 800, y: 200, scale: 2, opacity: 0.5 }, 2: { x: 400, y: 600, scale: 0.5, opacity: 1 }, }; return ( <motion.div animate={positions[currentScene]} transition={{ duration: 0.8, ease: "easeInOut" }} className="absolute w-32 h-32 rounded-full bg-gradient-to-r from-coral to-orange" /> ); };
Before delivering, verify: Mute test: Story follows visually without sound? Squint test: Hierarchy visible when squinting? Timing test: Motion feels natural, not robotic? Consistency test: Similar elements behave similarly? Slideshow test: Does NOT look like PowerPoint? Loop test: Video loops smoothly back to start?
Scrapling brand scrape β If featuring a product, scrape its site first Director's treatment β Write vibe, camera style, emotional arc Visual direction β Colors, fonts, brand feel, animation style Scene breakdown β List every scene with description, duration, text, transitions Plan assets β User assets + generated images/videos + brand scrape assets Define durations β Vary pacing (2-3s punchy, 4-5s dramatic) Build persistent layer β Animated background outside scenes Build scenes β Each with enter/exit animations, 3-5 timed moments Open with hook β High-impact first scene Develop narrative β Content-driven middle scenes Strong ending β Intentional, resolved close Start Remotion Studio β npm run dev on port 3000 Expose via tunnel β bash skills/cloudflare-tunnel/scripts/tunnel.sh start 3000 Send user the public URL β They preview and request changes live Iterate β Edit source, hot-reload, repeat Render β Only when user says to export final video
my-video/ βββ src/ β βββ Root.tsx # Composition definitions β βββ index.ts # Entry point β βββ index.css # Global styles β βββ MyVideo.tsx # Main video component β βββ scenes/ # Scene components (optional) βββ public/ β βββ images/ β β βββ brand/ # Scrapling-scraped assets β βββ audio/ # Background music βββ remotion.config.ts βββ package.json
See references/components.md for reusable: Animated backgrounds Terminal windows Feature cards Stats displays CTA buttons Text reveal animations
# Start tunnel (exposes port 3000 publicly) bash skills/cloudflare-tunnel/scripts/tunnel.sh start 3000 # Check status bash skills/cloudflare-tunnel/scripts/tunnel.sh status 3000 # List all tunnels bash skills/cloudflare-tunnel/scripts/tunnel.sh list # Stop tunnel bash skills/cloudflare-tunnel/scripts/tunnel.sh stop 3000
IssueSolutionExpected ">" but found "schema"Use .tsx extension for files with JSX, not .tsuseCurrentFrame() can only be called inside a componentUse registerRoot + Composition API (see Step 7)"fps" must be a number, but you passed undefined to spring()Pass fps to spring: spring({ frame, fps, from: 0.8, to: 1 })Could not find composition with ID indexUse composition name: npx remotion render MyVideo out.mp4Module build failedEnsure react and react-dom are in dependenciesRemotion not foundRun npm install in project directoryHot reload not workingEnsure running npm run dev, not npx remotion directlyBrand colors not extractingSome sites use CSS variables - check page source manually
Use .tsx for files with JSX (components with < tags >) Use .ts for pure TypeScript files Entry point MUST be .tsx if it uses JSX
Start dev server: npm run dev Open http://localhost:3000 Make changes - auto-refreshes Check composition in browser
Initial release (adapted from superskills) Firecrawl replaced with Scrapling for brand data extraction Uses StealthyFetcher for JS-heavy sites Full brand data extraction: brandName, tagline, headline, description, features, logoUrl, faviconUrl, primaryColors, ctaText, socialLinks, screenshotUrl, ogImageUrl
Added Quick Usage Guide with step-by-step instructions Added troubleshooting section for common issues Tested with OpenClaw promotional video - working! π Documented file extension requirements (.tsx vs .ts) Fixed Remotion v4 API: registerRoot + Composition pattern Fixed spring() must receive fps parameter Fixed composition name in render command
Here's the actual project created during testing: Location: skills/remotion-video-generator/openclaw-promo/ Brand Data Extracted: Tagline: "The AI that actually does things." Logo: favicon.svg from openclaw.ai Primary Color: #FF6B35 (extracted from design) Screenshot: Generated via thum.io Project Structure: openclaw-promo/ βββ src/ β βββ index.tsx # Entry point β βββ OpenClawPromo.tsx # Video component βββ public/ β βββ images/ β βββ brand/ β βββ logo.svg β βββ og-image.png β βββ screenshot.png βββ package.json βββ tsconfig.json Commands: cd skills/remotion-video-generator/openclaw-promo npm run dev # Start studio at localhost:3000 npm run build # Bundle for production Last updated: 2026-02-25
Agent frameworks, memory systems, reasoning layers, and model-native orchestration.
Largest current source with strong distribution and engagement signals.