动画 HTML 完成后,用户常想「能导出视频吗」。这份指南给出完整流程。
导出时机:
用户可能说的触发语:
默认一次给三种格式,让用户选:
| 格式 | 规格 | 适合场景 | 典型大小(30s) |
|---|---|---|---|
| MP4 25fps | 1920×1080 · H.264 · CRF 18 | 公众号嵌入、视频号、YouTube | 1-2 MB |
| MP4 60fps | 1920×1080 · minterpolate 插帧 · H.264 · CRF 18 | 高帧率展示、B站、作品集 | 1.5-3 MB |
| GIF | 960×540 · 15fps · palette 优化 | Twitter/X、README、Slack 预览 | 2-4 MB |
两个脚本在 scripts/:
render-video.js — HTML → MP4录一个 25fps 的 MP4 基础版本。依赖全局 playwright。
NODE_PATH=$(npm root -g) node /path/to/claude-design/scripts/render-video.js <html文件>
可选参数:
--duration=30 动画时长(秒)--width=1920 --height=1080 分辨率--trim=2.2 从视频开头裁掉的秒数(去掉 reload + 字体加载时间)--fontwait=1.5 字体加载等待时间(秒),字体多时调高输出:与 HTML 同目录,同名 .mp4。
add-music.sh — MP4 + BGM → MP4给无声 MP4 混入背景音乐,按场景(mood)从内置 BGM 库里选,也可自带音频。自动匹配时长、加淡入淡出。
bash add-music.sh <input.mp4> [--mood=<name>] [--music=<path>] [--out=<path>]
内置 BGM 库(在 assets/bgm-<mood>.mp3):
--mood= |
风格 | 适配场景 |
|---|---|---|
tech(默认) |
Apple Silicon / 苹果发布会,极简合成器+钢琴 | 产品发布、AI工具、Skill 宣传 |
ad |
upbeat 现代电子,有 build + drop | 社交媒体广告、产品预告、促销片 |
educational |
温暖明亮、轻吉他/电钢琴,inviting | 科普、教程介绍、课程预告 |
educational-alt |
同类备选,换一首试试 | 同上 |
tutorial |
lo-fi 环境音,几乎无存在感 | 软件演示、编程教程、长演示 |
tutorial-alt |
同类备选 | 同上 |
行为:
-c:v copy 不重编码,音频 AAC 192k--music=<path> 优先级高于 --mood,可以直接指定任意外部音频典型流水线(动画导出三件套 + 配乐):
node render-video.js animation.html # 录屏
bash convert-formats.sh animation.mp4 # 派生 60fps + GIF
bash add-music.sh animation-60fps.mp4 # 加默认 tech BGM
# 或针对不同场景:
bash add-music.sh tutorial-demo.mp4 --mood=tutorial
bash add-music.sh product-promo.mp4 --mood=ad --out=promo-final.mp4
convert-formats.sh — MP4 → 60fps MP4 + GIF从已有 MP4 生成 60fps 版本和 GIF。
bash /path/to/claude-design/scripts/convert-formats.sh <input.mp4> [gif_width] [--minterpolate]
输出(与输入同目录):
<name>-60fps.mp4 — 默认用 fps=60 帧复制(兼容性广);加 --minterpolate 启用高质量插帧<name>.gif — palette 优化的 GIF(默认 960 宽,可改)60fps 模式选择:
| 模式 | 命令 | 兼容性 | 使用场景 |
|---|---|---|---|
| 帧复制(默认) | convert-formats.sh in.mp4 |
QuickTime/Safari/Chrome/VLC 全通 | 通用交付、上传平台、社交媒体 |
| minterpolate 插帧 | convert-formats.sh in.mp4 --minterpolate |
macOS QuickTime/Safari 可能拒打 | B站等需要真插帧的展示场景,交付前必须本地测目标播放器 |
为什么默认改成帧复制?minterpolate 输出的 H.264 elementary stream 有 known compat bug——之前默认 minterpolate 时多次踩到「macOS QuickTime 打不开」的问题。详见 animation-pitfalls.md §14。
gif_width 参数:
用户说「导出视频」后:
cd <项目目录>
# 假设 $SKILL 指向本 skill 的根目录(自行按安装位置替换)
# 1. 录 25fps 基础 MP4
NODE_PATH=$(npm root -g) node "$SKILL/scripts/render-video.js" my-animation.html
# 2. 派生 60fps MP4 和 GIF
bash "$SKILL/scripts/convert-formats.sh" my-animation.mp4
# 产出清单:
# my-animation.mp4 (25fps · 1-2 MB)
# my-animation-60fps.mp4 (60fps · 1.5-3 MB)
# my-animation.gif (15fps · 2-4 MB)
trim 裁掉前面的加载时间render-video.js 已处理以上问题。
当前配置:minterpolate=fps=60:mi_mode=mci:mc_mode=aobmc:me_mode=bidir:vsbmc=1
mi_mode=mci — motion compensation interpolation(运动补偿)mc_mode=aobmc — adaptive overlapped block motion compensationme_mode=bidir — 双向运动估计vsbmc=1 — 可变 size block motion compensation对 CSS transform 动画(translate/scale/rotate)效果好。 对纯 fade 可能产生轻微 ghosting——如果用户嫌弃,退化为简单帧复制:
ffmpeg -i input.mp4 -r 60 -c:v libx264 ... output.mp4
GIF 只能 256 色。一次 pass 的 GIF 会把全动画色彩压到 256 色通用 palette,对米色底+橙色这种细腻配色会糊。
两阶段:
palettegen=stats_mode=diff —— 先扫描全片,生成针对此动画的 optimal palettepaletteuse=dither=bayer:bayer_scale=5:diff_mode=rectangle —— 用这个 palette 编码,rectangle diff 只更新变化区域,大幅减小文件对 fade 过渡用 dither=bayer 比 none 更平滑,但文件大一点。
导出前 30 秒自检:
animation-pitfalls.md)window.__recording 强制 loop=false(手写 Stage 必查;用 assets/animations.jsx 自带)fadeOut={0}(视频末帧不淡出)导出完成后给用户的标准说明格式:
**完整交付**
| 文件 | 格式 | 规格 | 大小 |
|---|---|---|---|
| foo.mp4 | MP4 | 1920×1080 · 25fps · H.264 | X MB |
| foo-60fps.mp4 | MP4 | 1920×1080 · 60fps(运动插帧)· H.264 | X MB |
| foo.gif | GIF | 960×540 · 15fps · palette 优化 | X MB |
**说明**
- 60fps 用 minterpolate 做运动估计插帧,transform 动画效果好
- GIF 用 palette 优化,30s 动画可压到 3MB 左右
要换尺寸或帧率说一声。
| 用户说 | 应对 |
|---|---|
| 「太大了」 | MP4:提高 CRF 到 23-28;GIF:降分辨率到 600 或 fps 到 10 |
| 「GIF 太糊」 | 提高 gif_width 到 1280;或者建议用 MP4 代替(微信朋友圈也支持) |
| 「要竖屏 9:16」 | 改 HTML 源的 --width=1080 --height=1920,重新录 |
| 「加水印」 | ffmpeg 加 -vf "drawtext=..." 或 overlay= 一个 PNG |
| 「要透明背景」 | MP4 不支持 alpha;用 WebM VP9 + alpha 或 APNG |
| 「要无损」 | CRF 改 0 + preset veryslow(文件会大 10 倍) |