/install auto-remotion
\r \r
云端链接\r
\r
- GitHub: https://github.com/16Miku/auto-remotion\r
- ClawHub: https://clawhub.ai/16miku/auto-remotion\r \r ---\r \r
核心理念\r
\r 这条工作流的核心不是"让 AI 替代人工",而是:\r \r
把人工判断和自动化工具各自放在最合适的位置。\r 人工判断哪些画面有价值,工具负责把价值组合成视频。\r \r 执行顺序很重要:\r
- 先锁定素材区间\r
- 再锁定段落结构\r
- 再锁定总时间线\r
- 最后才叠加字幕、配音、BGM、包装\r \r 违反这个顺序,会导致大量返工。\r \r ---\r \r
快速启动(3 分钟理解全局)\r
\r 对于 AI Agent / 自动化脚本,使用非交互式创建:\r \r
npx create-video --yes --blank --no-tailwind my-video\r
```\r
\r
**对于手动操作**:\r
```bash\r
npx create-video@latest\r
# 交互式选择 Blank 模板\r
```\r
\r
**典型对话节奏**:\r
- 用户:录屏 20 分钟 → 宣传片 60 秒\r
- 执行顺序:先看素材定结构,再动手写代码\r
\r
---\r
\r
## 阶段零:环境准备\r
\r
### 0.1 创建 Remotion 项目\r
\r
**交互式创建**(手动操作时):\r
```bash\r
npx create-video@latest\r
# 选择模板:Blank(空白模板)\r
```\r
\r
**非交互式创建**(AI Agent / 脚本时):\r
```bash\r
npx create-video --yes --blank --no-tailwind my-video\r
```\r
\r
可用模板 flags:\r
| Flag | 模板 |\r
|------|------|\r
| `--blank` | 空白画布(推荐) |\r
| `--hello-world` | Hello World 动画 |\r
| `--javascript` | 纯 JavaScript 版 |\r
| `--recorder` | 录屏工具 |\r
| `--still` | 静态图片模板 |\r
| `--overlay` | 视频叠加层 |\r
| `--audiogram` | 音频可视化 |\r
| `--prompt-to-video` | AI 文字生视频 |\r
\r
**重要 flags**:\r
- `--yes` / `-y`:跳过所有交互提示(AI Agent 必须)\r
- `--no-tailwind`:不安装 TailwindCSS\r
- `--tmp`:在临时目录创建\r
\r
### 0.2 安装依赖\r
\r
```bash\r
cd my-video\r
npm install\r
```\r
\r
### 0.3 启动开发服务器\r
\r
```bash\r
npm run dev\r
```\r
\r
同时在另一个终端启动 Claude Code:\r
\r
```bash\r
cd my-video\r
claude\r
```\r
\r
### 0.4 安装 ClawHub CLI(可选)\r
\r
如需发布技能或管理注册表认证,可安装独立 clawhub CLI:\r
\r
```bash\r
npm i -g clawhub\r
# 或\r
pnpm add -g clawhub\r
```\r
\r
### 0.5 安装 remotion-video-toolkit skill(可选)\r
\r
**本 skill(auto-remotion)与 remotion-video-toolkit 是不同的 skill:**\r
\r
- **auto-remotion**:本 skill,专注"从录屏到宣传片"的完整剪辑工作流,覆盖需求确认→素材识别→Remotion 实现→配音字幕→BGM→渲染出片\r
- **remotion-video-toolkit**:ClawHub 上的另一个 skill,29 条规则,专注 Remotion API 使用、动画特效、渲染管道等技术细节\r
\r
两者可互补使用。如果需要 remotion-video-toolkit 辅助开发:\r
\r
**方式一:使用 openclaw 原生命令(推荐)**\r
\r
```bash\r
openclaw skills install remotion-video-toolkit\r
```\r
\r
**方式二:使用 clawhub CLI**\r
\r
```bash\r
npx clawhub@latest install remotion-video-toolkit --force\r
```\r
\r
该 skill 包含 29 条规则,覆盖:\r
- 动画、时序、渲染(CLI/Node.js/Lambda/Cloud Run)\r
- 字幕、3D、图表、文字特效、转场、媒体处理\r
\r
**注意**:`npx skills add remotion-dev/skills` 是安装 **remotion-best-practices** skill 的方式,与 remotion-video-toolkit 是完全不同的 skill。\r
\r
**方式三:从本地路径安装(安装 **remotion-best-practices**)**\r
\r
```bash\r
npx skills add remotion-dev/skills\r
```\r
\r
安装时选择:\r
- Agent 类型:Claude Code 或当前使用的 Agent\r
- 安装范围:全局安装(global)\r
\r
**注意**:`npx skills add remotion-dev/skills` 安装的是 **remotion-best-practices**,与 auto-remotion 和 remotion-video-toolkit 都是完全不同的 skill。\r
\r
### 0.6 环境检查清单\r
\r
| 检查项 | 命令 | 预期结果 |\r
|--------|------|---------|\r
| Node.js | `node --version` | ≥ 18 |\r
| npm | `npm --version` | ≥ 9 |\r
| Remotion CLI | `npx remotion --version` | 显示版本号 |\r
| 开发服务器 | `npm run dev` | localhost:3000 可访问 |\r
\r
---\r
\r
## 阶段一:明确目标与约束\r
\r
在动手之前,先对齐:\r
\r
1. **输入是什么**:录屏、直播录屏、剪辑素材包,还是多段演示视频?\r
2. **输出是什么**:官网宣传片、产品介绍、销售演示,还是社媒短视频?\r
3. **时长目标**:严格 60 秒、可浮动到 70 秒,还是优先完整表达?\r
4. **核心价值**:产品能力、用户体验、结果展示,还是品牌感?\r
5. **哪些后置**:字幕、配音、BGM 放到第二阶段?\r
\r
如果约束不先说清楚,后面会在"要不要保留完整结果""能不能接受更长"这类问题上反复拉扯。\r
\r
---\r
\r
## 阶段二:建立结构化中间产物\r
\r
不要直接写代码。先建立以下文件:\r
\r
### 2.1 剪辑执行稿(`.md`)\r
\r
按 Segment 分解,每段包含:\r
- 目标 / 画面描述 / 屏幕文案 / 旁白 / Remotion 对接建议\r
- 这是讨论和审阅的基础\r
\r
### 2.2 分镜表(`storyboard.json`)\r
\r
```json\r
{\r
"compositionId": "MyPromoV1",\r
"fps": 30,\r
"durationInFrames": 1800,\r
"canvas": "1920x1080",\r
"segments": [\r
{\r
"segmentId": "SegmentIntro",\r
"segmentIndex": 0,\r
"startFrame": 0,\r
"durationFrames": 150,\r
"goal": "片头引入,30字内概括价值",\r
"text": { "eyebrow": "", "title": "", "body": "" },\r
"narration": "产品名,让 AI 完成真实任务。",\r
"clip": null,\r
"overlay": "top-bar"\r
}\r
]\r
}\r
```\r
\r
### 2.3 编辑规格(`edit-spec.json`)\r
\r
帧级时间线,包含真实素材区间和速度:\r
\r
**单视频源**:\r
```json\r
{\r
"compositionId": "MyPromoV1",\r
"fps": 30,\r
"durationInFrames": 1800,\r
"sourceVideo": { "path": "./public/source.mp4" },\r
"segments": [\r
{\r
"segmentId": "SegmentIntro",\r
"startFrame": 0,\r
"durationFrames": 150,\r
"clips": []\r
}\r
]\r
}\r
```\r
\r
**多视频源**(`clips[]` 中指定 `src`):\r
```json\r
{\r
"compositionId": "MyPromoV1",\r
"fps": 30,\r
"durationInFrames": 1800,\r
"sourceVideos": [\r
{ "id": "video-a", "path": "./public/product-demo.mp4" },\r
{ "id": "video-b", "path": "./public/user-review.mp4" }\r
],\r
"segments": [\r
{\r
"segmentId": "SegmentIntro",\r
"startFrame": 0,\r
"durationFrames": 150,\r
"clips": [\r
{ "src": "video-a", "start": 10.5, "end": 15.2, "playbackRate": 1 }\r
]\r
},\r
{\r
"segmentId": "SegmentFeature",\r
"startFrame": 150,\r
"durationFrames": 300,\r
"clips": [\r
{ "src": "video-b", "start": 0, "end": 8.5, "playbackRate": 1 }\r
]\r
}\r
]\r
}\r
```\r
\r
---\r
\r
## 阶段三:识别母视频时间点\r
\r
这一步是整个链路的核心桥梁。\r
\r
**不要跳过**。即使有 AI 视频理解能力,在 MVP 阶段人工识别仍然最快。\r
\r
推荐做法:\r
1. 用户(或你引导用户)观看原视频,给出粗粒度内容分区\r
2. 在粗粒度分区中细化为可剪辑时间点\r
3. 区分"价值展示片段"和"过程等待片段"\r
4. 用结构化表格记录所有时间点\r
\r
**关键原则**:\r
- 对话类片段要确保"输入→发送→回复出现"的因果链完整\r
- 长任务演示不要只靠整体快进,要拆成"发起/执行/结果/成果展示"多个叙事节点\r
- 真实切片时间点以**分**为单位记录(`4:16` 而不是 `4.267`)\r
\r
---\r
\r
## 阶段三补充:自动视频理解(可选)\r
\r
> 本章节借鉴 [video-use](https://github.com/browser-use/video-use) 项目。如需实现 Agent 自动化剪辑,建议启用本流程。\r
\r
### 3.1 核心思想:让 LLM 读视频,而不是看视频\r
\r
传统方式(纯人工):\r
```\r
人工看视频 10-20min → 人工标记时间点 → 人工判断价值 → 人工规划分镜\r
```\r
\r
自动化方式(基于转录):\r
```\r
视频 → 转录文本(1-2min)→ LLM 阅读转录(10s)→ 自动识别有价值片段 → 自动生成分镜\r
```\r
\r
**关键洞察**:用转录文本把视频"文本化",LLM 擅长处理文本,就能自动化原本需要人工判断的决策。\r
\r
---\r
\r
### 3.2 两段式视频理解架构\r
\r
| 层 | 方式 | 代价 |\r
|----|------|------|\r
| **音频转录层** | ElevenLabs Scribe 词级时间戳 | ~12KB/小时视频 |\r
| **视觉合成层** | 按需生成 filmstrip + waveform PNG | 仅在决策点生成 |\r
\r
LLM 从不直接处理视频帧,而是读取"文本化的视频信息"。这样把 ~45M tokens(逐帧 dump)压缩到 ~12KB + 少量 PNG。\r
\r
---\r
\r
### 3.3 转录管道\r
\r
**依赖安装**:\r
\r
```bash\r
pip install -e video-use/helpers\r
# 或独立安装\r
pip install requests librosa matplotlib pillow numpy\r
```\r
\r
**核心脚本**:\r
\r
| 脚本 | 功能 |\r
|------|------|\r
| `transcribe.py` | ElevenLabs Scribe 转录,输出词级时间戳 JSON |\r
| `pack_transcripts.py` | 把 JSON 打包成 `takes_packed.md`(phrase 级) |\r
| `timeline_view.py` | 按需生成 filmstrip + waveform PNG |\r
\r
**转录命令**:\r
\r
```bash\r
# 单文件\r
python helpers/transcribe.py \x3Cvideo_path>\r
\r
# 批量(4 并行)\r
python helpers/transcribe_batch.py \x3Cvideos_dir>\r
\r
# 打包成 takes_packed.md\r
python helpers/pack_transcripts.py --edit-dir \x3Cedit_dir>\r
```\r
\r
---\r
\r
### 3.4 takes_packed.md 格式\r
\r
这是 LLM 阅读视频内容的主要 artifact。格式示例:\r
\r
```markdown\r
# Packed transcripts\r
\r
## C0103 (duration: 43.0s, 8 phrases)\r
[002.52-005.36] S0 Ninety percent of what a web agent does is completely wasted.\r
[006.08-006.74] S0 We fixed this.\r
```\r
\r
**生成规则**:\r
- 按静音 ≥ 0.5s 或说话人切换切分 phrase\r
- 每个 phrase 带有 `[start-end]` 时间戳\r
- 包含音频事件标记:`(laughs)`、`(sighs)`、`(applause)`\r
\r
---\r
\r
### 3.5 LLM 自动分镜\r
\r
给定 `takes_packed.md`,LLM 可直接生成分镜:\r
\r
```json\r
[\r
{"source": "C0103", "start": 2.42, "end": 6.85,\r
"beat": "HOOK", "quote": "Ninety percent...", "reason": "Cleanest delivery"},\r
{"source": "C0103", "start": 14.30, "end": 28.90,\r
"beat": "SOLUTION", "quote": "We fixed this", "reason": "Only take without false start"}\r
]\r
```\r
\r
**Editor sub-agent prompt 要点**:\r
- 输入:takes_packed.md + 用户上下文 + 目标时长\r
- 输出:JSON 数组,带 source/start/end/beat/quote/reason\r
- 规则:切点必须在词边界、30-200ms pad、优先 ≥400ms 静音\r
\r
---\r
\r
### 3.6 timeline_view:按需可视化\r
\r
在 LLM 判断模糊时,生成可视化确认:\r
\r
```bash\r
python helpers/timeline_view.py \x3Cvideo> \x3Cstart> \x3Cend> -o out.png\r
```\r
\r
输出:filmstrip + waveform + word labels PNG\r
\r
**使用原则**:只在决策点使用,不是全程扫描工具。\r
\r
---\r
\r
## 阶段四:Remotion 骨架搭建\r
\r
### 4.1 项目结构约定\r
\r
```\r
remotion-app/\r
├── public/ ← 所有源素材放这里(视频、音频、图片)\r
│ ├── source.mp4 ← 源视频(单视频场景)\r
│ ├── video-a.mp4 ← 多视频场景:来源视频 A\r
│ ├── video-b.mp4 ← 多视频场景:来源视频 B\r
│ ├── voiceover.mp3 ← 配音\r
│ └── bgm.mp3 ← BGM\r
├── src/\r
│ ├── Composition.tsx ← 主 composition(含所有 Segment 组件)\r
│ └── Root.tsx ← composition 注册\r
└── package.json\r
```\r
\r
**所有源素材必须放 `public/`,用 `staticFile("文件名")` 引用。**\r
\r
### 4.2 视频切片工具函数\r
\r
**单视频源**(默认):\r
\r
```tsx\r
type ClipSpec = {\r
trimBeforeFrames: number;\r
trimAfterFrames: number;\r
playbackRate: number;\r
};\r
\r
const clip = (\r
startSeconds: number,\r
endSeconds: number,\r
playbackRate = 1\r
): ClipSpec => ({\r
trimBeforeFrames: Math.round(startSeconds * 30),\r
trimAfterFrames: Math.round(endSeconds * 30),\r
playbackRate,\r
});\r
\r
// 高倍速片段务必 muted\r
\x3CVideo\r
src={videoSrc}\r
muted // ← 超过 10x 强烈建议 muted\r
trimBefore={trimBeforeFrames}\r
trimAfter={trimAfterFrames}\r
playbackRate={playbackRate}\r
style={{ width: "100%", height: "100%", objectFit: "cover" }}\r
/>\r
```\r
\r
**多视频源**:传入视频文件标识符:\r
\r
```tsx\r
type ClipSpec = {\r
trimBeforeFrames: number;\r
trimAfterFrames: number;\r
playbackRate: number;\r
src?: string; // ← 可选:指定来源视频(默认为主视频)\r
};\r
\r
// 不同 Segment 使用不同来源视频\r
const clipA = clip(10, 15, 1); // 来自 source-a.mp4\r
const clipB = clip(5, 12, 1, "source-b.mp4"); // 来自 source-b.mp4\r
\r
\x3CVideo\r
src={staticFile(clipA.src || "source-a.mp4")}\r
muted\r
trimBefore={clipA.trimBeforeFrames}\r
trimAfter={clipA.trimAfterFrames}\r
playbackRate={clipA.playbackRate}\r
style={{ width: "100%", height: "100%", objectFit: "cover" }}\r
/>\r
```\r
\r
### 4.3 Sequence 嵌套与时长管理\r
\r
**父子 Sequence 时长是关键原则**:\r
\r
> 外层 Sequence 的 `durationInFrames` 必须足够容纳所有子片段的总时长。\r
\r
如果子片段时长总和超过父级,会发生截断(子片段被砍掉尾部)。\r
\r
```tsx\r
// 正确示例\r
\x3CSequence from={840} durationInFrames={606}> {/* ← 必须 ≥ 所有子片段之和 */}\r
\x3CSegmentModules />\r
\x3C/Sequence>\r
```\r
\r
### 4.4 TypeScript 踩坑清单\r
\r
| 错误写法 | 正确写法 |\r
|---------|---------|\r
| `\x3CAbsoluteFill pointerEvents="none">` | `\x3CAbsoluteFill style={{ pointerEvents: "none" }}>` |\r
| `\x3CVideo style={{ objectFit: "cover" }}>` | `\x3CVideo objectFit="cover">` |\r
| `playbackRate={0}` | 不支持,改为纯色背景 |\r
| `import JSON from "./data.json"` | 内联为 TypeScript 常量数组 |\r
\r
---\r
\r
## 阶段五:字幕轨接入\r
\r
### 5.1 字幕数据结构\r
\r
字幕 cue 用**左闭右开**区间 `[startFrame, endFrame)`:\r
\r
```tsx\r
type SubtitleCue = {\r
cueId: string;\r
segmentId: string;\r
startFrame: number; // 包含\r
endFrame: number; // 不包含\r
text: string;\r
};\r
\r
const activeCue = subtitleCues.find(\r
(cue) => frame >= cue.startFrame && frame \x3C cue.endFrame\r
);\r
```\r
\r
### 5.2 渲染组件\r
\r
```tsx\r
const SubtitleTrack: React.FC = () => {\r
const frame = useCurrentFrame();\r
const activeCue = subtitleCues.find(\r
(cue) => frame >= cue.startFrame && frame \x3C cue.endFrame\r
);\r
if (!activeCue) return null;\r
\r
return (\r
\x3CAbsoluteFill style={{ pointerEvents: "none" }}>\r
\x3Cdiv style={{\r
position: "absolute", left: 140, right: 140, bottom: 42,\r
display: "flex", justifyContent: "center",\r
}}>\r
\x3Cdiv style={{\r
maxWidth: 1080, padding: "16px 24px", borderRadius: 22,\r
background: "rgba(5, 8, 22, 0.72)", color: "white",\r
fontSize: 28, textAlign: "center",\r
}}>\r
{activeCue.text}\r
\x3C/div>\r
\x3C/div>\r
\x3C/AbsoluteFill>\r
);\r
};\r
```\r
\r
---\r
\r
## 阶段六:中文配音(edge-tts)\r
\r
### 6.1 流程\r
\r
```\r
voiceover-script.json(结构化旁白文本)\r
→ edge-tts 生成各段 MP3\r
→ ffmpeg 合并(每段后加静音填充对齐目标帧时长)\r
→ 放入 public/\r
→ \x3CAudio src={staticFile("voiceover.mp3")} /> 接入 Composition\r
```\r
\r
### 6.2 静音填充是关键\r
\r
**不能假设配音自然时长等于目标帧时长。**\r
\r
edge-tts 按自然语速生成,每句实际时长和目标帧时长必然有偏差(可能 ±0.5-2 秒)。直接合并会导致:\r
- 配音总时长比视频短\r
- 后半段 Segment 没有配音\r
- 字幕和配音完全错位\r
\r
**正确做法**:每段配音后测量实际时长,用 `anullsrc` 生成静音填充到目标秒数:\r
\r
```bash\r
# 生成静音\r
ffmpeg -f lavfi -i anullsrc=r=24000:cl=mono -t 2.5 -q:a 9 silence.mp3\r
# 合并\r
ffmpeg -f concat -safe 0 -i concat_list.txt -acodec libmp3lame output.mp3\r
```\r
\r
### 6.3 配音生成脚本示例\r
\r
实际项目中使用的 Python 脚本结构(`generate_voiceover_v2.py`):\r
\r
```python\r
import asyncio\r
import edge_tts\r
import subprocess\r
import json\r
import os\r
\r
FFMPEG = "A:/study/AI/LLM/browser-use-cli-test/remotion-app/node_modules/@remux/compositor-win32-x64-msvc/ffmpeg.exe"\r
\r
async def generate_segment(seg: dict, output_dir: str):\r
"""生成单段配音 + 静音填充"""\r
target_sec = seg["targetSec"]\r
output_path = os.path.join(output_dir, f"vo_{seg['id']}.mp3")\r
\r
# 1. 生成配音\r
communicate = edge_tts.Communicate(seg["text"], "zh-CN-XiaoxiaoNeural")\r
seg_path = os.path.join(output_dir, f"seg_{seg['id']}.mp3")\r
await communicate.save(seg_path)\r
\r
# 2. 测量实际时长\r
probe = subprocess.run([\r
FFMPEG, "-i", seg_path, "-hide_banner"\r
], capture_output=True, text=True)\r
# 解析输出获取时长,或使用 ffprobe 精确测量\r
actual_dur = measure_duration(seg_path) # 自定义函数\r
\r
# 3. 计算静音填充\r
silence_sec = target_sec - actual_dur\r
if silence_sec > 0.05:\r
silence_path = os.path.join(output_dir, f"silence_{seg['id']}.mp3")\r
subprocess.run([\r
FFMPEG, "-f", "lavfi",\r
"-i", f"anullsrc=r=24000:cl=mono",\r
"-t", str(silence_sec),\r
"-q:a", "9",\r
silence_path\r
])\r
# 4. 合并配音 + 静音\r
concat_file = os.path.join(output_dir, f"concat_{seg['id']}.txt")\r
with open(concat_file, "w") as f:\r
f.write(f"file '{seg_path}'\
")\r
f.write(f"file '{silence_path}'\
")\r
subprocess.run([\r
FFMPEG, "-f", "concat", "-safe", "0",\r
"-i", concat_file, "-acodec", "libmp3lame", output_path\r
])\r
else:\r
os.rename(seg_path, output_path)\r
\r
async def main():\r
with open("voiceover-script.json") as f:\r
segments = json.load(f)\r
for seg in segments:\r
await generate_segment(seg, "output_dir")\r
# 最后用 ffmpeg concat 合并所有段\r
subprocess.run([FFMPEG, "-f", "concat", "-safe", "0",\r
"-i", "final_concat.txt", "-acodec", "libmp3lame",\r
"remotion-app/public/voiceover.mp3"])\r
\r
asyncio.run(main())\r
```\r
\r
### 6.4 中文语音选项\r
\r
| Voice | 特点 | 适用场景 |\r
|-------|---|---|\r
| `zh-CN-XiaoxiaoNeural` | 专业女声,清晰流畅 | 产品介绍(本次选用) |\r
| `zh-CN-YunxiNeural` | 年轻男声,有点活泼 | 科技产品演示 |\r
| `zh-CN-YunjianNeural` | 阳刚男声 | 强技术感,专业工具 |\r
\r
### 6.5 配音与时间线匹配策略\r
\r
微调顺序:\r
1. 先调文字内容长度\r
2. 次调语速(`rate` 参数)\r
3. 最后才改 Segment 时长(因为改时长会影响所有子片段基准)\r
\r
---\r
\r
## 阶段七:BGM 接入\r
\r
### 7.1 来源\r
\r
Pixabay Music(商用免费,无需署名)\r
关键词:`"light technology"`、`"corporate tech"`\r
\r
### 7.2 动态音量接入\r
\r
```tsx\r
\x3CAudio\r
src={staticFile("bgm.mp3")}\r
volume={(frame) => {\r
const t = frame / 30;\r
if (t \x3C 3) return (t / 3) * 0.4; // 淡入\r
if (t > 63.2) return ((66.2 - t) / 3) * 0.4; // 淡出\r
return 0.2; // 配音密集段\r
}}\r
/>\r
```\r
\r
### 7.3 音量原则\r
\r
**配音清晰度优先**:BGM 必须作为背景,不能盖过人声。\r
\r
- 配音密集段:0.15-0.25\r
- 无配音段(片头/片尾):0.3-0.5\r
- 本次实践最终值:峰值 0.4,正常段 0.2\r
\r
---\r
\r
## 阶段八:渲染出片\r
\r
### 8.1 渲染命令\r
\r
```bash\r
npx remotion render MyCompositionV1 --fps=30 --frames=0-{N-1} --output="output.mp4"\r
```\r
\r
**帧范围是左闭右开 `[0, N)`**,总帧数 N 意味着最后一帧是 N-1。\r
\r
### 8.2 磁盘空间要求\r
\r
Remotion 渲染需要:\r
- webpack bundle 缓存(~400MB)\r
- Chromium headless(~100MB)\r
- 临时帧文件\r
\r
渲染前确保 **C 盘有 5-10GB 可用空间**。`%TEMP%` 中的 `remotion-webpack-bundle-*` 可提前清理。\r
\r
### 8.3 Studio 预览 ≠ 最终渲染\r
\r
- Studio 预览受浏览器解码限制,高倍速(>10x)可能卡顿\r
- 最终渲染用 ffmpeg 硬解码,流畅得多\r
- **Studio 只做节奏判断,最终质量以渲染出片为准**\r
\r
---\r
\r
## 关键设计决策框架\r
\r
### Hard Rules(生产正确性铁律)\r
\r
> 以下规则来自 [video-use](https://github.com/browser-use/video-use) 项目的生产验证。违反这些规则会导致静默失败或输出损坏,务必遵守。\r
\r
| # | 规则 | 说明 |\r
|---|------|------|\r
| 1 | **字幕 LAST** | 字幕必须在滤镜链最后应用,否则叠加层会遮住字幕 |\r
| 2 | **分段提取 → 无损 concat** | 有叠加时用 `-c copy` concat,避免双重编码 |\r
| 3 | **30ms 音频淡入淡出** | 每个分段边界加 `afade=t=in:st=0:d=0.03,afade=t=out:st={dur-0.03}:d=0.03`,否则有 pop 音 |\r
| 4 | **叠加层 PTS 偏移** | 用 `setpts=PTS-STARTPTS+T/TB` 偏移叠加层帧 0,否则动画窗口显示错误帧 |\r
| 5 | **Master SRT 用输出时间线偏移** | `output_time = word.start - segment_start + segment_offset`,否则 concat 后字幕错位 |\r
| 6 | **不在词中间切割** | 所有切边必须对齐到转录词的边界 |\r
| 7 | **切割边缘留 pad** | 工作窗口 30-200ms,Scribe 时间戳漂移 50-100ms,pad 吸收漂移 |\r
| 8 | **词级 verbatim ASR** | 不用 SRT/phrase 模式(丢失亚秒级间隙数据) |\r
| 9 | **按源缓存转录** | 不重新转录,除非源文件本身变了 |\r
| 10 | **多动画并行子代理** | 用 `Agent` 工具并行生成,总耗时 ≈ 最慢那个 |\r
| 11 | **执行前确认策略** | 在用户确认计划前不进行任何切割 |\r
| 12 | **输出到 `\x3Cvideos_dir>/edit/`** | 不在 skill 目录写任何输出 |\r
\r
### Option A vs Option B 决策\r
\r
当某个 Segment 时长问题无法通过调速解决时:\r
\r
| 选项 | 做法 | 适用条件 |\r
|-----|------|---------|\r
| Option A(压缩) | 强制缩短时长,裁剪内容 | 甲方严格卡时长 |\r
| Option B(接受更长) | 让叙事完整,接受更长总时长 | 优先内容完整 |\r
\r
**决策原则**:官网宣传片的核心目标是"把产品价值讲清楚",而非"严格卡 N 秒"。压缩到不完整,反而失去意义。\r
\r
### 冻结帧实现\r
\r
不要用 `Img src="video.mp4#t=1.0"`(依赖 HTTP 服务器)或 `playbackRate={0}`(不支持)。改用纯色背景或预渲染图片。\r
\r
---\r
\r
## 不适用场景(重要)\r
\r
本 skill **不适用**于以下场景,识别到时请明确告知用户:\r
\r
| 场景 | 原因 | 建议 |\r
|-----|------|------|\r
| **技术文档/幻灯片 → 视频** | 本 skill 需要已有录屏视频作为输入,没有源视频无法切片 | 先用 Screen Studio/OBS/Keynote 录制幻灯片演示,再走本工作流 |\r
| **AI 生成视频画面** | 本 skill 仅处理已有素材的剪辑组合,不生成新画面 | 需要 Text-to-Video / AI 视频生成工具(如 Sora、Pika) |\r
| **从零构建动画视频** | 本 skill 假设有现成素材,只是剪辑重组 | 需要纯动画/图形动画工具(如 After Effects、Canva) |\r
\r
**回归路径**:如果用户有技术文档但没有录屏 → 引导用户先录制幻灯片演示(Screen Studio/OBS)→ 再回到本工作流。\r
\r
---\r
\r
## 决策树\r
\r
用户描述任务时,按以下顺序判断:\r
\r
```\r
用户描述任务\r
│\r
├─ 有录屏/产品演示视频(.mp4)?\r
│ ├─ 是 → 走完整工作流(本 skill)\r
│ └─ 否 → 跳转到"不适用场景"处理\r
│\r
└─ 目标是官网宣传片/产品介绍?\r
├─ 是 → 本 skill 适用\r
└─ 否 → 说明本 skill 专注场景,建议其他方案\r
```\r
\r
---\r
\r
## 项目结构总览\r
\r
```\r
project/\r
├── work/ ← 工作流与资产层\r
│ └── projects/{project-id}/\r
│ ├── edit-script.md ← 剪辑执行稿\r
│ ├── storyboard.json ← 分镜表\r
│ ├── edit-spec.json ← 编辑规格(帧级时间线,支持多视频源)\r
│ ├── subtitle-track.json ← 字幕时间轴\r
│ ├── voiceover-script.json ← 配音脚本\r
│ ├── generate_voiceover.py ← 配音生成脚本\r
│ ├── process_bgm.py ← BGM 混合脚本\r
│ ├── takes_packed.md ← 自动视频理解:打包转录文本\r
│ ├── transcripts/ ← 自动视频理解:原始转录 JSON\r
│ │ └── \x3Cvideo_stem>.json\r
│ ├── timeline_view/ ← 自动视频理解:可视化确认 PNG\r
│ └── animations/ ← 动画叠加层(如有)\r
└── remotion-app/ ← Remotion 实现层\r
├── public/\r
│ ├── source.mp4 ← 源视频(单视频场景)\r
│ ├── video-a.mp4 ← 多视频场景:来源视频 A\r
│ ├── video-b.mp4 ← 多视频场景:来源视频 B\r
│ ├── voiceover.mp3 ← 配音\r
│ └── bgm.mp3 ← BGM\r
└── src/\r
├── Composition.tsx ← 主 composition\r
└── Root.tsx ← 注册\r
```\r
\r
---\r
\r
## 常见问题速查\r
\r
| 问题 | 原因 | 解决方案 |\r
|-----|------|---------|\r
| 子片段被截断 | 父级 Sequence durationInFrames 不够 | 检查并扩大父级时长 |\r
| Studio 预览高倍速片段卡顿 | 浏览器解码压力大 | 设置 `muted: true`,Studio 只判断节奏 |\r
| 配音和字幕错位 | 配音总时长 ≠ 视频时长 | 每段后加静音填充对齐 |\r
| 渲染报 ENOSPC | C 盘空间不足 | 清理 %TEMP%,确保 5-10GB 可用 |\r
| 渲染时 FreezeFrame 报错 | `#t=` 或 `playbackRate=0` 不支持 | 改用纯色背景 |\r
| 渲染报错 "frame range 0-N is not inbetween..." | 帧范围写错(应为左闭右开) | 改为 `--frames=0-{N-1}` |\r
| 某 Segment 时长不够 | 素材本身内容少 + 加速已到极限 | Option B:接受更长;或压缩其他 Segment |\r
| BGM 盖过人声 | BGM 音量过大 | 降低 BGM 音量至 0.15-0.25,配音段更低 |\r
| edge-tts 生成失败 | 网络或认证问题 | 检查 `edge-tts --list-voices` 是否正常 |\r
- Make sure OpenClaw is installed (local or Docker)
- Run the install command in chat:
/install auto-remotion - After installation, invoke the skill by name or use
/auto-remotion - Provide required inputs per the skill's parameter spec and get structured output
What is auto-remotion?
从已有录屏/产品演示视频生成官网宣传片的工作流。 当用户提到以下场景时触发: - "把录屏转成宣传片"、"用录屏做产品视频" - "把演示视频做成官网介绍" - "Remotion 切片"、"视频分镜" - "产品宣传视频生成"、"screen recording to promo video" - "多个视频合... It is an AI Agent Skill for Claude Code / OpenClaw, with 71 downloads so far.
How do I install auto-remotion?
Run "/install auto-remotion" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.
Is auto-remotion free?
Yes, auto-remotion is completely free, licensed under MIT-0. You can download, install and use it at no cost.
Which platforms does auto-remotion support?
auto-remotion is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).
Who created auto-remotion?
It is built and maintained by 16Miku (@16miku); the current version is v1.0.0.