
🎯 学什么:把视频当成代码来写——用 React 组件描述每一帧的画面,用数学函数驱动动画,一键渲染成 MP4。不需要打开 Premiere,不需要学剪辑。同一个视频模板能批量生成 1000 个不同版本,适合个性化视频营销。核心洞察:(1) Remotion 的核心理念极其简单——帧号就是时间,
useCurrentFrame()返回当前帧号(0, 1, 2...),任何属性(位置、透明度、旋转)都通过帧号来驱动变化;(2)spring()物理弹簧是 Remotion 和传统视频最大的差异点——模拟真实物理规律(阻尼、质量、刚度)创造最自然的运动,不需要手动调关键帧;(3) 性能问题在开发时看不出来但到渲染时暴露无遗——因为开发只渲染当前帧,渲染时需要计算全部 1800 帧。 💡 难易度:⭐⭐⭐⭐ | ⏱️ 预计时间:45 分钟
1. 课程概览
💡 白话小课堂:传统做视频就像用手画一幅画——一笔一笔地描。Remotion 做视频就像用"画图机器人"——你写一段代码告诉机器人"画一条线从左边移动到右边,移动过程中颜色从红变蓝",机器人就自动为你画出 60 张连续的画,串成一段 2 秒的动画。如果你会写 React(或者愿意学最基础的 React),你就能做视频。
来源:Remotion 团队 / https://github.com/remotion-dev/skills
2. Remotion 的核心范式
2.1 视频 = React 组件的连续渲染帧
传统视频制作 vs Remotion:
传统(Premiere / Final Cut):
剪辑软件 → 时间轴 → 拖拽素材 → 手动调关键帧 → 渲染
Remotion:
React 组件 → useCurrentFrame() 驱动动画 → FFmpeg 合成 MP4
帧号 = React 组件的"时间轴"
第 0 帧 = 视频开始
第 300 帧 = 第 10 秒(30fps × 10)
核心优势:
✓ 程序化控制:用代码修改视频的任何参数(位置/颜色/透明度/文字)
✓ 版本控制:视频项目可以 git diff——"这一版和上一版改了什么?"
✓ 批量生成:同一个模板生成 1000 个变体——传统工具需要手动导出 1000 次
✓ 自动化:CI/CD 中自动生成视频——代码 push 完立即渲染
✓ 数据驱动:从 API 拉数据直接渲染到视频中——"今日销售额"数字实时变化
2.2 最小可行视频
// 第一个 Remotion 项目:文字从左边飞到右边
import { useCurrentFrame, interpolate, spring, AbsoluteFill, Composition } from 'remotion';
const HelloWorld: React.FC = () => {
const frame = useCurrentFrame(); // 当前帧号 = "现在是什么时间"
// 文字从左边(-200px)飞到右边(200px)
const x = interpolate(frame, [0, 60], [-200, 200]);
return (
<AbsoluteFill style={{ justifyContent: 'center', alignItems: 'center' }}>
<div style={{ transform: `translateX(${x}px)`, fontSize: 80 }}>
Hello World
</div>
</AbsoluteFill>
);
};
export const RemotionRoot: React.FC = () => (
<Composition
id="HelloWorld"
component={HelloWorld}
durationInFrames={60} // 2 秒(30fps × 2)
fps={30}
width={1920}
height={1080}
/>
);
3. 动画引擎:物理弹簧 vs 手动缓动
3.1 spring() 的工作原理
spring() 是 Remotion 和传统视频制作最大的差异点:
传统方式:
→ 手动调关键帧 → 手动调缓动曲线 → 需要经验才能调出"自然"的感觉
→ 一个弹跳效果可能花 20 分钟调贝塞尔曲线
spring() 方式:
→ 你设置物理参数 → Remotion 自动计算每个帧的值
→ 模拟真实物理弹簧——damping(阻尼)、mass(质量)、stiffness(刚度)
spring() 的三个物理参数:
damping(阻尼):
→ 控制弹簧的弹性衰减速度
→ damping 越小 → 弹簧越"弹"(回弹次数多、衰减慢)
→ damping 越大 → 弹簧越"软"(快速归位、少回弹)
→ 想要活泼弹跳 → 减小 damping(200 → 10)
stiffness(刚度):
→ 控制弹簧的硬度
→ stiffness 越大 → 弹簧越"硬"(回弹速度快)
→ stiffness 越小 → 弹簧越"软"(缓慢移动)
mass(质量):
→ 控制"物体多重"——影响惯性和运动感
→ mass 越大 → 启动慢、停不下来(像推卡车)
→ mass 越小 → 轻快灵敏(像弹乒乓球)
3.2 useCurrentFrame() + interpolate() + spring() 的配合
// 组合示例:心跳脉冲动画
const frame = useCurrentFrame();
// 方案 1:interpolate() 线性插值(匀速/匀加速)
const scale1 = interpolate(frame, [0, 30, 60], [1, 1.2, 1]);
// 帧 0-30:1 → 1.2(放大),帧 30-60:1.2 → 1(缩小)
// 方案 2:spring() 物理弹簧(自然弹跳)
const scale2 = spring({
frame,
config: { damping: 10, stiffness: 100 }, // 低阻尼 = 多次回弹
});
// 从 0 弹跳到 1,物理规律驱动,不需要手动指定中间值
// interpolate 适合:线性移动、精确同步
// spring 适合:弹跳、弹出、自然运动
4. 性能优化:开发时看不出的陷阱
4.1 为什么性能在开发时被隐藏
开发模式下:
→ 只渲染你当前看到的那一帧(实时预览)
→ 你对性能的感受是"这一帧挺快的"
→ 看不到全局性能
最终渲染时:
→ 需要计算每一帧
→ 60 秒视频 × 30fps = 1800 帧
→ 每一帧多花 0.5 秒 = 多花 15 分钟
→ 开发时完全感知不到的问题突然暴露
4.2 最常见的性能杀手
杀手 1:在渲染函数里创建大数组
❌ function MyComponent() {
const items = new Array(1000).fill(0); // 每一帧都创建 1000 个数组
// 1800 帧 × 1000 = 180 万个不必要的数组
}
✅ const items = useMemo(() => new Array(1000).fill(0), []); // 只创建一次
杀手 2:使用原生 <img> 而非 <Img>
❌ <img src="image.jpg" /> // 每帧可能重新加载
✅ <Img src="image.jpg" /> // 预加载和缓存,每帧不重新请求
杀手 3:使用原生 <Video> 而非 <OffthreadVideo>
❌ <Video src="video.mp4" /> // 解码在主线程,阻塞渲染
✅ <OffthreadVideo src="video.mp4" /> // 解码在独立线程
优化杀手锏:
→ 渲染时使用 --concurrency=4 并行渲染多帧
→ 4 个线程同时渲染 → 理论上快 4 倍
5. Remotion 的适用边界
Remotion 最适合的 4 类项目:
1. 产品演示视频
→ 屏幕录制 + 文字标注 + 缩放高亮
→ 参数化:不同产品换不同截图和数据
2. 数据可视化视频
→ API 数据 → 图表动画 → 视频
→ "每日销售额"自动生成的报告视频
3. 文字动画视频
→ 标题逐字出现、打字机效果、动态排版
→ 适合:社交媒体短视频(竖屏 9:16)
4. 模板批量生成 ⭐ 最独特优势
→ 同一视频模板 × 不同数据 = 1000 个个性化视频
→ 如:"XX 先生/女士专属生日祝福"
→ 传统工具需要手动导出 1000 次
Remotion 不适合:
✗ 2 小时婚礼纪录片
→ 需要大量手动选择、情感判断和创造性叙事
→ 这些是 Premiere/Final Cut 的强项
✗ 实时视频编辑
→ Remotion 是渲染引擎,不是实时编辑器
✗ 需要大量视频素材拼接的项目
→ Remotion 的优势在"程序化生成"不是"拼接已有素材"
6. 结构拆解:编程式视频 Skill 模板
编程式视频生成型 Skill 模板
核心特征
→ 管理对象 = React 驱动的程序化视频生成 → 核心原则 = 帧号即时间 + spring 物理弹簧 + 性能优化前置 → 关键设计 = Composition 定义 + 动画函数三件套 + 批量渲染
通用结构
Core Paradigm(核心范式)
- 视频 = React 组件的连续渲染帧
- useCurrentFrame() = "时间变量"(返回当前帧号)
- 配置:durationInFrames / fps / width / height
Animation Engine(动画引擎)
- interpolate():线性插值——从帧 A 到帧 B 的值映射
- spring():物理弹簧——阻尼/刚度/质量驱动自然运动
- Easing:缓动函数——easeIn / easeOut / easeInOut
Performance(性能优化)
- 开发 vs 渲染:开发只看当前帧,渲染需计算全部帧
- useMemo:避免每帧创建大数组/对象
/ :替代原生标签
- --concurrency=4:并行渲染
Batch Generation(批量生成)
- 同一个模板 × 不同 props = 多个视频
- 脚本循环:for each data → npx remotion render ... --props='...'
- 最大独特优势:传统工具无法实现的规模
7. 电商案例:抖音信息流商品展示视频批量生成
某抖音电商品牌(主营设计师款保温杯,单 SKU 均价 ¥129,SKU 总数 80+)的产品上新节奏为每周 3-5 款。每款新品需要一个 15 秒竖版展示短视频用于抖音信息流投放——展示产品外观 + 核心卖点 + 价格 + CTA。传统方式外包给视频剪辑师 ¥200/条,3 天出片。80 个 SKU 全做 = ¥16,000,且每周上新的 3-5 款排队等剪辑排期。
用 Remotion 建立参数化视频模板,运营更新 JSON 配置即可自动生成。
模板设计(15 秒竖屏 1080×1920,30fps = 450 帧,3 段 Sequence):
interface BottleProps {
productName: string; // 如「极光渐变保温杯」
images: string[]; // 3 张场景图
capacity: string; // 如「500ml」
feature1: string; // 核心卖点 1,如「12h 保温」
feature2: string; // 核心卖点 2,如「316 不锈钢」
price: number; // 售价
primaryColor: string; // 杯身渐变色用于视频背景
discount: string; // 优惠文案,如「新客减 20」
}
const BottleShowcase: React.FC<BottleProps> = ({
productName, images, capacity, feature1, feature2, price, primaryColor, discount
}) => {
const frame = useCurrentFrame();
// Sequence 1(0-90 帧 / 3s):品牌 Logo + 产品名弹入
const logoIn = spring({ frame, config: { damping: 12, stiffness: 150 } });
// Sequence 2(90-330 帧 / 8s):3 张产品场景图逐张切换 + 卖点文字
const imgIndex = Math.floor((frame - 90) / 80) % 3; // 0→1→2 循环换图
const imgProgress = spring({ frame: frame - 90 - imgIndex * 80, config: { damping: 20 } });
// Sequence 3(330-450 帧 / 4s):价格冲击 + 优惠券 CTA
const priceBounce = spring({ frame: frame - 330, config: { damping: 8, stiffness: 200 } });
return (
<AbsoluteFill style={{ background: `linear-gradient(135deg, ${primaryColor}40, ${primaryColor})` }}>
{/* Seq 1: Logo */}
<Sequence from={0} durationInFrames={90}>
<div style={{ opacity: logoIn, transform: `translateY(${(1-logoIn) * 50}px)` }}>
<Img src="/brand/bottle-logo.png" style={{ width: 200 }} />
<div style={{ fontSize: 32, marginTop: 12 }}>{productName}</div>
</div>
</Sequence>
{/* Seq 2: 产品图 + 卖点 */}
<Sequence from={90} durationInFrames={240}>
<Img src={images[imgIndex]} style={{ opacity: imgProgress, borderRadius: 24 }} />
<div style={{ position: 'absolute', bottom: 120, fontSize: 28 }}>
{capacity} · {feature1} · {feature2}
</div>
</Sequence>
{/* Seq 3: 价格 + CTA */}
<Sequence from={330}>
<div style={{ transform: `scale(${priceBounce})`, fontSize: 80, fontWeight: 800 }}>
¥{price}
</div>
<div style={{ fontSize: 32, color: '#FFD700', marginTop: 16 }}>
{discount}
</div>
<div style={{
marginTop: 32, padding: '16px 48px',
background: '#FF4400', borderRadius: 48, fontSize: 28
}}>
点击下方小黄车 👇
</div>
</Sequence>
</AbsoluteFill>
);
};
批量渲染脚本:
#!/bin/bash
# 批量生成 80 个保温杯产品视频
jq -c '.[]' bottles.json | while read -r bottle; do
name=$(echo "$bottle" | jq -r '.productName')
npx remotion render BottleShowcase \
"output/${name// /_}.mp4" \
--props="$bottle" \
--concurrency=4 \
--codec=h264 \
--crf=23 &
# 每 4 个任务并行,防止内存溢出
if (( $(jobs -r | wc -l) >= 4 )); then
wait -n
fi
done
wait
echo "80 个视频全部生成完成"
效果:
- 80 个视频生成时间:约 50 分钟(--concurrency=4 并行),传统外包 80×3天 = 排队数周
- 成本:从 ¥16,000(外包 80 条 × ¥200)→ 接近零(服务器电费 + Remotion 开源免费)
- 抖音信息流投放 CTR:个性化视频(每条带专属产品名和颜色)平均 CTR 3.2%,比通用品牌视频(全 SKU 共用一条)的 2.1% 提升 52%
- 后续每周上新 3-5 个 SKU:运营在
bottles.json加 3-5 行 → 运行脚本 → 20 分钟出片——不再依赖剪辑师排期
🔑 启示:电商短视频批量生成的最大优势不是「成本低」——是「上新速度」。外包 3 天 vs 脚本 20 分钟——新品从到仓到上线投流的时间窗口从一周压缩到当天。3 段 Sequence 的设计对应了信息流视频的「3 秒钩子(产品出现)→ 8 秒种草(卖点展示)→ 4 秒转化(价格冲击)」——每一帧都是参数化的,改 JSON 改不了视频节奏。
8. 掌握检验
Q1:Remotion 的核心范式是什么——它和 Adobe Premiere 等传统视频制作工具的本质区别?
- A) Remotion 更便宜
- B) Remotion 把视频当作 React 组件的连续渲染帧——帧号就是时间轴,用代码驱动动画而非手动拖拽关键帧
- C) Remotion 只能做 10 秒以内的短视频
- D) Remotion 不需要任何编程知识
Q2:useCurrentFrame() 和 spring() 在 Remotion 动画系统中各扮演什么角色?
- A) useCurrentFrame() 控制颜色,spring() 控制位置
- B) useCurrentFrame() 是"时间变量"——返回当前帧号驱动所有动画;spring() 是物理弹簧动画——模拟真实物理规律创造最自然的运动
- C) 两者完全等价,只是写法不同
- D) useCurrentFrame() 用于视频,spring() 用于音频
Q3:为什么 Remotion 中使用 <Img> 和 <OffthreadVideo> 而非原生 <img> 和 <Video>?
Q4:"性能问题在开发时看不出来,到最终渲染时暴露无遗"——请解释这句话的含义。
Q5:Remotion 适合哪些类型的视频项目?为什么"个性化批量生成"是 Remotion 相比传统工具最独特的优势?
Q6:以下哪种场景最不适合用 Remotion?
- A) 为 1000 个客户批量生成"XX 专属生日祝福"视频
- B) 制作一个数据驱动的"每日销售额"自动视频报告
- C) 剪辑一段 2 小时的婚礼纪录片
- D) 做一个产品功能演示视频模板
Q7:spring() 函数中的 damping(阻尼)和 stiffness(刚度)分别控制弹簧的什么行为?
Q8:50 款产品各需要一个 15 秒展示短视频,请设计一个 Remotion 批量生成方案。
9. 答案
点击查看答案
Q1:B — Remotion 的核心范式是"视频 = React 组件的连续渲染帧"。帧号就是时间轴——第 0 帧 = 视频开始,第 300 帧 = 第 10 秒(30fps)。
Q2:B — useCurrentFrame() 返回当前帧号,是所有动画的"时间变量"。spring() 是模拟真实物理弹簧的函数——设置阻尼/质量/刚度,自动计算出最自然的运动轨迹。
Q3:参考答案 — <Img> 预加载和缓存图片,保证每帧不重新请求,避免渲染速度瓶颈。<OffthreadVideo> 将视频解码放在独立线程中,不阻塞主渲染线程。原生标签会造成渲染卡顿。
Q4:参考答案 — 开发时只渲染当前看到的那一帧,感受不到整体性能。最终渲染时需要计算每一帧——60 秒 × 30fps = 1800 帧。每一帧多花 0.5 秒 = 多 15 分钟。
Q5:参考答案 — 适合类型:产品演示、数据可视化视频、文字动画、模板批量生成。批量生成是最独特优势:同一视频模板改一行代码生成 1000 个变体,传统工具需要手动导出 1000 次。
Q6:C — 剪辑 2 小时婚礼纪录片需要大量手动选择、情感判断和创造性叙事——这是 Premiere/Final Cut 的强项。Remotion 擅长参数化、可批量、数据驱动的视频类型。
Q7:参考答案 — damping(阻尼):控制弹簧弹性衰减速度——越小越"弹"(回弹多)。stiffness(刚度):控制弹簧硬度——越大越"硬"(回弹快)。想要活泼弹跳:减小 damping。
Q8:参考答案 — (1) 模板:3 段 Sequence(Logo 弹入 → 产品图渐入 → 价格脉冲+CTA);(2) 参数化:productName/images/price/tagline/primaryColor;(3) 批量渲染:脚本循环调用 npx remotion render ... --props='...' --concurrency=4。
(6/8 通过)
10. 延伸阅读
- [[L5-21-远程浏览器操控|上一课:远程浏览器操控]]
- [[L5-23-高级创意脑暴|下一课:高级创意脑暴术]]

评论区
共 0 条评论