Remotion 教程 101 - 用 React 写视频?Remotion 全面入门

6 阅读7分钟

🎯 学习目标

学完这篇,你将能够:

  • 理解 Remotion 的核心概念
  • 搭建 Remotion 开发环境
  • 创建第一个视频项目
  • 理解"代码即视频"的思想

📖 什么是 Remotion?

Remotion = 用 React 写视频

我的理解

Remotion 不是一个视频编辑工具,而是一个视频生成框架

它让你用写 React 组件的方式写视频,然后用 Node.js 渲染成 MP4。

传统视频制作 vs Remotion

维度传统剪辑Remotion
工具剪映/PR代码编辑器
时间轴手动拖拽代码定义
复用困难组件复用
自动化难以实现天然支持
版本控制困难Git 友好

核心思想:视频 = 数据 + 模板 + 自动化

💡 我的实践心得

用 Remotion 做视频,最大的优势不是"能用代码写",而是:

  1. 可批量生产 - 一套模板,生成 100 个视频
  2. 可版本管理 - 每次修改都有 Git 记录
  3. 可自动化 - 结合数据自动生成视频

适合场景:

  • ✅ 教程视频(代码演示)
  • ✅ 数据报告(动态图表)
  • ✅ 产品介绍(模板化)
  • ❌ 电影剪辑(需要精细操作)
  • ❌ Vlog(需要实拍)

🚀 快速开始(3 步)

1. 环境要求

  • Node.js 16+(推荐 v20+)
  • npm / yarn / pnpm
  • 代码编辑器(VS Code)

2. 创建项目

# 使用官方脚手架
npx create-video@latest

# 选择模板(推荐 Hello World)
# 进入项目目录
cd my-video

# 启动开发服务器
npm run dev

3. 打开 Remotion Studio

浏览器访问 http://localhost:3000

你会看到:

  • 预览窗口
  • 时间轴
  • 属性面板

📁 项目结构

my-video/
├── src/
│   ├── Root.tsx          # 根组件(定义 Composition)
│   ├── Video.tsx         # 视频主组件
│   └── index.ts          # 入口文件
├── package.json
└── remotion.config.js    # Remotion 配置

Root.tsx 详解

import { Composition } from 'remotion';
import { MyVideo } from './Video';

export const RemotionRoot = () => {
  return (
    <>
      <Composition
        id="MyVideo"
        component={MyVideo}
        durationInFrames={90}  // 90  = 3 30fpsfps={30}
        width={1920}
        height={1080}
      />
    </>
  );
};

关键参数:

  • id: Composition 唯一标识
  • component: 视频组件
  • durationInFrames: 总帧数
  • fps: 帧率(30 = 每秒 30 帧)
  • width/height: 分辨率

🎬 第一个视频组件

// Video.tsx
import { useCurrentFrame } from 'remotion';

export const MyVideo = () => {
  const frame = useCurrentFrame();
  
  return (
    <div style={{
      width: '100%',
      height: '100%',
      background: '#000',
      color: '#fff',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      fontSize: '100px'
    }}>
      Hello World! Frame: {frame}
    </div>
  );
};

核心钩子:

  • useCurrentFrame(): 获取当前帧数
  • 根据帧数实现动效

🎨 基础动效

1. 透明度变化

import { useCurrentFrame, interpolate } from 'remotion';

export const FadeIn = () => {
  const frame = useCurrentFrame();
  
  // 0-30 帧:透明度从 0 到 1
  const opacity = interpolate(frame, 0, 30, 0, 1);
  
  return (
    <div style={{ opacity }}>
      渐入效果
    </div>
  );
};

2. 位移动画

export const SlideIn = () => {
  const frame = useCurrentFrame();
  
  // 0-30 帧:从上方滑入
  const translateY = frame < 30 ? -100 + (frame / 30) * 100 : 0;
  
  return (
    <div style={{
      transform: `translateY(${translateY}px)`
    }}>
      滑入效果
    </div>
  );
};

3. 缩放动画

export const ZoomIn = () => {
  const frame = useCurrentFrame();
  
  // 0-30 帧:从 0.5 倍放大到 1 倍
  const scale = frame < 30 ? 0.5 + (frame / 30) * 0.5 : 1;
  
  return (
    <div style={{
      transform: `scale(${scale})`
    }}>
      放大效果
    </div>
  );
};

⏱️ Sequence 时间轴

多个场景按时间顺序播放:

import { Sequence } from 'remotion';

export const MultiScene = () => {
  return (
    <>
      {/* 场景 1: 0-30 帧 */}
      <Sequence from={0} to={30}>
        <Scene1 />
      </Sequence>
      
      {/* 场景 2: 30-60 帧 */}
      <Sequence from={30} to={60}>
        <Scene2 />
      </Sequence>
      
      {/* 场景 3: 60-90 帧 */}
      <Sequence from={60} to={90}>
        <Scene3 />
      </Sequence>
    </>
  );
};

🔊 音频处理

import { Audio } from 'remotion';

export const VideoWithAudio = () => {
  return (
    <>
      {/* 视频内容 */}
      <div>视频画面</div>
      
      {/* 背景音乐 */}
      <Audio src="./bgm.mp3" />
      
      {/* 旁白 */}
      <Audio src="./narration.mp3" />
    </>
  );
};

音频同步:

  • 音频自动与视频同步
  • 支持多个音频轨道
  • 音量控制:volume={0.5}

📤 渲染导出

# 导出 MP4
npx remotion render MyVideo out/video.mp4

# 指定编码
npx remotion render MyVideo out/video.mp4 --codec=h264

# 导出序列帧
npx remotion render MyVideo out/frames --image-format=png

渲染参数:

  • --codec: h264(兼容性好)/ h265(文件小)
  • --quality: 0-100(默认 80)
  • --frames: 渲染指定帧范围

💡 核心思想

传统剪辑 vs Remotion

维度传统剪辑Remotion
工具剪映/PR代码编辑器
时间轴手动拖拽代码定义
复用困难组件复用
自动化难以实现天然支持
版本控制困难Git 友好

为什么用代码写视频?

  1. 可复用 - 组件化,一套模板生产无数视频
  2. 可自动化 - 结合数据自动生成
  3. 可版本控制 - Git 管理变更
  4. 可测试 - 单元测试保证质量
  5. 可协作 - 代码审查、CI/CD

🎯 实战练习

练习 1:文字渐入

// 实现文字从透明到不透明的效果
// 提示:使用 interpolate 控制 opacity

练习 2:多场景切换

// 创建 3 个场景,每个场景 30 帧
// 提示:使用 Sequence 组件

练习 3:添加背景音乐

// 为你的视频添加 BGM
// 提示:使用 Audio 组件

🔥 我的第一个 Remotion 项目

项目背景

我需要做一个 FAISS 向量检索的教程视频,传统方式需要:

  1. 写脚本(30 分钟)
  2. 录屏(20 分钟)
  3. 剪辑 + 字幕(1-2 小时)

用 Remotion 后:

  1. 写脚本(30 分钟)
  2. 写代码(40 分钟)
  3. 渲染(5 分钟)

总耗时:1 小时 15 分钟 vs 3 小时

项目结构

faiss-video/
├── src/
│   ├── Video.tsx          # 视频主组件
│   ├── scenes/
│   │   └── scenes-data.ts # 场景数据(核心)
│   └── components/
│       ├── TitleScene.tsx # 标题场景
│       ├── CodeScene.tsx  # 代码场景
│       └── Xiaomo.tsx     # IP 形象
├── audio/
│   └── narration.mp3      # 旁白音频
└── out/
    └── video.mp4          # 输出视频

核心代码

场景数据(scenes-data.ts):

export const scenes: SceneData[] = [
  {
    start: 0.0,
    end: 3.46,
    type: 'title',
    title: '检索速度提升\n948 倍!',
  },
  {
    start: 3.46,
    end: 8.5,
    type: 'pain',
    title: '传统检索有多慢?',
    subtitle: '百万级数据 = 等待 30 秒',
  },
  // ... 更多场景
];

渲染命令:

npx remotion render FaissVideo out/video.mp4 --codec=h264

成果

  • 视频时长: 35 秒
  • 文件大小: 2.3MB
  • 分辨率: 1920x1080
  • 渲染时间: 45 秒

视频已发布: 小红书/抖音/B 站


⚠️ 踩坑记录

坑 1:interpolate 参数格式

问题: 直接抄官方文档报错

// ❌ 错误写法
const opacity = interpolate(frame, [0, 30], [0, 1]);

解决: 新版 Remotion 改了参数格式

// ✅ 正确写法
const opacity = interpolate(frame, 0, 30, 0, 1);

坑 2:字体加载

问题: 渲染时报字体缺失

Font family 'Arial Black' not found

解决: 把字体文件放到 public/目录,用@font-face 显式加载

坑 3:音画不同步

问题: 音频和视频对不上

解决: 时间戳用帧计算,不用秒

// ❌ 错误
from={0} to={30}  // 秒

// ✅ 正确
from={0} to={30 * fps}  // 帧

💡 最佳实践

1. 先写场景数据,再写组件

// 1. 先定义场景数据
const scenes = [...];

// 2. 再写组件渲染
scenes.map(scene => <Scene key={...} {...scene} />);

2. 用 TypeScript

// 定义类型
interface SceneData {
  start: number;
  end: number;
  type: string;
  title?: string;
}

// 类型安全
const scenes: SceneData[] = [...];

3. 组件复用

// ❌ 重复代码
<TitleScene title="标题 1" />
<TitleScene title="标题 2" />

// ✅ 提取公共逻辑
<SceneRenderer scenes={scenes} />

4. 预览用低分辨率

# 预览版(快速)
npx remotion render Video out/preview.mp4 --width=1280 --height=720

# 正式版(高清)
npx remotion render Video out/video.mp4 --width=1920 --height=1080

📚 5 个核心概念总结

概念作用示例
Composition视频定义分辨率、帧率、时长
useCurrentFrame获取当前帧实现动效的基础
Sequence时间轴管理按时间顺序播放场景
interpolate插值动效透明度/位移/缩放
Audio音频处理BGM/旁白/音效

📝 总结

核心概念:

  • Composition = 视频定义
  • useCurrentFrame = 获取当前帧
  • Sequence = 时间轴管理
  • interpolate = 插值动效
  • Audio = 音频处理

下一步:

  • 学习 React 组件写视频(102 篇)
  • 30 分钟做出第一个完整视频(103 篇)

📋 系列预告

这是 Remotion 教程系列的第一篇,后续还有:

入门篇

  • 102 - React 组件如何变成视频
  • 103 - 30 分钟做出第一个视频

进阶篇

  • 201 - 动效系统全解析
  • 202 - 音频处理完整指南
  • 203 - 性能优化

实战篇

  • 301 - 小墨 IP 形象设计
  • 302 - 场景模板系统
  • 303 - Remotion + OpenClaw 自动化

商业化篇

  • 401 - Remotion 技能变现:5 种赚钱方式

💬 互动话题

  1. 你觉得用代码写视频怎么样?
  2. 想用 Remotion 做什么类型的视频?
  3. 有遇到什么问题?评论区交流!

🎁 福利时间

如果这篇文章对你有帮助:

  1. 点赞 👍 - 让更多人看到
  2. 收藏 ⭐ - 随时回来查阅
  3. 关注 ➕ - 不错过后续教程
  4. 评论 💬 - 留下你的想法

你的支持是我持续更新的动力! 🚀


📢 系列预告

这是 Remotion 教程系列的第一篇,后续还有 7 篇 干货:

  • 102 - React 组件如何变成视频
  • 103 - 30 分钟做出第一个视频
  • 201 - 动效系统全解析
  • 202 - 音频处理完整指南
  • 301 - 小墨 IP 形象设计
  • 302 - 场景模板系统
  • 303 - Remotion + OpenClaw 自动化
  • 401 - Remotion 技能变现:5 种赚钱方式

关注我,第一时间获取更新! 🔔


🔗 参考资料