remotion-video
npx skills add https://github.com/z1w2r3/remotion-video-skill --skill remotion-video
Agent 安装分布
Skill 文档
Remotion è§é¢çææè½
éç¨åºæ¯
- 产åå®£ä¼ çï¼é»è®¤ 16:9 æ¨ªå± 1920×1080ï¼
- ç«å±çè§é¢ï¼æé³/è§é¢å· 1080×1920ï¼éç¨æ·æç¡®æå®ï¼
- ç¥è¯ç§æ®å¨ç»
- åçå±ç¤ºç
- ä»»ä½éè¦ React 代ç 驱å¨çç¨åºåè§é¢
ç»é¢è§æ ¼
| è§æ ¼ | å辨ç | éç¨åºæ¯ |
|---|---|---|
| 横å±ï¼é»è®¤ï¼ | 1920Ã1080 | å®ç½å®£ä¼ ãBç«ãYouTubeãä¼è®®å±ç¤º |
| ç«å± | 1080Ã1920 | æé³ãè§é¢å·ãInstagram Reels |
é»è®¤ä½¿ç¨æ¨ªå±ãä» å½ç¨æ·æç¡®è¦æ±ç«å±æ¶æåæ¢ã
åç½®æ¡ä»¶
æ¬æè½åºäº Remotion 宿¹èææ¶ + 宿¹ Skillsï¼remotion-best-practicesï¼ã
宿¹ Skills æä¾ API å±é¢çæä½³å®è·µï¼å¨ç»ãé³é¢ã转åºç 30 个è§åæä»¶ï¼ï¼æ¬æè½æä¾ç«¯å°ç«¯å·¥ä½æµï¼å
容è§å â é
é³ â åºæ¯å¼å â 导åºï¼ã两è
äºè¡¥ä½¿ç¨ã
工使µæ¦è§
é¶æ®µ1: 项ç®åå§å â é¶æ®µ2: å
容è§å â é¶æ®µ3: é
é³çæ
â é¶æ®µ4: åºæ¯å¼å â é¶æ®µ5: æ¶é´è½´éæ â é¶æ®µ6: é¢è§ä¸å¯¼åº
é¶æ®µ 1: 项ç®åå§å
æ£æ¥æ¸ å
- 使ç¨
npx create-video@latestå建项ç®ï¼é Blank + TailwindCSS + Skillsï¼ - å®è£ é¢å¤ä¾èµï¼lucide-react çï¼
- å建 src/scenes/ å public/audio/ ç®å½
- éªè¯ Studio å¯å¨
æä½æ¥éª¤
- 使ç¨å®æ¹ CLI å建项ç®ï¼ç¨æ·å¨ç»ç«¯æ§è¡ï¼é交äºéæ©ï¼:
npx create-video@latest <project-name>
ææç¤ºéæ©:
- æ¨¡æ¿ â Blank
- TailwindCSS â Yes
- Skills â Yesï¼èªå¨å®è£
remotion-best-practices宿¹æè½ï¼
- å®è£ é¢å¤ä¾èµ:
cd <project-name>
npm install lucide-react
- å建ç®å½:
mkdir -p src/scenes public/audio
- éªè¯:
npm run devè½å¯å¨ Remotion Studio 䏿 æ¥éã
宿¹èææ¶çæçå ³é®æä»¶
| æä»¶ | 说æ |
|---|---|
remotion.config.ts |
Webpack é
ç½® + @remotion/tailwind-v4 |
src/Root.tsx |
Composition 注åï¼å¯¼åºå RemotionRootï¼ |
src/index.ts |
registerRoot å
¥å£ |
src/index.css |
Tailwind CSS v4 æ ·å¼ |
package.json |
å« @remotion/mediaãtailwindcss 4.x |
.agents/skills/ |
宿¹ remotion-best-practices æè½ |
å ³é® API å·®å¼ï¼ä¸æ§ç对æ¯ï¼
- Audio: ä»
@remotion/mediaå¯¼å ¥ï¼ä¸æ¯remotionï¼ - Tailwind: v4 +
@remotion/tailwind-v4ï¼ä¸æ¯ v3 +@remotion/tailwindï¼ - Sequence: æ¨èå
premountFor={30}é¢å è½½ - Root 导åºå:
RemotionRootï¼ä¸æ¯Rootï¼
é¶æ®µ 2: å 容è§å
æ£æ¥æ¸ å
- ä¸ç¨æ·ç¡®è®¤è§é¢ä¸»é¢åç®æ åä¼
- ç¡®å®åºæ¯æ°éåæ¯ä¸ªåºæ¯çæ ¸å¿ä¿¡æ¯
- 为æ¯ä¸ªåºæ¯ç¼åé 鳿æ¬
- å建 voiceover.json æä»¶
æä½æ¥éª¤
-
ä¸ç¨æ·è®¨è®ºï¼ç¡®è®¤ä»¥ä¸ä¿¡æ¯:
- è§é¢ä¸»é¢åæ ¸å¿åç¹
- ç®æ å¹³å°ï¼æé³/è§é¢å·/éç¨ï¼
- åºæ¯æ°éï¼æ¨è 3-5 ä¸ªï¼æ¯ä¸ª 8-12 ç§ï¼
- é é³è¯è¨å飿 ¼
-
å建 voiceover.json:
[
{
"id": "scene1",
"text": "第ä¸ä¸ªåºæ¯çé
鳿æ¬",
"voice": "zh-CN-YunxiNeural",
"rate": "+5%"
},
{
"id": "scene2",
"text": "第äºä¸ªåºæ¯çé
鳿æ¬",
"voice": "zh-CN-YunxiNeural",
"rate": "+5%"
}
]
常ç¨ä¸æè¯é³
| Voice ID | ç¹ç¹ | éç¨åºæ¯ |
|---|---|---|
zh-CN-YunxiNeural |
ç·å£°ï¼ä¸ä¸æ | ç§æäº§åãåå¡ |
zh-CN-XiaoxiaoNeural |
女声ï¼äº²åå | çæ´»ç±»ãæè² |
zh-CN-YunjianNeural |
ç·å£°ï¼æµå | 纪å½çãåºé |
é¶æ®µ 3: é é³çæ
æ£æ¥æ¸ å
- 确认 edge-tts å·²å®è£
ï¼
pip3 install edge-ttsï¼ - 确认 ffprobe å¯ç¨ï¼
ffprobe -versionï¼ - 为æ¯ä¸ªåºæ¯çæ mp3 é³é¢
- è·åæ¯æ®µé³é¢çæ¶é¿å¹¶è®¡ç®å¸§æ°
- è®°å½ SCENES é ç½®æ°æ®
æä½æ¥éª¤
æ¹å¼ä¸ï¼ä½¿ç¨èæ¬ï¼æ¨èï¼
bash scripts/generate-voiceover.sh
æ¹å¼äºï¼æå¨é个çæ
对 voiceover.json ä¸çæ¯ä¸ªæ¡ç®æ§è¡:
# çæé³é¢
edge-tts --voice zh-CN-YunxiNeural --rate="+5%" \
--text "é
鳿æ¬" \
--write-media public/audio/scene1.mp3
# è·åæ¶é¿
ffprobe -i public/audio/scene1.mp3 \
-show_entries format=duration -v quiet -of csv="p=0"
# 计ç®å¸§æ°: ceil(æ¶é¿ç§æ° * 30) + 10ï¼ä½éï¼
帧æ°è®¡ç®å ¬å¼
å¸§æ° = Math.ceil(é³é¢ç§æ° * 30) + 10
é¢å¤ 10 帧ä½ä¸ºåºæ¯åæ¢çç¼å²ä½éã
é¶æ®µ 4: åºæ¯å¼å
æ£æ¥æ¸ å
- 为æ¯ä¸ªåºæ¯å建 src/scenes/SceneXXX.tsx æä»¶
- æ¯ä¸ªåºæ¯å å«ï¼æ·¡å ¥æ·¡åºå ç»ãèæ¯å±ãå 容å¨ç»
- æ·¡åºå¸§èå´ä¸åºæ¯ duration 对é½
- å¨ Studio ä¸é个é¢è§åºæ¯
åºæ¯ç»ä»¶æ å骨æ¶
import {
AbsoluteFill, useCurrentFrame, useVideoConfig,
spring, interpolate,
} from "remotion";
const DURATION = 340; // â å¿
é¡»ä¸ SCENES ä¸ç duration ä¸è´
export const SceneX: React.FC = () => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
// æ·¡å
¥ï¼å 15 帧ï¼
const sceneIn = interpolate(frame, [0, 15], [0, 1], {
extrapolateRight: "clamp",
});
// æ·¡åºï¼æå 20 帧ï¼â 帧æ°å¿
é¡»å¹é
DURATION
const sceneOut = interpolate(frame, [DURATION - 20, DURATION], [1, 0], {
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});
return (
<AbsoluteFill style={{ opacity: sceneIn * sceneOut }}>
{/* èæ¯å± */}
<AbsoluteFill
style={{
background: "radial-gradient(ellipse at center, #252525 0%, #1A1A1A 100%)",
}}
/>
{/* èæ¯ç½æ ¼ï¼å¯éï¼ */}
<div
className="absolute inset-0"
style={{
backgroundImage: `
linear-gradient(rgba(255,107,0,0.03) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,107,0,0.03) 1px, transparent 1px)
`,
backgroundSize: "40px 40px",
}}
/>
{/* æ é¢ */}
<div className="absolute top-24 left-1/2 -translate-x-1/2 text-center">
<h1 className="text-4xl font-bold text-white">主æ é¢</h1>
<p className="text-2xl mt-2" style={{ color: "#FF6B00" }}>坿 é¢</p>
</div>
{/* å
容åºå â 卿¤æ·»å åºæ¯ç¹æçå¨ç»åå
ç´ */}
{/* åºé¨è£
饰线ï¼å¯éï¼ */}
<div
className="absolute bottom-0 left-0 right-0 h-1"
style={{
background: "linear-gradient(90deg, transparent, #FF6B00, transparent)",
opacity: 0.5,
}}
/>
</AbsoluteFill>
);
};
Remotion API åèï¼æ¥èªå®æ¹ remotion-best-practicesï¼
åºæ¯å¼åæ¶æ¥é
references/remotion-api/ ä¸çè§åæä»¶ï¼è·åå API çæä½³å®è·µï¼
| æä»¶ | å 容 |
|---|---|
animations.md |
å¨ç»åºç¡ï¼å¿
é¡»ç¨ useCurrentFrame()ï¼ç¦æ¢ CSS å¨ç»ï¼ |
timing.md |
interpolateãspringãEasing 详解 + 常ç¨é
ç½® |
sequencing.md |
<Sequence>ã<Series>ãpremountForãåµå¥æ¶åº |
transitions.md |
<TransitionSeries> åºæ¯è½¬åºï¼fade/slide/wipe/flipï¼ |
audio.md |
<Audio> 导å
¥/è£åª/é³é/åé/循ç¯ï¼ä» @remotion/mediaï¼ |
images.md |
<Img> ç»ä»¶ï¼ç¦æ¢ç¨åç <img>ï¼ |
fonts.md |
Google Fonts + æ¬å°åä½å è½½ |
tailwind.md |
TailwindCSS éææ³¨æäºé¡¹ |
text-animations.md |
æåæºãæåé«äº®å¨ç»æ¨¡å¼ |
compositions.md |
Composition å®ä¹ãdefaultPropsãcalculateMetadata |
display-captions.md |
TikTok 飿 ¼å广¾ç¤º |
transcribe-captions.md |
è¯é³è½¬åå¹ |
charts.md |
æ°æ®å¯è§åå¾è¡¨ |
3d.md |
Three.js + React Three Fiber 3D å 容 |
lottie.md |
Lottie å¨ç»åµå ¥ |
maps.md |
Mapbox å°å¾å¨ç» |
parameters.md |
Zod schema åæ°åè§é¢ |
宿´åè¡¨è§ references/remotion-api/ ç®å½ã
å¨ç»æ¨¡å¼éæ¥
åè references/animation-patterns.md è·åå¯å¤ç¨çå¨ç»ä»£ç çæ®µï¼å
æ¬:
- æåæºææ Hook
- å¼¹æ§å ¥åºï¼springï¼
- 声波å¯è§å
- é·è¾¾æ«æ
- æµ®å¨å ç´
- 计æ°å¨ç»
- LED è·é©¬ç¯
é¶æ®µ 5: æ¶é´è½´éæ
æ£æ¥æ¸ å
- å¨ Main.tsx ä¸å¯¼å ¥ææåºæ¯ç»ä»¶
- é ç½® SCENES æ°ç»ï¼idãcomponentãdurationãaudioï¼
- 确认 duration ä¹åçäº Root.tsx ç durationInFrames
- æ¯ä¸ª Audio å¨å¯¹åº Sequence å
Main.tsx 模æ¿
import { AbsoluteFill, Sequence, staticFile } from "remotion";
import { Audio } from "@remotion/media";
import { Scene1XXX } from "./scenes/Scene1XXX";
import { Scene2XXX } from "./scenes/Scene2XXX";
// ... 导å
¥ææåºæ¯
const SCENES = [
{ id: "scene1", component: Scene1XXX, duration: 340, audio: "audio/scene1.mp3" },
{ id: "scene2", component: Scene2XXX, duration: 355, audio: "audio/scene2.mp3" },
// ...
];
export const Main: React.FC = () => {
let currentFrame = 0;
return (
<AbsoluteFill style={{ background: "#0A0A0A" }}>
{SCENES.map((scene) => {
const from = currentFrame;
currentFrame += scene.duration;
const Component = scene.component;
return (
<Sequence
key={scene.id}
from={from}
durationInFrames={scene.duration}
name={scene.id}
premountFor={30}
>
<Component />
<Audio src={staticFile(scene.audio)} volume={1} />
</Sequence>
);
})}
</AbsoluteFill>
);
};
æ´æ° Root.tsx
// 注æï¼å®æ¹èææ¶å¯¼åºåæ¯ RemotionRoot
durationInFrames: /* SCENES ææ duration ä¹å */,
width: 1920, // 横å±é»è®¤
height: 1080,
fps: 30,
é¶æ®µ 6: é¢è§ä¸å¯¼åº
æ£æ¥æ¸ å
- Studio é¢è§ï¼åºæ¯åæ¢æµç ãé³ç»åæ¥
- æ£æ¥æ·¡å ¥æ·¡åºæ è·³å
- å¯¼åº MP4
å½ä»¤
# å¼åé¢è§
npm run dev
# å¯¼åº MP4
npx remotion render Main out/video.mp4
# å¯¼åº GIFï¼å¯éï¼
npx remotion render Main out/video.gif
常è§é·é±
1. æ»å¸§æ°ä¸å¹é
çç¶: è§é¢æ«å°¾é»å±æè¢«æªæã
åå : Root.tsx ç durationInFrames ä¸ SCENES ååºæ¯ duration ä¹åä¸ä¸è´ã
ä¿®å¤: ç¡®ä¿ durationInFrames = SCENES.reduce((sum, s) => sum + s.duration, 0)ã
2. æ·¡åºå¸§èå´é误
çç¶: åºæ¯ç»å°¾çªç¶æ¶å¤±èéå¹³æ»æ·¡åºã
åå : åºæ¯å
sceneOut ç interpolate 帧èå´ä¸è¯¥åºæ¯çå®é
duration ä¸å¹é
ã
ä¿®å¤: sceneOut çç»æå¸§å¿
é¡»çäºè¯¥åºæ¯å¨ SCENES ä¸ç duration å¼ã
3. lucide-react ESM è·¯å¾æ¥é
çç¶: Webpack ç¼è¯æ¥éï¼æ¾ä¸å° lucide-react 模åã
åå : 使ç¨äºæ§ç lucide-reactï¼å¦ 0.263ï¼ï¼å
¶ ESM 导åºè·¯å¾æé®é¢ã
ä¿®å¤: å®è£
ææ°ç npm install lucide-react@latestã
4. Audio æ¾å¨ Sequence å¤é¨
çç¶: é³é¢ä»è§é¢å¼å¤´å°±å¼å§ææ¾ï¼ä¸è·éåºæ¯æ¶é´ã
åå : <Audio> ç»ä»¶æ²¡æè¢«å
裹å¨å¯¹åºç <Sequence> å
ã
ä¿®å¤: æ¯æ®µ Audio å¿
é¡»å¨å
¶æå±åºæ¯ç Sequence å
ã
5. Audio å¯¼å ¥è·¯å¾é误
çç¶: Audio is not exported from 'remotion'ã
åå : Remotion 4.x æ°é¡¹ç®ä¸ Audio å·²è¿ç§»å° @remotion/media å
ã
ä¿®å¤: import { Audio } from "@remotion/media";ï¼ä¸æ¯ from "remotion"ï¼ã
6. Tailwind v3 vs v4 æ··æ·
çç¶: Tailwind ç±»åä¸çæææå»ºæ¥éã
åå : npx create-video çæçæ°é¡¹ç®ä½¿ç¨ Tailwind v4 + @remotion/tailwind-v4ï¼ä¸å
¼å®¹ v3 é
ç½®ã
ä¿®å¤: ä½¿ç¨ index.css ä¸ç @import "tailwindcss" è¯æ³ï¼ä¸åéè¦ tailwind.config.jsã