Communitygithub.com

erencalik/motion-graphics-video-generator-claude

根据单一请求生成带音乐的动画 MP4 动态图形视频(9:16 Reels 或 16:9),通过逐帧渲染 HTML/CSS/JS 动画并利用 ffmpeg 合成。适用于动态图形、动态文字、动画统计和 Reels 动画。

motion-graphics-video-generator-claude 是什么?

该技能允许你在 Claude 的代码环境中端到端生成 MP4 格式的动态图形视频,无需任何编辑软件或素材库。它通过编写一个完全基于帧号计算每个元素位置、大小、颜色和不透明度的 HTML 页面来驱动渲染,使用 Playwright 控制的 Chrome 无头浏览器逐帧截图,然后用 ffmpeg 将这些帧合成为 H.264 编码的 MP4 文件,并可以合成或添加背景音乐。支持 9:16 和 16:9 两种分辨率,适用于 Reels/TikTok/Shorts 或 YouTube/作品集。开发者只需提供文字、数字、风格(如动态文字、动画统计图、粒子效果等)和素材(如 Logo、照片),即可快速制作专业级别的动态图形视频,非常适合制作品牌宣传片、数据可视化动画和社交媒体内容。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/erencalik/motion-graphics-video-generator-claude/tree/HEAD

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Motion Graphics Video

在 Claude 的代码环境中端到端生成 MP4 视频,无需编辑软件或素材库。需要启用代码执行和文件创建功能(在 claude.ai 上:设置 > 能力)。如果是品牌视频,请上传 logo、照片、颜色和字体,或指定品牌风格文件。以用户的语言回复。

工作原理

  1. 动画编写在单个 HTML 页面中。每个元素的位置、大小、颜色和不透明度根据帧号计算(window.renderFrame(f));不使用 CSS 过渡、setTimeout 或 requestAnimationFrame。这使得渲染具有确定性。
  2. 无头 Chrome(Playwright)捕获每一帧。20 秒 × 60 fps = 1,200 帧。
  3. ffmpeg 将帧转换为 MP4(H.264, yuv420p)。
  4. 音乐在代码中合成,与转场节奏匹配,并添加到视频中。

请求检查清单(缺少时询问一次)

  1. 时长: 15–20 秒为理想。
  2. 格式: 9:16 (1080x1920) 用于 Reels/TikTok/Shorts,16:9 (1920x1080) 用于 YouTube/作品集。
  3. 素材: 网站链接、上传的照片、Logo,或者什么都不提供。
  4. 风格: 指定技术名称:动态文字、信息图/统计动画、粒子、半调、地图/地形、计数器、时间线。指定技术名称能获得更可靠的结果。
  5. 规则和排除项: 需要匹配的颜色、需要省略的内容(例如价格、额外文字)。
  6. 创作自由度: 如果用户说“尽你最大努力”,Claude 自行选择概念、调色板和音乐,并更大胆地发挥。

故事 Reel 的现成结构:Logo/片头介绍(0–2 秒)→ 故事句子以动态文字形式出现 → 计数器上增长的数字 → 时间线或地图 → 结尾卡片(账号 ID)。保持屏幕文字在 Reels 安全区域内(顶部 210 px,底部 310 px,右侧 84 px 留空)。数字和日期必须有来源;切勿动画化虚构的数字。

制作步骤

  1. 逐秒编写场景计划(表格:时间 | 屏幕上内容 | 转场 | 音频节拍)并展示给用户。
  2. 编写 scene.html。规则:固定像素尺寸,定义 window.TOTAL(总帧数)和 window.renderFrame(f);使用缓动函数进行插值;将字体嵌入为 base64 woff2(环境可能无法访问 Google Fonts),图片嵌入为 base64。
  3. 首先捕获 3–4 张 PNG 帧并自行检查(溢出文字、错误字体、空白帧)。然后再进行完整渲染。
  4. 使用 audio.py 合成音乐;将节拍对齐场景转场。如果用户上传了自己的音乐,则使用该音乐。
  5. 合并,使用 ffprobe 验证时长/分辨率,目视检查中间帧,交付 MP4。

渲染时间:20 秒 @ 60 fps 大约需要 8–10 分钟。快速草稿使用 30 fps,最终版本使用 60 fps。接受按时间码提出的修改请求(“让 0:07 处的计数器慢一点”)。

模板(经过测试;也作为文件与此 SKILL.md 一起提供)

scene.html(骨架)

<!doctype html><html><head><meta charset="utf-8"><style>
html,body{margin:0;width:1080px;height:1920px;overflow:hidden;background:#0E0E10;font-family:'Montserrat',Arial,sans-serif}
#s{position:relative;width:1080px;height:1920px}
.t{position:absolute;left:90px;right:90px;color:#F5F1E8;font-weight:800;line-height:1.05}
</style></head><body><div id="s">
<div class="t" id="a" style="top:520px;font-size:120px">5,126</div>
<div class="t" id="b" style="top:680px;font-size:64px;color:#FF5A1F">FAILED PROTOTYPES</div>
</div><script>
const FPS=30,DUR=3;window.TOTAL=FPS*DUR;
const clamp=(x,a=0,b=1)=>Math.min(b,Math.max(a,x));
const easeOut=t=>1-Math.pow(1-t,3);
window.renderFrame=f=>{const t=f/FPS;
 const p=easeOut(clamp(t/0.6));a.style.opacity=p;a.style.transform=`translateY(${(1-p)*80}px)`;
 a.textContent=Math.round(5126*easeOut(clamp(t/1.5))).toLocaleString('en-US');
 const q=easeOut(clamp((t-0.8)/0.5));b.style.opacity=q;b.style.transform=`scale(${0.8+0.2*q})`;};
</script></body></html>

render.js:node render.js scene.html video.mp4 30(如果缺少 Playwright:npm i playwright && npx playwright install chromium;如果失败,则使用 Python Playwright 构建相同的循环)

// node render.js scene.html out.mp4 [fps]
const {chromium}=require('playwright');const {spawn}=require('child_process');const path=require('path');
(async()=>{const [,,html,out,fpsArg]=process.argv;const fps=+(fpsArg||30);
const b=await chromium.launch();const p=await b.newPage({viewport:{width:1080,height:1920}});
await p.goto('file://'+path.resolve(html));await p.evaluate(()=>document.fonts.ready);
const total=await p.evaluate(()=>window.TOTAL);
const ff=spawn('ffmpeg',['-y','-f','image2pipe','-framerate',String(fps),'-i','-','-c:v','libx264','-pix_fmt','yuv420p','-crf','18','-preset','medium',out],{stdio:['pipe','inherit','inherit']});
for(let f=0;f<total;f++){await p.evaluate(f=>window.renderFrame(f),f);ff.stdin.write(await p.screenshot({type:'jpeg',quality:92}));}
ff.stdin.end();await new Promise(r=>ff.on('close',r));await b.close();console.log('frames',total);})();

对于 16:9,将视口和页面尺寸更改为 1920x1080。

audio.py:python3 audio.py music.wav <seconds>(numpy 合成:铺底 + 节拍)

# python3 audio.py music.wav 3   -> 合成铺底 + 节拍
import sys,wave,numpy as np
out,dur=sys.argv[1],float(sys.argv[2]);sr=44100;t=np.arange(int(sr*dur))/sr
pad=sum(np.sin(2*np.pi*f*t) for f in (110,164.8,220))*0.08*np.minimum(1,t/0.5)
def hit(at,f0=60):
    x=np.zeros_like(t);m=t>=at;tt=t[m]-at;x[m]=np.sin(2*np.pi*f0*tt*(1+3*np.exp(-tt*30)))*np.exp(-tt*8)*0.6;return x
y=pad+hit(0.0)+hit(0.8,90)
y=y/np.max(np.abs(y))*0.8;fade=np.minimum(1,(dur-t)/0.4);y*=fade
w=wave.open(out,'wb');w.setnchannels(1);w.setsampwidth(2);w.setframerate(sr);w.writeframes((y*32767).astype(np.int16).tobytes());w.close()

合并

ffmpeg -y -i video.mp4 -i music.wav -c:v copy -c:a aac -b:a 192k -shortest final.mp4

限制

  • 效果可应用于照片(粒子、半调、裁剪);无法对人物进行动画处理,无法实现口型同步(请使用专用的虚拟形象/视频模型)。
  • 合成音乐为电子风格;如需真实乐器或人声,请上传音频文件。
  • 禁止使用用户不拥有的受版权保护的字符或徽标。在新闻/评论语境中使用真实公司徽标时,需注明来源。

致谢:基于 Michael Ly 的指南“How to Generate Motion Graphics Videos with Claude”(milleemd.com/guides/motion-graphics-videos)中的方法;代码模板为此技能编写。

相关技能