Remotion 程序化视频制作完整指南
TL;DR
Remotion 是用 React 代码写视频的框架,通过 registerRoot() 注册入口、useCurrentFrame() 获取帧号、interpolate() 和 spring() 做动画、Sequence 控制播放顺序。适合程序化生成动态文字动画、数据可视化、参数化批量模板。
核心概念速览
| 概念 | 说明 |
|------|------|
| Composition | 视频配置(fps、duration、width、height) |
| registerRoot() | 注册根组件,必须使用 |
| useCurrentFrame() | 获取当前帧编号(0 开始) |
| useVideoConfig() | 获取 fps、duration 等配置 |
| interpolate() | 在两值之间根据帧号插值(动画核心) |
| spring() | 弹簧动画,比 interpolate 更自然 |
| AbsoluteFill | 填满整个视频区域的容器 |
| Sequence | 时间轴组件,控制子元素播放顺序和时间偏移 |
| staticFile() | 引用静态资源(图片、音频等) |
触发场景
- 需要程序化生成动态文字动画(系统弹窗风格)
- 数据可视化动画
- 参数化批量模板(一个模板 + 不同参数 = 多期系列视频)
- 需要与 ComfyUI 生成的 AIGC 视觉素材结合
行动步骤
1. 项目初始化(手动搭建,绕过交互式 CLI)
mkdir -p my-remotion/src/HelloWorld my-remotion/public
cd my-remotion
npm init -y
npm install remotion @remotion/cli react react-dom
2. 配置 package.json scripts
{
"scripts": {
"start": "remotion studio src/index.tsx",
"build": "remotion render src/index.tsx MyVideo out.mp4",
"preview": "remotion preview src/index.tsx"
}
}
3. 入口文件必须用 .tsx(不是 .ts)
import { registerRoot } from "remotion";
import React from "react";
import { Composition } from "remotion";
import { HelloWorld } from "./HelloWorld/Title";
registerRoot(() => {
return (
<>
<Composition
id="MyVideo"
component={HelloWorld}
durationInFrames={150} // 5秒 @ 30fps
fps={30}
width={1920}
height={1080}
defaultProps={{
titleText: "Hello World",
subtitleText: "Remotion First Try",
}}
/>
</>
);
});
4. 核心动画 API
// 获取当前帧
const frame = useCurrentFrame();
const { fps, durationInFrames } = useVideoConfig();
const seconds = frame / fps;
// 插值动画(0-30帧映射到 0-100)
const left = interpolate(frame, [0, 30], [0, 100]);
// 弹簧动画(更自然)
const titleY = spring({ frame, fps, config: { damping: 200, stiffness: 200, mass: 0.5 } });
// Sequence 配合
<AbsoluteFill style={{ backgroundColor: "#0a0a0a" }}>
<Sequence from={0} durationInFrames={75}>
<Title />
</Sequence>
<Sequence from={20} durationInFrames={75}>
<Subtitle />
</Sequence>
</AbsoluteFill>
5. 渲染命令
# 启动 Studio 预览
npx remotion studio src/index.tsx
# 列出所有 compositions
npx remotion compositions src/index.tsx
# 渲染静态帧(测试用)
npx remotion still src/index.tsx MyVideo out.png --frame=30
# 渲染视频
npx remotion render src/index.tsx MyVideo out.mp4
# 带参数渲染
npx remotion render src/index.tsx MyVideo out.mp4 \
--props='{"titleText":"Custom Title"}'
证据
- 150帧(5秒 @ 30fps)渲染约 20 秒完成
- 并发数:8x(自动)
- 输出大小:270.6 KB(MP4 H264)
- 已验证
spring+interpolate动画效果正常 - 已验证
Sequence+AbsoluteFill配合正常
失败边界
- 入口文件必须用
.tsx,不能用.ts(需要 JSX 支持) - 必须用
registerRoot()包裹所有<Composition />,否则报错 "does not contain registerRoot" @remotion/core独立包已废弃,用remotion包代替- 渲染出来是黑色:动画还没开始(frame=0),用
--frame=30测试中间帧 create-videoCLI 是交互式的,无法自动化,手动搭建项目结构
易混淆场景
- Sequence 的
from是相对于 Sequence 容器的偏移,不是绝对时间 transform中做数学运算时记得加反引号:<div style={{ transform: \translateY(${y}px)\}}>- 渲染性能:150帧约20秒,不是实时,需预估完整渲染时间
原理
Remotion 本质是将 React 组件树映射为视频帧序列,通过帧号驱动动画函数(interpolate/spring)实现时间维度上的连续变化。每一帧都是Pure function,无副作用,天然支持并发渲染。
关联与延伸
- 相关笔记:[[20250129-vis-04]] — 视频创作感知体系
- 工作流位置:草稿 → 白板框架 → ComfyUI → Remotion → Final Cut Pro
使用记录
| 日期 | 项目/场景 | 结果 | 备注 |
|------|----------|------|------|
| 2026-05-17 | 初始整理 | - | 从 0-Inbox 迁入 |
附件
- 项目路径:
/Users/lewis/视觉/Remotion/remotion-explore - 第一个视频输出:
out.mp4(5秒,270KB)