claude-motion-design 教程:用 HTML、Playwright 和 ffmpeg 写代码做运动设计视频(2026)
阅读说明
仓库信息查阅日期:2026-10-23;星数、更新时间会变,以仓库页面为准;本文不写价格。
一句话结论
howseen-ai/claude-motion-design 是一个 Claude Code 技能。它用 HTML 按时间算出每一帧,再用 Playwright 截图和 ffmpeg 合成运动设计视频。README 的定位是纯代码:不经过 After Effects,也不用剪辑软件。
适合已经在用 Claude Code、希望成片由 seek(t) 决定、并且接受先出静帧再渲染全片的人。仓库里的示例发布片,README 写明是用 Claude Opus 5.5 和这个技能做了 5 轮。
仓库信息
截至 2026-10-23,星数、最近推送和创建时间取自仓库元数据,日期为北京时间。
| 仓库 | 星数 | 最近推送(北京时间) | 许可 | 创建时间 |
|---|---|---|---|---|
| howseen-ai/claude-motion-design | 654 | 2026-10-04 | MIT | 2026-09-28 |
仓库描述是 “A Claude Code skill to make motion design videos in pure code: HTML + Playwright + ffmpeg. No After Effects, no Remotion license.” 公开文件树是 README.md、LICENSE、examples/、skill/。
LICENSE 为 MIT,版权人是 Howseen AI(Raphaël Aubry),年份 2026。README 写代码为 MIT。fetch_assets.py 下载的第三方媒体不随仓库分发,各自保留许可:Mixkit free license、Pexels 与 Unsplash 的许可、Geist 字体为 OFL。品牌标志归各自所有者。示例里的 Howseen 标志归 Howseen AI。README 写作者是 Raphaël Aubry。
它能做什么样的视频
每一帧由时间算出来,再逐帧渲染、做运动模糊,并卡在音乐节拍上。音效落在测到的峰值上。同一段输入得到同一批帧。
| 类型 | 仓库写明的做法 |
|---|---|
| 示例发布片 | 源码在 examples/howseen-launch。README 的运行注释写 24 秒、60 fps,子帧运动模糊,画面输出 out/video.mp4。render.py 的视口是 1080×1350 |
| 发布片、showreel、产品宣传、LinkedIn / X、meme | SKILL.md 的 description 列出这些类型。同一文件写 LinkedIn 用 4:5 的 1080×1350;X 用 16:9 或 1:1,时长不超过 2 分 20 秒 |
| 提示库里的 5 种 | README 点名 one-shot、branded、UI morph、launch reveal、LinkedIn loops |
| 逐帧翻拍 | skill/motion-design/scripts/remake/。按帧复刻一支发布片并换成自己的品牌,分屏格式是 original 与 opus 5.5 copy |
| 产品全片 | SKILL.md 第 11 节:45–75 秒。先做 lean pass:1 种语言、16:9、无旁白。完整版本只在用户要求时做 |
README 写的流水线是:inputs → beat map → 4 stills approved → full render → pop scan → audio → final。写代码之前要有品牌文件夹、带来源的 facts.md,以及导演简报(点名的参考风格、带时间的状态、图层清单、声音计划)。
引擎只使用 seek(t)。README 写明不用 CSS transition,也不用计时器。技能覆盖的做法包括闭式弹簧、在对数空间插值的镜头、共享元素交接、铺满最远角的色块、逐词遮罩文字,以及把 21st.dev 的 Animated Beam、Border Beam 改写成 seek(t)。
渲染侧 README 写明:Playwright 截图(字体就绪、暂停 Web Animations、每次 seek 之后等 2 次 requestAnimationFrame);全片之前先出一版 540p 的 draft;每一帧 N 张子帧,按 180° 快门用 tmix 混合,并且不跨硬切;BT.709、电视范围编码;pop 与单帧闪白检测;循环要同时检查位置和速度;WEBGL=1 时带上 SwiftShader 参数。
draft、180° 快门、loop 和 WEBGL=1 在 scripts/render_template.py。示例 render.py 有自己的 probe、beats、full、pops,参数见下一节。模板文件头写明:
| 命令 | 模板文件头写明的结果 |
|---|---|
probe t1 t2 … | probe/p_XX.png 和 probe/sheet.png |
beats | 每拍一帧,输出 probe/beats.png |
draft | 30 fps,每帧截 1 次,960×540,crf 23,veryfast,输出 out/draft.mp4 |
full | SHUTTER = 0.5(文件头写 180°),子帧经 tmix 合成 60 fps。文件头写的输出名是 out/crave_video.mp4 |
pops | 单帧突变扫描 |
loop | 循环接缝检查 |
WEBGL=1 | 用 SwiftShader / ANGLE 启动 Chromium。文件头写无头 WebGL 否则是黑的 |
音频:用频段能量找真正的 drop,不信任自动节拍网格;让 drop 落在关键画面上;每个音效按测到的峰值摆放;2 遍 loudnorm 到 −14 LUFS。素材来源 README 列出 Mixkit 的音乐、音效和视频,Pexels,Unsplash,svgl 的标志,simple-icons。仓库带搜索和下载脚本。
翻拍模式分 4 段,README 的原文要点是:
- Phase 0 抽出每一帧,检测切点,写成逐镜头说明。
- Phase 1 是共用的
seek(F)引擎,带一个调色滤镜。 - Phase 2 用 4 个搭建代理,各管一组镜头,并用并排对比图核对参考片。另有 1 个音频代理:README 写免版税曲目拉伸到参考片的 BPM,合成音效放在参考片的击打时间上。
SKILL.md把拉伸幅度写成不超过 8%。 - Phase 3 渲染,编码分屏和一条叠放的同步检查。简报模板在
scripts/remake/BRIEF_TEMPLATE.md。
翻拍不要复用参考片的音乐、人声和人物照片。画面上的示意数据要标成 “Example data”。字幕保持与事实一致。
BRIEF_TEMPLATE.md 把验收写成:并排同步时,版面、尺寸、位置、时间、缓动、镜头、切点、模糊、光标路径和打字节奏都要跟上参考片;只换内容。位置和尺寸误差的目标是画面的 1%–2% 以内,切点偏差 0 帧。每个代理只写 shots/<G>.js,用 CORE.rand,不用 Math.random、Date 或计时器。
SKILL.md 还引用作者本机目录 ~/Desktop/Howseen AI/howseen-video/ 以及多支成片文件夹。公开仓库的文件树里没有这些目录。仓库里能直接跑的示例是 examples/howseen-launch。
需要准备什么
README 的安装和示例用到这些:
- Claude Code。技能拷到
~/.claude/skills/,在会话里输入/motion-design,或直接要求做一支片子。 - Python 包:
playwright、imageio-ffmpeg、numpy、pillow,以及 Playwright 的 Chromium。 - 示例的最后一步调用 PATH 上的
ffmpeg。示例render.py、audio.py和技能模板则通过imageio_ffmpeg.get_ffmpeg_exe()取二进制。SKILL.md的 gotcha 写:没有 brew 安装的 ffmpeg 时,用这个函数,或使用作者本机的howseen-video/bin/ffmpeg。 - 网络。
fetch_assets.py会下载音乐、音效、标志和 Geist 字体。这些文件不在仓库里。
SKILL.md 把 21st.dev 组件检索的 key 放在 ~/.config/21st.key,原文括号是 “free tier: 2 code retrievals/day”。同一文件的音频一节写旁白用 Cartesia(Katie),并带词级时间戳。示例里的 fetch_assets.py、render.py 和 audio.py 不读取这两项。
安装与第一次运行
命令都来自 README,路径相对仓库根目录。
- 把技能拷进 Claude Code:
mkdir -p ~/.claude/skills && cp -r skill/motion-design ~/.claude/skills/
- 安装 Python 依赖并下载 Chromium。README 的原文是:
pip install playwright imageio-ffmpeg numpy pillow && python -m playwright install chromium
在 Claude Code 里要一支片子,或输入
/motion-design。模型选择见下一节。跑仓库自带的示例。README 的命令是:
cd examples/howseen-launch
python fetch_assets.py # downloads the free music, SFX, logos and font (not redistributed here)
python -m http.server 8000 & # serve the film
python render.py probe 1 8 15 20 # quick stills -> probe/sheet.png
python render.py full # 24 s, 60 fps, subframe motion blur -> out/video.mp4
python audio.py # music + SFX by peak, -14 LUFS -> out/audio.wav
- README 接着写的合成命令是:
ffmpeg -i out/video.mp4 -i out/audio.wav -map 0:v -map 1:a -c:v libx264 -crf 16 -c:a aac -shortest out/final.mp4
render.py 默认打开 http://localhost:8000/film.html,可用环境变量 FILM_URL 改掉。因此第 4 步里的 HTTP 服务要保持运行。probe 把静帧拼成 probe/sheet.png。full 在脚本里把时长设为 24 秒、帧率 60、每帧 8 张子帧,无声画面写到 out/video.mp4,这一步的编码参数是 crf 14、preset slow。带声音的成片是第 5 步的 out/final.mp4,README 写的是 crf 16。
同一支 render.py 还接受 beats 和 pops。beats 按脚本里写死的时间出 probe/beats.png。pops 扫描 out/video.mp4 里的单帧突变。示例脚本没有 draft 和 loop,这两条在 scripts/render_template.py。
audio.py 的文件头写明这是 24 秒配乐,曲目为 Mixkit 的 Cat Walk(Arulo,130 BPM),音效按测到的峰值摆放,最后 0.9 秒淡出,loudnorm 到 −14 LUFS。脚本里的起点是 START = 14.769 - 8.0,也就是把歌曲的 14.769 秒对齐到成片的 8.0 秒。文件头另写歌曲 37.66 秒,和这个 START 对不上。SKILL.md 把 Cat Walk 的 drop 记在 14.769 秒,把 37.66 秒记在另一首 Driving Ambition 上。
在 Claude Code 里用 Opus 5.5 驱动它
在 Claude Code 里用 /model 选 Opus 5.5,详见 Claude Opus 5.5。
README 写的调用方式是要一支片子,或输入:
/motion-design
README 把可以交给模型的修改写成这三句:
make the transitions faster
change the music
add a 3D cube on the drop
SKILL.md 把默认顺序写成:若简报里有 <inputs> 块就先问,否则自己选一组默认值并说明;然后写 BEATMAP.md(BPM、每场落在拍上、drop 对准关键画面,静止不超过 1 秒);先出 4 张静帧或每拍一帧的接触表,看过并改完再全片渲染;接着做 pop 扫描、音频、合成,并给出文件路径和一句与事实相符的说明文字。
同一文件要求写代码前先交导演简报:时长、主格式、从同一条时间线导出的 16:9 / 1:1 / 9:16、主题和一句承诺、受众、渠道、点名的参考风格(文件里的例子是 “Linear launch”“Stripe docs”“Apple bumper”),以及带时间戳的状态。预期产出是 6 拍、图层清单和声音计划(静音、代码合成的音效,或 Mixkit 曲目),然后停下来等确认。没有 facts.md 就不在画面上放数字。
SKILL.md 的提示库写明 adapt, never paste raw for a client。其中 2 段是完整英文提示,原文如下。
One-shot viral:
make a dynamic 15-second motion graphics video that shows what an incredible motion designer you are, like it's your showreel for a résumé. go all out.
One-shot branded:
Make a 15-second showreel at 1920x1080, 30fps. Keep it in one self-contained index.html. HTML, CSS, JS, SVG or Canvas only. No CDN, no external URLs. Bold type and simple shapes. End on [BRAND]. Play and Replay. window.seek(t). Do not render the MP4 yet.
另外三种在 SKILL.md 里是用法说明,不是一整段可直接粘贴的提示。UI morph:一个形状走过 8 到 12 个界面状态(button → loader → player → slider → toggle → tabs → chart → command palette → toast),要有一个真的滑杆,大约 120 BPM,循环要精确接上。Launch reveal:inputs → direction → 逐帧结构 → seek(t) → gotchas → 全片之前先出 4 张静帧。LinkedIn loops:纯 HTML/CSS,一套视觉规范,1 次 “A becomes B”,5–9 秒循环,同一时间只有 1 件东西在动,缓动为 cubic-bezier(.6,0,.2,1) 和 cubic-bezier(.2,.8,.2,1)。
示例提示词(按 README 写明的用法改写,不是仓库原文):
用 /motion-design 做一支发布片。先写导演简报:点名一种参考风格,列出带时间的状态、图层清单和声音计划,确认后再写代码。画面只放在 seek(t) 里。先给出 4 张静帧,我确认后再做全片、pop scan 和音频。示意数据在画面上写成 Example data。音效按测到的峰值摆放,响度做到 -14 LUFS。
用 remake 模式,把我给的发布片按帧换成我的品牌,并做成 original 和 opus 5.5 copy 的分屏。不要复用原片的音乐、人声和人物照片。音乐用免版税曲目并对到参考片的 BPM,音效放在参考片的击打时间上。
限制与已知问题
README 和 SKILL.md 写明的约束:
- 画面只由
seek(t)计算。不用 CSS transition,不用计时器,帧与帧之间不保留状态。SKILL.md写不要使用Math.random,改用带种子的 PRNG。 - 示意数据必须在画面上标成 “Example data”“Example answer” 或 “Illustration”。字幕不能写成与制作过程不符的说法。
tmix不跨硬切。循环要同时对齐位置和速度。- 第三方媒体、品牌标志和 Howseen 标志的归属见上一节,不在 MIT 代码许可里。
- 翻拍不得复用参考片的音乐、人声和人物照片。
BRIEF_TEMPLATE.md还写不要做出并不存在的联名,例如暗示与某家公司合作的组合标志。 - 无头 WebGL 会全黑。模板用环境变量
WEBGL=1加上 SwiftShader / ANGLE。 - Unsplash 的 napi 可能返回 401。
SKILL.md写的退路是picsum.photos。 - 示例
render.py的子帧偏移铺满整帧间隔。180° 快门(SHUTTER = 0.5)写在render_template.py里,不在示例脚本里。 SKILL.md写超过 25 秒的片子要分成 3 段并行渲染。仓库示例是 24 秒,README 给出的是一条python render.py full。SKILL.md里的多支成片目录不在公开仓库中。按那些路径去拷贝文件夹,在克隆下来的仓库里找不到。
SKILL.md 的症状表:
| 现象 | SKILL.md 写的处理 |
|---|---|
| 成片和常见模板片一样 | one-shot 提示被原样贴上,没有规范和状态。先写简报、facts.md 和点名的参考风格 |
| 文字发糊、标志发灰 | 走了像素视频模型。回到代码和真实 SVG |
| 导出卡顿 | 用了计时器或 CSS transition。改成纯 seek(t),每次 seek 之后等 2 次 requestAnimationFrame |
| 循环跳一下 | 位置对齐了,速度没有。补上前 2 个循环的弹簧尾,并运行 render.py loop |
| 弹性看起来很廉价 | 用了 bounce 缓动。改成弹簧,阻尼比至少 0.72 |
| 编造了功能 | 没有截图、仓库或 facts.md |
| WebGL 全黑 | 设置 WEBGL=1 |
| 很小的修改却把 effort 开到最大 | 改用 medium |
症状表里的 render.py loop 对应 scripts/render_template.py。示例目录里的 render.py 没有 loop 子命令。
SKILL.md 还写了一组反“AI motion”规则:只用一个强调色;除非滑杆驱动连续变形,否则同一时间只动一件事;从头到尾一个形状系统,用变形而不是硬切;弹簧阻尼比至少 0.72,过冲很小。文件点名不要用彩虹渐变、粒子、发光金属、emoji、lorem ipsum,以及没有必要的三维翻转。字号要在手机上可读。9:16 的安全区在分镜时定,文字放在中间 1080×1080 里。
截至 2026-10-23,仓库有 1 个 open issue。
常见问题
能不能用 Codex 或 Cursor?
README 未写明 Codex 或 Cursor。安装路径是 ~/.claude/skills/,调用方式是 Claude Code 里的 /motion-design。SKILL.md 的 description 也把它写成 Claude Code skill。
成品是 HTML 还是 MP4?怎么导出?
两边都有。制作结果是一个 HTML,示例文件是 film.html,每一帧由 window.seek 计算。导出的画面是 python render.py full 得到的 out/video.mp4(示例为 24 秒、60 fps)。python audio.py 得到 out/audio.wav。README 再用一条 ffmpeg 命令合成 out/final.mp4。技能模板另有 draft,输出 out/draft.mp4。
商用和许可怎么算?
代码许可是 MIT,版权人 Howseen AI(Raphaël Aubry)。README 写第三方媒体由 fetch_assets.py 下载,并保留各自的许可:Mixkit free license、Pexels 与 Unsplash 的许可、Geist 为 OFL。品牌标志归所有者,示例中的 Howseen 标志归 Howseen AI。翻拍时不要复用参考片的音乐、人声和人物照片。自备的音乐和标志要按它们自己的许可使用。
要不要 API key?有没有中文字幕或中文配音?
按 README 的安装和示例跑,不需要 API key。SKILL.md 另写了 21st.dev 的 key,路径是 ~/.config/21st.key,原文括号是 “free tier: 2 code retrievals/day”;旁白一节写 Cartesia(Katie)和词级时间戳。示例脚本不读取这两项。中文字幕和中文配音 README 未写明。产品全片一节写的是 FR/EN 词典。
相关阅读
- 热门项目合集
- 用 Opus 5.5 做视频
- 从提示词到成片
- 场景模板
- 报错与省用量
- 开源 Skill 与工具
- Claude Opus 5.5
- 环境搭建
- 开源 AI 视频 Skill 目录
- Claude Motion(官方功能)
- product-launch-motion 教程
- claude-motion 教程
- motion-graphics-skills 教程
- animate 教程
- awesome-opus5-5-videos 教程
- herk-edit-kit 教程
参考来源
- howseen-ai/claude-motion-design(查阅日期:2026-10-23)
- 仓库 README.md(查阅日期:2026-10-23)
- skill/motion-design/SKILL.md(查阅日期:2026-10-23)
- LICENSE(查阅日期:2026-10-23)
- examples/howseen-launch/render.py(查阅日期:2026-10-23)
- examples/howseen-launch/audio.py(查阅日期:2026-10-23)
- examples/howseen-launch/fetch_assets.py(查阅日期:2026-10-23)
- skill/motion-design/scripts/render_template.py(查阅日期:2026-10-23)
- skill/motion-design/scripts/remake/BRIEF_TEMPLATE.md(查阅日期:2026-10-23)