📦 video by remotion — 自动化视频制作工作室
v1.0.1基于 Remotion + React + TTS 的自动化视频生产工作室。通过 make 驱动的流水线将 JSON 内容脚本转换为带配音和字幕的动画讲解视频:TTS 音频生成 → 渲染属性计算 → Remotion 视频渲染。适用于创建教育/讲解视频、动画演示、数据可视化视频或任何需要旁白和字幕的程序化视频。支持 Edge TTS(在线免费)和 Qwen TTS(本地 MLX)。
详细分析 ▾
运行时依赖
版本
澄清了「仅使用 make」规则:所有项目操作必须使用 `make`,除了初始脚架期间的 `init_project.py`。添加了说明,解释技能包将 Makefile 存储为 Makefile.txt 并省略 .gitignore 以符合发布规范;这些文件由 `init_project.py` 恢复。此版本无功能或代码更改;改进了文档以便更轻松入门和更清晰的项目初始化工作流程。
安装命令
点击复制技能文档
自动化视频制作:JSON 内容脚本 → TTS 音频 → 动画 Remotion 视频。
⚠️ 关键规则:仅使用 make
所有项目操作必须通过 make。切勿运行裸命令。 唯一的例外是 scripts/init_project.py,它在项目存在之前运行(因此在 Makefile 可用之前)。项目初始化后,所有操作必须使用 make。
# ✅ 正确 — 项目脚架(仅使用 make 规则的唯一例外) python scripts/init_project.py my-video --path ~/projects# ✅ 正确 — 所有后续操作使用 make make pipeline-edge
# ❌ 错误 — 会破坏环境/路径 python3 scripts/pipeline.py --tts edge npx remotion render src/index.ts MainVideo build/video.mp4
工作流程(分步)
创建视频项目时按此确切顺序操作:
步骤 1:脚架项目
将模板从 assets/project-template/ 复制到目标目录:
python scripts/init_project.py --path
或手动复制 assets/project-template/ 并运行 make install。
步骤 2:编辑配置
在运行任何流水线之前,编辑 config/project.json 自定义视频参数。需要查看的关键配置部分:
video:分辨率(1920×1080)、FPS(30)、编码器、质量tts.engine:选择"edge"(在线,免费)或"qwen"(本地 MLX)tts.speedRate:语速乘数(1.0 = 正常,1.25 = 快 25%)subtitle:样式(bottom/tiktok/center)、显示模式(sentence/full)animation:过渡类型(fade/slide/wipe/none)theme:颜色、字体、布局bgm:背景音乐(文件路径、音量、循环)speakers:将说话者名称映射到 TTS 语音 ID 以支持多说话者
完整参数文档请参阅 references/config-reference.md。
步骤 3:编写内容脚本
编辑 content/subtitles.json:
{
"title": "Video Title",
"slides": [
{
"id": "slide_01",
"title": "Opening",
"text": "Narration text — TTS converts this to speech.",
"speaker": "default",
"type": "intro",
"notes": "Opening slide"
},
{
"id": "slide_02",
"title": "Core Concept",
"text": "Main content narration.",
"speaker": "default",
"notes": "Content slide"
},
{
"id": "slide_03",
"title": "Closing",
"text": "Summary and thanks.",
"speaker": "narrator",
"type": "outro",
"notes": "Closing slide"
}
]
}
规则:
id:必须唯一,格式为slide_XX。映射到自定义场景组件。text:旁白。保持每张幻灯片 50-150 个字符以获得最佳字幕显示。speaker:映射到config.speakers中的语音(默认:使用tts.edge.voice)。type:可选。"intro"表示开场,"outro"表示结尾。常规内容省略。
内容设计指南
- 推荐幻灯片:2-5 分钟视频使用 7-12 张幻灯片
- 文本长度:每张幻灯片 50-150 个字符,以获得最佳 TTS 和字幕显示
- 结构:开场 → 核心概念(3-6 张幻灯片)→ 对比/示例 → 应用 → 总结
- 说话者多样性:为多语音旁白使用不同的
speaker值
步骤 4:(可选)创建动画场景
为特定幻灯片创建自定义动画场景。没有自定义场景的幻灯片将获得通用文本布局。
- 创建
src/components/scenes/YourScene01.tsx:
import React from "react"; import { AbsoluteFill, useCurrentFrame, useVideoConfig, spring, interpolate } from "remotion"; import type { SlideRenderData, ThemeConfig } from "../../types/types";type Props = { slide: SlideRenderData; // 完整幻灯片数据(id, title, text, durationInFrames 等) title: string; // slide.title 的快捷方式 theme: ThemeConfig; // 主题颜色、字体、尺寸 };
export const YourScene01: React.FC = ({ slide, title, theme }) => { const frame = useCurrentFrame(); const { fps } = useVideoConfig();
// 使用 slide.durationInFrames 调整动画时序 const midPoint = Math.floor(slide.durationInFrames / 2);
// 使用 ../animations/ 中的动画组件(FadeIn, SineWave, AnimatedBarChart 等)
return ( {/ 您的动画内容 /} ); };
- 从
src/components/scenes/index.ts导出 - 在
src/components/sceneMap.ts中注册:
export const SCENE_MAP: Record> = {
slide_01: YourScene01,
};
完整参考请参阅 src/components/scenes/ExampleScene.tsx。
可用动画组件请参阅 references/animation-components.md。
步骤 5:运行流水线
make pipeline-edge # Edge TTS(在线,免费,推荐)
make pipeline-qwen # Qwen TTS(本地 MLX,Apple Silicon)
输出:build/video.mp4
用于迭代开发(仅重新生成更改的幻灯片):
make rebuild-edge # 使用 Edge TTS 增量重新构建
make rebuild-fast # 重新构建时不进行音频标准化(更快)
步骤 6:预览(可选)
make dev # 打开 Remotion Studio 浏览器预览
流水线阶段
content/subtitles.json → TTS → public/audio/.mp3 + .srt → 音频标准化(可选) → build/render-props.json → build/video.mp4
- TTS:将每张幻灯片的文本转换为音频(Edge 为 MP3 + SRT 字幕,Qwen 为 WAV)
- 音频后处理:通过 ffmpeg 进行响度标准化(EBU R128)(使用
--no-normalize跳过) - 渲染属性:探测音频时长,计算帧数,生成
build/render-props.json - Remotion 渲染:合成动画 + 音频 + 字幕 → 最终视频
增量构建
TTS 引擎使用基于哈希的变更检测。当您修改幻灯片的文本时,仅会重新生成该幻灯片的音频。强制完全重新生成:
make clean-tts # 移除 TTS 清单
make pipeline-edge # 完全重新生成
项目结构
关于模板打包的说明:技能包将Makefile存储为Makefile.txt并省略.gitignore以符合发布平台的文件类型验证规则。init_project.py脚本在项目脚架期间自动将这些文件恢复到正确的名称。
project-root/
├── Makefile # 所有操作入口点(由 init_project.py 从 Makefile.txt 恢复)
├── .gitignore # Git 忽略规则(自动生成)
├── config/
│ ├── project.json.template # 配置模板(来自 project-template.json)
│ └── project.json # 本地配置(Git 忽略,编辑此文件)
├── content/
│ ├── subtitles.json # 视频内容脚本
│ └── subtitles.json.template # 内容模板(来自 subtitles-template.json)
├── scripts/
│ ├── pipeline.py # 端到端流水线编排器
│ ├── tts_edge.py # Edge TTS 引擎(增量、多说话者、SRT)
│ ├── tts_qwen.py # Qwen TTS 引擎(本地 MLX)
│ └── tts_utils.py # 共享工具(路径解析、配置加载)
├── src/
│ ├── index.ts # Remotion 入口
│ ├── Root.tsx # 根组合注册
│ ├── lib/config.ts # Remotion 配置加载器
│ ├── compositions/
│ │ └── MainVideo.tsx # 主视频编排器(+ BGM 支持)
│ ├── components/
│ │ ├── SlideScene.tsx # 场景调度器(自定义 → 回退)
│ │ ├── SubtitleOverlay.tsx # 字幕渲染器(sentence/full 模式)
│ │ ├── sceneMap.ts # 幻灯片 ID → 场景组件注册表
│ │ ├── animations/ # 可重用动画组件(13 个组件)
│ │ └── scenes/ # 主题特定动画场景
│ │ └── ExampleScene.tsx # 参考场景模板
│ └── types/types.ts # TypeScript 类型定义
├── public/
│ ├── audio/ # TTS 输出(生成:.mp3 + .srt)
│ └── bgm/ # 背景音乐文件(可选)
├── build/ # 渲染输出(生成)
├── package.json
├── requirements.txt # Python 依赖
└── tsconfig.json
Make 命令
| 命令 | 描述 |
|---|---|
make install | 安装 npm 依赖(自动 init-config) |
make install-chrome | 安装 Chrome Headless Shell(自动检测 zip 或从其他项目复制) |
make install-chrome CHROME_ZIP=path | 从特定 zip 文件安装 Chrome |
make install-chrome CHROME_FROM=path | 从另一个项目的 node_modules 复制 Chrome |
make dev | 打开 Remotion Studio 浏览器预览 |
make pipeline | 完整流水线(默认 TTS 来自配置) |
make pipeline-edge | 完整流水线 + Edge TTS(推荐) |
make pipeline-qwen | 完整流水线 + Qwen TTS(本地 MLX) |
make pipeline-content CONTENT=content/xxx.json | 使用自定义内容文件的流水线 |
make rebuild-edge | 增量重新构建(Edge TTS,仅更改的幻灯片) |
make rebuild-qwen | 增量重新构建(Qwen TTS) |
make rebuild-fast | 重新构建时不进行音频标准化(更快) |
make tts-edge | 仅生成 TTS 音频(Edge) |
make tts-qwen | 仅生成 TTS 音频(Qwen) |
make render | 仅渲染视频(需要现有音频) |
make render-props | 仅生成 render-props.json |
make deps-qwen | 安装 Qwen TTS 依赖 |
make clean | 移除生成的音频和视频 |
make clean-tts | 移除 TTS 清单(强制完全重新生成) |
make distclean | 移除所有生成文件 + node_modules |
TTS 引擎
| 引擎 | 类型 | 速度 | 特性 |
--------|------|-------|----------|
| edge | 在线 | ⚡ 快速 | 多说话者、SRT 字幕、增量构建 |
| qwen | 本地(MLX) | 🚀 Apple Silicon 上快速 | 自定义语音、离线 |
默认:edge(推荐用于大多数用例)。
网络与隐私披露
- Edge TTS (
tts_edge.py):通过edge-ttsPython 包调用 Microsoft Edge TTS 免费 API(端点:speech.platform.bing.com)。仅发送幻灯片旁白文本进行语音合成。无需 API 密钥或账户。不传输任何其他用户数据。 - Qwen TTS (
tts_qwen.py):完全离线。在 Apple Silicon 上本地运行 MLX 模型。完全无网络调用。 - 流水线 (
pipeline.py):编排 TTS +ffmpeg(本地音频处理)+npx remotion render(本地视频渲染)。除所选 TTS 引擎外无网络调用。 - 无需凭据:此技能不需要任何 API 密钥、令牌或环境密钥。
多说话者支持
在 config/project.json 中配置说话者到语音的映射:
"speakers": {
"default": "zh-CN-YunyangNeural",
"narrator": "zh-CN-YunyangNeural",
"female": "zh-CN-XiaoxiaoNeural",
"expert": "zh-CN-YunxiNeural"
}
然后在 subtitles.json 中使用:
{
"id": "slide_01",
"speaker": "narrator",
"text": "..."
},
{
"id": "slide_02",
"speaker": "female",
"text": "..."
}
背景音乐
在 config/project.json 中启用 BGM:
"bgm": {
"enabled": true,
"file": "bgm/background.mp3",
"volume": 0.15,
"loop": true
}
将音频文件放在 public/bgm/。建议音量 0.1-0.2,以免压过旁白。
Qwen 的 Python 环境
Qwen TTS 需要单独的 Python 环境。在 config/project.json 中配置:
"pythonEnv": {
"type": "conda",
"conda": {
"name": "base"
},
"venv": {
"path": ".venv"
}
}
命令行覆盖:make pipeline-qwen ENV_TYPE=conda CONDA_ENV=myenv
可用动画组件
从 src/components/animations/ 导入:
| 组件 | 描述 |
-----------|-------------|
| FadeIn | 不透明度淡入 |
| ScaleIn | 缩放进入 |
| SlideIn | 方向滑动进入 |
| TypewriterText | 逐字符文本揭示 |
| WordHighlight | 逐词高亮效果 |
| AnimatedBarChart | 动画条形图 |
| AnimatedLineChart | 动画折线图 |
| AnimatedPieChart | 动画饼图 |
| SineWave | 动画正弦波 SVG |
| CoordinateSystem | 动画坐标轴 |
| AnimatedPath | SVG 路径绘制动画 |
| StaggeredList | 交错列表项进入 |
| CountUp | 数字计数动画 |
API 详情请参阅 references/animation-components.md。
Remotion 模式
Remotion 核心 API 模式请参阅 references/remotion-rules.md。
环境要求
- Node.js ≥ 18
- Python ≥ 3.10
- make(macOS/Linux 内置)
- FFmpeg(与 @remotion/renderer 捆绑,也用于音频标准化)
- 用于 Edge TTS 的
pip install edge-tts - Qwen TTS:带有
mlx-audio soundfile numpy的单独 conda/venv
故障排除
Chrome Headless Shell 下载失败
Remotion 需要 Chrome Headless Shell(~94MB)进行渲染。如果自动下载失败(网络问题、代理等):
快速安装(推荐):
# 自动检测当前或父目录中的 zip make install-chrome# 从特定 zip 文件 make install-chrome CHROME_ZIP=/path/to/chrome-headless-shell-mac-arm64.zip
# 从另一个项目复制(避免重新下载) make install-chrome CHROME_FROM=/path/to/other-project
手动安装(如果 make install-chrome 不起作用):
步骤 1:找到所需版本:
node -e "console.log(require('@remotion/renderer/package.json').version)"
# 然后检查:
node_modules/@remotion/renderer/dist/browser/BrowserFetcher.js
# 查找 TESTED_VERSION(例如 "144.0.7559.20")
步骤 2:手动下载:
https://storage.googleapis.com/chrome-for-testing-public//mac-arm64/chrome-headless-shell-mac-arm64.zip
将 替换为步骤 1 中的版本。对于 Intel Mac,使用 mac-x64。
步骤 3:安装到正确目录:
CHROME_DIR="node_modules/.remotion/chrome-headless-shell" mkdir -p "$CHROME_DIR/mac-arm64"# 解压并移动到平台目录 unzip chrome-headless-shell-mac-arm64.zip -d "$CHROME_DIR/mac-arm64/"
# 写入 VERSION 文件(必须与 TESTED_VERSION 完全匹配) echo "144.0.7559.20" > "$CHROME_DIR/VERSION"
# 确保可执行权限 chmod +x "$CHROME_DIR/mac-arm64/chrome-headless-shell-mac-arm64/chrome-headless-shell"
预期目录结构:
node_modules/.remotion/chrome-headless-shell/
├── VERSION ← 必须包含精确版本字符串
└── mac-arm64 ← 平台目录
└── chrome-headless-shell-mac-arm64 ← 解压文件夹
└── chrome-headless-shell ← 可执行文件
流水线中途失败
如果流水线在 TTS 之后但渲染之前失败:
make render # 只需重新运行渲染步骤
如果 TTS 部分完成:
make pipeline-edge # 增量:仅重新生成缺失/更改的音频
强制完全重新生成:
make clean-tts # 移除哈希清单
make pipeline-edge # 完全重新生成
音频质量问题
如果旁白听起来太响/太轻或不一致:
- 音频标准化自动运行(EBU R128 标准)
- 使用
make rebuild-fast或--no-normalize标志跳过 - 调整配置中的
tts.speedRate(建议 1.0-1.5)
场景中的 JSX 常见陷阱
编写自定义场景组件时,注意以下 JSX 陷阱:
文本中的大括号:{ } 在 JSX 中被视为 JavaScript 表达式,而非字面文本。这在显示数学公式时特别常见。
// ❌ 错误 — JSX 将 { f(t) } 解释为表达式,导致 "f is not defined" 错误
ℒ { f(t) } → F(s)// ✅ 正确 — 包装在字符串字面量中
{"ℒ { f(t) } → F(s)"}// ✅ 也正确 — 使用变量
const formula = "ℒ { f(t) } → F(s)";
{formula}
文本中的尖括号:< 和 > 可能被误解为 JSX 标签。
// ❌ 错误
when x < 0 and y > 1// ✅ 正确
{"when x < 0 and y > 1"}
提示:如有疑问,始终将包含特殊字符({ } < >)的文本包装在 {"..."} 字符串表达式中。
视频渲染但看起来不对
- 使用
make dev打开 Remotion Studio 进行视觉调试 - 检查
build/render-props.json中的帧数是否正确 - 验证场景组件已在
sceneMap.ts中注册
示例
完整示例项目位于 assets/examples/:
- fourier-transform/:完整的傅里叶变换讲解视频,包含 9 个自定义场景
- 将场景复制到您的项目中作为参考
- 演示 SVG 动画、数据可视化、对比布局