AI 编程实战:用 Remotion 打造武汉旅游宣传视频

AI 编程实战:用 Remotion 打造武汉旅游宣传视频

本文记录了使用 Remotion + Claude Code 从零打造武汉旅游宣传视频的完整过程,涵盖环境搭建、原理解析、实战迭代、手把手部署导出。

一、Remotion 是什么?

Remotion 是一个基于 React 的视频创作框架,可以用写代码的方式”画”出视频。简单来说:

  • 传统视频软件:拖拽时间轴、加滤镜、导出 MP4
  • Remotion:用 React 组件 + 动画 API 生成视频,代码即视频

Remotion 的核心理念是:视频是可执行的程序。你可以用变量控制时长、用函数封装动画、用 TypeScript 确保类型安全。更重要的是,它可以与 AI 编程工具(如 Claude Code、Cursor)深度结合,用自然语言描述需求,AI 自动生成视频代码。

二、环境搭建(完整步骤)

2.1 前置要求

确保本地已安装:

1
2
node --version   # 需要 >= 18.x
npm --version # 或使用 bun/yarn/pnpm

2.2 创建 Remotion 项目

Remotion 官方提供了交互式脚手架,推荐使用 npx create-video@latest 创建空白项目:

1
npx create-video@latest

交互式向导中建议选择:

选项 推荐选择 理由
模板 Blank(空白) 最灵活,从零开始学习
CSS 方案 Tailwind CSS 现代化样式,AI 更容易生成
包管理器 npm 最通用,文档最完善
TypeScript Yes 类型安全,减少调试成本

示例交互过程:

1
2
3
4
5
6
7
8
9
10
11
12
? Choose a template of your Remotion project: (Use arrow keys)
❯ Blank
Hello World
Motion Graphics
...

? Choose how you want to configure CSS: (Use arrow keys)
❯ Tailwind CSS
Styled JSX
...

? Enter the project directory name: wuhan-tourism-video

创建完成后进入项目目录:

1
2
cd wuhan-tourism-video
npm install

2.3 目录结构一览

项目创建后的目录结构:

1
2
3
4
5
6
7
8
9
10
11
wuhan-tourism-video/
├── public/
│ └── videos/ # 视频素材目录
├── src/
│ ├── Composition.tsx # 视频主组件(核心)
│ ├── Root.tsx # 入口组件
│ ├── index.ts # 启动入口
│ └── style.css # 全局样式
├── package.json
├── remotion.config.ts # Remotion 配置
└── tsconfig.json

2.4 启动 Remotion Studio

Remotion 提供了一个浏览器中的”视频编辑器”——Remotion Studio,可以实时预览效果:

1
npm run dev

启动后访问 http://localhost:3000,即可在浏览器中看到视频预览界面,修改代码后会自动热更新。

2.5 AI 辅助开发(Claude Code 集成)

Remotion 官方支持与 Claude Code 深度集成,可以大幅提升开发效率。安装 Remotion Skills:

1
npx skills add remotion-dev/skills

然后在另一个终端窗口中启动 Claude Code:

1
2
# 在项目目录中
claude

现在你可以用自然语言描述需求,Claude Code 会帮你生成 Remotion 代码:

1
2
3
4
5
6
创建一个30秒的武汉旅游宣传视频,包含:
1. 日出开场动画
2. 长江日出实拍片段
3. 东湖樱花园
4. 结尾欢迎文字
整体风格:大气、温暖、中国红配色

三、Remotion 生成视频的原理

3.1 核心概念:帧即状态

Remotion 的工作原理可以概括为:将视频理解为随时间变化的帧序列

在 Remotion 中,每一个时刻对应一个”帧(Frame)”,视频就是一连串帧的快速切换。你通过 React Hook 获取当前帧号,然后用插值函数(interpolate)计算每一帧的视觉状态。

3.2 核心 API 解析

Remotion 提供了一系列 React Hook 来控制视频逻辑:

Hook 作用 常用场景
useCurrentFrame() 获取当前帧号 驱动所有动画
useVideoConfig() 获取视频配置(fps、时长) 计算相对时间
spring() 弹簧动画 自然的弹跳效果
interpolate() 插值计算 数值平滑过渡

3.3 动画工作原理示例

以一个淡入动画为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
import { useCurrentFrame, interpolate } from "remotion";

// 淡入动画:opacity 从 0 变到 1
const MyComponent: React.FC = () => {
const frame = useCurrentFrame(); // 当前帧号

// 第 0-30 帧内完成淡入
const opacity = interpolate(frame, [0, 30], [0, 1], {
extrapolateRight: "clamp" // 超出范围后保持 1
});

return <div style={{ opacity }}>淡入文字</div>;
};

3.4 视频渲染架构

Remotion 的整体渲染流程:

1
2
3
4
5
6
7
8
9
10
┌─────────────┐     ┌──────────────┐     ┌────────────┐
│ React 代码 │ --> │ Puppeteer │ --> │ Canvas │
│ (组件树) │ │ (浏览器引擎) │ │ (像素帧) │
└─────────────┘ └──────────────┘ └────────────┘

┌────────────────────────────┘

┌─────────────┐
│ FFmpeg │ --> MP4 / GIF / 序列帧
└─────────────┘
  1. React 组件树:定义每一帧的视觉内容
  2. 浏览器引擎:使用 Puppeteer 将 React 渲染为 Canvas 像素
  3. FFmpeg:将 Canvas 帧序列编码为最终视频文件

四、武汉旅游宣传视频实战

4.1 项目目标

制作一段 30秒 的武汉旅游宣传视频,包含以下场景:

时间段 场景 素材
0-3秒 开场动画(日出动画 + 主标题) 代码生成
3-7秒 日出江城 真实视频
7-12秒 东湖樱花园 真实视频
12-17秒 东湖风光 真实视频
17-22秒 光谷科技新城 真实视频
22-27秒 璀璨夜景 真实视频
27-30秒 结尾欢迎 代码生成

4.2 视频素材准备

视频素材存放在 public/videos/ 目录下,使用 staticFile() 函数引用:

1
2
3
4
5
6
7
8
9
10
import { staticFile } from "remotion";

// 视频素材路径定义
const VIDEO_CLIPS = {
sunrise: () => staticFile("videos/sunrise_wuhan.mp4"), // 河畔日出
cherry: () => staticFile("videos/cherry.mp4"), // 樱花
lake: () => staticFile("videos/lake.mp4"), // 湖泊
tech: () => staticFile("videos/guanggu.mp4"), // 科技新城
night: () => staticFile("videos/night.mp4"), // 烟花夜景
};

素材来源:视频来自 Mixkit 免费素材库,下载命令:

1
2
3
# PowerShell
Invoke-WebRequest -Uri 'https://assets.mixkit.co/videos/31614/31614-720.mp4' `
-OutFile 'public/videos/sunrise_wuhan.mp4'

4.3 时间轴配置

Remotion 使用帧(Frame)作为时间单位。假设帧率为 30fps,则:

  • 1秒 = 30帧
  • 30秒 = 900帧
1
2
3
4
5
6
7
8
9
10
// 时间轴配置(帧)
const TIMELINE = {
opening: { start: 0, duration: 90 }, // 0-3秒
sunrise: { start: 90, duration: 120 }, // 3-7秒
cherry: { start: 210, duration: 150 }, // 7-12秒
lake: { start: 360, duration: 150 }, // 12-17秒
tech: { start: 510, duration: 150 }, // 17-22秒
night: { start: 660, duration: 150 }, // 22-27秒
ending: { start: 810, duration: 90 }, // 27-30秒
};

4.4 视频片段组件

使用 Video 组件嵌入视频,配合 AbsoluteFill 实现全屏覆盖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import { AbsoluteFill, interpolate, useCurrentFrame, useVideoConfig, Video } from "remotion";

const VideoClip: React.FC<{
src: string;
startFrame: number;
duration: number;
emoji: string;
title: string;
subtitle: string;
}> = ({ src, startFrame, duration, emoji, title, subtitle }) => {
const frame = useCurrentFrame();
const relativeFrame = frame - startFrame;

// 淡入淡出转场效果
const fadeInFrames = 20;
const fadeOutFrames = 20;

let opacity = 1;
if (relativeFrame < fadeInFrames) {
opacity = relativeFrame / fadeInFrames;
} else if (relativeFrame > duration - fadeOutFrames) {
opacity = Math.max(0, (duration - relativeFrame) / fadeOutFrames);
}

return (
<AbsoluteFill style={{ opacity }}>
{/* 全屏视频 */}
<Video
src={src}
style={{ width: "100%", height: "100%", objectFit: "cover" }}
/>

{/* 半透明遮罩 - 增强字幕可读性 */}
<div style={{
position: "absolute",
bottom: 0,
left: 0,
right: 0,
height: "250px",
background: "linear-gradient(transparent, rgba(0, 0, 0, 0.7))",
}} />

{/* 场景标题 */}
<div style={{
position: "absolute",
top: "30%",
left: 0,
right: 0,
textAlign: "center",
}}>
<div style={{ fontSize: "80px" }}>{emoji}</div>
<div style={{
fontSize: "64px",
fontWeight: "bold",
color: "#FFD700",
letterSpacing: "10px",
textShadow: "0 0 30px rgba(255, 215, 0, 0.6)",
}}>
{title}
</div>
<div style={{ fontSize: "28px", color: "#FFFFFF", marginTop: "15px" }}>
{subtitle}
</div>
</div>
</AbsoluteFill>
);
};

4.5 迭代过程记录

在开发过程中,我根据实际效果不断调整:

版本 问题 解决方案
v1.0 视频素材不真实 替换为 Mixkit 实拍视频
v2.0 璀璨夜景使用普通夜景 替换为烟花城市夜景
v3.0 科技新城使用电路板视频 替换为赛博朋克夜景
v4.0 日出使用假日出图片 替换为河畔日出视频
v5.0 最终版本 所有素材均为真实视频

迭代经验

  1. 视频素材:优先使用真实拍摄素材,效果更震撼
  2. 字幕设计:使用半透明遮罩增强可读性
  3. 转场效果:相邻场景使用淡入淡出,避免突兀切换
  4. 武汉特色:字幕文案突出”长江”、”东湖”、”光谷”等武汉元素

五、服务运行与部署

5.1 开发模式(Remotion Studio)

开发阶段使用 npm run dev 启动 Remotion Studio:

1
2
npm run dev
# 访问 http://localhost:3000

Remotion Studio 提供了:

  • 实时预览视频效果
  • 帧级时间轴控制
  • 组件热更新(修改代码即时生效)
  • 视频参数调整面板

5.2 本地渲染预览

如果 Remotion Studio 中视频加载较慢,可以直接渲染一段测试视频:

1
npx remotion render WuhanTourismVideo out/test.mp4 --codec=h264

参数说明:

  • WuhanTourismVideo:要渲染的组件名(在 src/index.ts 中指定)
  • out/test.mp4:输出路径
  • --codec=h264:使用 H.264 编码,兼容性最好

5.3 渲染完整视频

项目完成后,渲染最终版本:

1
2
3
4
5
6
7
8
9
10
# 高质量渲染
npx remotion render WuhanTourismVideo out/wuhan-tourism-4k.mp4 \
--codec=h264 \
--quality=100 \
--scale=1

# 快速预览(低分辨率)
npx remotion render WuhanTourismVideo out/wuhan-preview.mp4 \
--codec=h264 \
--scale=0.5

5.4 渲染为 GIF

如果需要用于网页嵌入,可以导出为 GIF:

1
2
npx remotion render WuhanTourismVideo out/preview.gif \
--codec=gif

5.5 部署到服务器

Remotion 支持将视频组件部署为 Web 服务,用户可以通过 API 动态生成视频:

1
2
3
4
5
# 部署渲染服务
npx remotion serve

# 服务启动后访问 http://localhost:3000
# API 接口: GET /video?title=xxx&subtitle=xxx

六、完整项目代码结构

6.1 核心文件:Composition.tsx

武汉宣传视频的核心逻辑全部在 Composition.tsx 中:

1
2
3
4
5
6
7
8
9
src/Composition.tsx
├── VIDEO_CLIPS - 视频素材路径定义
├── COLORS - 武汉主题配色(中国红 + 金色 + 科技蓝)
├── Subtitle - 底部字幕组件
├── SceneTitle - 场景大标题组件
├── VideoClip - 视频片段组件(带淡入淡出)
├── OpeningScene - 开场动画(代码生成:太阳 + 城市剪影)
├── EndingScene - 结尾动画(代码生成:欢迎文字)
└── WuhanTourismVideo - 主组件(时间轴 + 场景切换)

6.2 关键配置:remotion.config.ts

1
2
3
4
import { Config } from "@remotion/cli/config";

Config.setVideoImageFormat("jpeg");
Config.setOverwriteOutput(true);

七、总结与展望

7.1 技术栈总结

层级 技术选型 作用
视频生成 Remotion 4.x React 驱动的视频框架
UI 样式 Tailwind CSS 快速样式开发
AI 辅助 Claude Code 自然语言生成代码
素材来源 Mixkit 免费视频素材库
视频编码 FFmpeg 最终视频渲染

7.2 Remotion 的优势

  1. 代码即视频:版本控制、代码复用、协作开发
  2. AI 友好:自然语言描述 → 可执行代码
  3. 动态参数化:同一模板生成千人千面的个性化视频
  4. Web 技术栈:前端工程师零门槛上手

7.3 应用场景

  • 营销视频:个性化广告模板,批量生成
  • 数据可视化:动态图表视频化
  • 社交媒体:自动化内容生产
  • 教育培训:课件动画生成

7.4 下一步探索

  1. AI 配音集成:配合 ElevenLabs 等 TTS 服务自动配音
  2. 用户定制:开放参数接口,让用户输入姓名生成专属视频
  3. 批量渲染:利用云函数实现大规模视频并发渲染

本文首发于 2026年4月10日,基于 Remotion 4.x 版本编写。