html-to-video
把 HTML/Canvas 动画逐帧渲染成 MP4(可配乐、可出 GIF、可出透明层)。当用户说「用代码做视频」「HTML 转视频」「导出 MP4/GIF」「做个动态图解/宣传片/数据动画」「逐帧渲染」时使用。自带渲染器与 11 个开箱即用模板(含多镜头讲解片、竖屏 9:16、前后对比、流程图、字幕卡)、图标/人物/运镜素材库,支持透明输出、外部字幕时间轴与 JSON 镜头表,装好依赖后一条命令出片。
Install / Use
npx skills add wx4766/html-to-videoInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
DesignSupported Platforms
Tags
Our assessment of html-to-video
html-to-video scores 70/100 on our quality scale, 245th of 264 Design skills we index.
Its SKILL.md is 24 KB long, well organised into 50 sections with 35 code examples: a thorough specification that gives an agent plenty to work with.
It has no GitHub stars yet, so there is no community track record; judge it on its content.
Maintenance, license and trust
- We could not determine when the repository was last updated.
- No license is declared. By default that means all rights are reserved: you can read it, but reusing or redistributing it is not clearly permitted. Ask the author before building on it commercially.
- Its trust signals score 68/100, with 3 cautions from licensing, adoption, age or documentation. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
html-to-video compared with similar skills
All 4 of these similar skills score higher than html-to-video; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| html-to-video (this skill)by wx4766 | 70 | 0 | — | SKILL.md |
| algorithmic-artby anthropics | 100 | 177.9k | 41d ago | SKILL.md |
| pptxby anthropics | 100 | 177.9k | 41d ago | SKILL.md |
| designby nextlevelbuilder | 100 | 143.4k | 2d ago | SKILL.md |
| ui-ux-pro-maxby nextlevelbuilder | 100 | 143.4k | 2d ago | SKILL.md |
Frequently asked questions
- How do I install html-to-video?
- Run
npx skills add wx4766/html-to-video. The install tabs above show the steps for each supported agent. - Which AI agents does html-to-video work with?
- It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
- Is html-to-video safe to use?
- It declares no license and scores 68/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is html-to-video still maintained?
- We could not determine when the repository was last updated.
Skill content
View source on GitHubname: html-to-video description: 把 HTML/Canvas 动画逐帧渲染成 MP4(可配乐、可出 GIF、可出透明层)。当用户说「用代码做视频」「HTML 转视频」「导出 MP4/GIF」「做个动态图解/宣传片/数据动画」「逐帧渲染」时使用。自带渲染器与 11 个开箱即用模板(含多镜头讲解片、竖屏 9:16、前后对比、流程图、字幕卡)、图标/人物/运镜素材库,支持透明输出、外部字幕时间轴与 JSON 镜头表,装好依赖后一条命令出片。 agent_created: true
html-to-video · 代码逐帧做视频
这套东西是什么
不是 AI 生成视频,是用代码逐帧画视频:
写 HTML/Canvas,把画面写成 frame(t) 纯函数
→ 无头浏览器逐帧 seek 到 t,截图
→ ffmpeg 编成 H.264 MP4
字幕 / 运镜 / 转场全在代码里,改代码重渲即可
优点:确定性(同输入同输出)、可控到帧、中文文字完美、零费用。 最适合做:讲解动画、动态图解、产品演示、数据可视化动画、宣传片片头。 不适合:实拍感/氛围镜头(那种走 VideoGen)。
能拿它做什么(assets/templates/ 里 11 个模板直接改字就能出片):
| 模板 | 用途 | 出片 |
|---|---|---|
| explainer.html | 多镜头讲解片:片头 / 人物+气泡 / 要点 / 条形对比 / 片尾,镜头带转场,可喂 JSON 镜头表;横屏恰好三条要点时自动并排成三栏,竖屏(1080×1920)另有上下版式 | --duration=17.6 |
| title-card.html | 视频片头:主标题逐字弹入 + 副标题 | --duration=6 |
| bar-chart.html | 条形图/排名:条形依次生长,数值同步滚动 | --duration=6 |
| line-chart.html | 折线趋势:折线生长 + 数据点亮起 + 末点浮标 | --duration=8 |
| number-counter.html | 大数字/KPI:从 0 滚到目标值 + 涨跌标签 | --duration=7 |
| timeline.html | 时间线/流程:中轴生长,节点逐个点亮 | --duration=7 |
| vertical-card.html | 竖屏 9:16 卡片:大字标题 + 大数字,抖音/视频号/Reels 用 | --duration=6 --width=1080 --height=1920 |
| compare.html | 前后对比:左右两栏对照,结论条收口 | --duration=7 |
| flow-steps.html | 流程图动画:步骤依次点亮,当前步高亮 | --duration=7 |
| subtitle-card.html | 逐句解说卡:一句话一句地出,底部带进度条 | --duration=8 + --srt |
| vertical-subtitle.html | 竖屏字幕卡:关键词高亮,9:16 原生版式 | --duration=8 --width=1080 --height=1920 + --srt |
每个模板单文件自包含,顶部有一个显眼的 CFG 配置块,改文案/数据即可 ——
不用懂 canvas 也能出片。11 个模板全部支持换主题(见「换配色」一节)。
想做别的,再看 assets/animation-skeleton.html 从零写。
做「一支片子」而不是「一段动画」:用 assets/lib/scenes.js 写多镜头 + 转场,
镜头表还能用 --story=shots.json 外置 —— LLM 写 JSON 比写几百行 canvas 代码可靠得多。
详见下面「多镜头与转场」一节。
尺寸:模板跟视口走,不用手改
11 个模板都按 window.innerWidth/innerHeight 设画布,所以换任何尺寸都不裁切:
# 横屏 1080p(默认)
bash assets/render.sh title-card.html --duration=6 --fps=60
# 竖屏 9:16
bash assets/render.sh title-card.html --duration=6 --fps=60 --width=1080 --height=1920
# 720p / 4K 同理
bash assets/render.sh title-card.html --duration=6 --fps=60 --width=1280 --height=720
模板内部用三档缩放把设计稿落到实际画布:
| 变量 | 含义 | 1920×1080 | 1080×1920 |
|---|---|---|---|
| SX = W/1920 | 横向尺寸、左右边距 | 1 | 0.5625 |
| SY = H/1080 | 纵向尺寸、行距 | 1 | 1.7778 |
| SF = √(SX·SY) | 字号、线宽、圆角、模糊 | 1 | 1 |
字号用面积等比(SF)而不是跟宽度走 —— 换成竖屏时字不会变小,只是版式铺开。
1920×1080 下三者都等于 1,所以默认输出与旧版逐像素一致(实测 PSNR = inf)。
自己写的动画也照这个来,否则改 --width/--height 会静默裁掉右下角:
const cv = document.getElementById('stage');
cv.width = window.innerWidth; // ← 不要写死 1920
cv.height = window.innerHeight; // ← 不要写死 1080
渲染器现在会主动量一次画布尺寸,比视口小就明确告警(不再静默出半张图)。
先装依赖(只需一次)
渲染器需要 Node 工作区(内含 playwright + 完整版 ffmpeg)。一条命令搞定:
bash scripts/install-deps.sh # 工作区默认 ~/.workbuddy/binaries/node/workspace
bash scripts/install-deps.sh /path/to/workspace # 或自己指定
它会自动探测本机浏览器缓存、挑匹配的 playwright 版本、装完整版 ffmpeg,
并把工作区路径写进 ~/.workbuddy/.html2video-env,之后 render.sh / smoke.sh / qa.sh 开箱即用。
手动装也行(工作区需含 playwright + @ffmpeg-installer/ffmpeg),然后自己写配置:
# ~/.workbuddy/.html2video-env
WB_NODE_WORKSPACE="<你的 node 工作区绝对路径>"
也可以用环境变量临时指定:
export WB_NODE_WORKSPACE="<路径>"。 不要把路径写进${VAR:-默认值}——用户名若含撇号(如O'Brien), bash 会把撇号当引号开始,报bad substitution。
四条硬约束(踩过,别重犯)
-
Playwright 版本必须和浏览器缓存匹配。
playwright-core@X只认自己在browsers.json里声明的 chromium build 号, 不匹配就报 "Executable doesn't exist"。→ 别猜版本,用
scripts/install-deps.sh,它会跑scripts/detect-env.js探测缓存后自动挑版本。 单独探测:node scripts/detect-env.js(输出RECOMMEND_PW=...)。 已知映射:build 1148→1.49.1、1155→1.50.1、1169→1.52.0、1187→1.55.0、1208→1.58.0。注意:某些网络环境下 chromium 下载会反复中断(表现为缓存目录里躺着半截的残缺目录)。 此时优先复用已有缓存而非升级——这正是探测脚本存在的理由。
-
Playwright 自带的那个 ffmpeg 没用。
ms-playwright/ffmpeg-*/ffmpeg-win64.exe是--disable-everything编译的, 只有 VP8 编码 + webm 封装,没有 H.264、没有 GIF、连 PNG 解码都没开。 必须用@ffmpeg-installer/ffmpeg的完整版。 -
ESM 不认
NODE_PATH。.mjs里import 'playwright'必然ERR_MODULE_NOT_FOUND。 → 辅助脚本一律写 CJS(.cjs/require)。 -
PATH 不可靠。 尤其在 Git Bash / Windows 上,塞进 PATH 的 Windows 风格路径会被转换搞坏。 → 别靠 PATH 传 ffmpeg,用
FFMPEG环境变量(渲染器已支持)。
出片流程
第 0 步(最省事的路):挑一个模板改字
cp assets/templates/bar-chart.html my-video.html
# 打开 my-video.html,只改顶部 CFG 里的 title / data / note
bash assets/render.sh my-video.html --duration=6 --fps=60
模板有字幕安全区意识:文字不会落在画面底部 15%(烧录字幕后会被盖住)。 自己做版式时也照这个来。
第 1 步:写动画 HTML(模板不够用时)
用 assets/animation-skeleton.html 当骨架。核心契约(渲染器靠它工作):
// 必须暴露这两个
window.__seek = (t) => { /* 把 t 时刻的画面完整重绘一帧 */ };
window.__ready = true; // 就绪信号
// 渲染器会注入 window.__seekRender = true,
// 此时必须【冻结自驱时钟】,完全由外部 __seek 推帧(保证确定性)
if (window.__seekRender) { renderAt(0); window.__ready = true; }
else { /* 浏览器预览:requestAnimationFrame 自驱循环 */ }
铁律:每一帧画面 = 时间 t 的纯函数。 不要依赖「上一帧」的状态,
不要用 Math.random() / Date.now() / performance.now()——那会让同输入不同输出,
QA 里的「确定性」会亮红灯,而且多 worker 并行渲染会各渲各的。
画布就是唯一输出:<canvas width=1920 height=1080>,CSS 定位在 left:0; top:0,
body margin:0。渲染器用 clip:{x:0,y:0,width:W,height:H} 截左上角,所以画布必须正好铺满视口、不能居中。
(渲染器也支持 DOM/CSS/SVG 动画,同样只需暴露 __seek——但注意:DOM 动画每帧重排较慢,
纯 canvas 通常更稳更快。)
禁止使用的 class 名(渲染器注入的 CSS 会无条件隐藏它们,元素会凭空消失):
.no-record .progress .progress-bar .counter .tCur .phases .phase-label .phase .replay .masthead .kicker .title .footer
另外别给 position:fixed/sticky 的元素加 <button>,会被启发式规则当成播放控件隐藏。
(想让某块出现在成片里,给它加 data-record-keep="true" 就能豁免启发式隐藏。)
中文字体:'"Microsoft YaHei", "PingFang SC", system-ui, sans-serif';等宽用 'ui-monospace, Consolas, monospace'。
第 2 步:冒烟测试(别跳)
先只截几帧,确认契约就绪、没控制台报错、画面没糊,再跑全量:
bash assets/smoke.sh animation.html
# SMOKE_T="0,1,2" SMOKE_W=1280 SMOKE_H=720 bash assets/smoke.sh animation.html
更快的迭代方式:只渲一小段,几秒就能看到动态效果。
bash assets/render.sh animation.html --from=3 --to=5 --fps=30 # 只渲 3s–5s
bash assets/render.sh animation.html --stills=1,3,5 # 只导出三张静帧
第 3 步:全量渲染
bash assets/render.sh animation.html --duration=12 --fps=60 --width=1920 --height=1080 --concurrency=4
常用参数:
| 参数 | 作用 |
|---|---|
| --duration / --from / --to | 时长 / 只渲某段(秒)。给了范围时输出名变成 名.起-止s.mp4,不会覆盖成品 |
| --stills=0.5,2.0 | 只导出这些时刻的 PNG,不编码 |
| --fps / --width / --height | 帧率与分辨率 |
| --preset=<名> | 按平台预设定尺寸:douyin / tiktok / vertical(1080×1920)、xiaohongshu(1080×1440)、instagram(1080×1350)、square(1080×1080)、bilibili / youtube / landscape(1920×1080) |
| --presets=a,b,c | 一条命令出全套比例,每个比例一个成片(文件名自动加 -比例名 后缀)。跨平台发布用这个 |
| --theme=<名> | 换主题(midnight / paper / neon),覆盖模板里的 CFG.theme,不用改文件。名字打错会明确告警并回退 midnight |
| --out=<文件> | 指定成片路径(默认同目录同名)。一份 HTML 出多套配色时用它,否则后渲的会盖掉前一个;上级目录不存在会自动建 |
| --json | stdout 只输出一行结果 JSON(output / duration / frames / warnings 等),人读日志全部走 stderr。给 Agent 解析用 |
| --concurrency | 并行 worker 数(每个 worker 一个 Chromium 页面,注意内存)。给 auto 按 CPU 与内存自己挑 |
| --audio=<file> | 编码后自动混音(视频流直接 copy,不重编码)。没给 --duration 时自动按音频长度出片(向上取整到整帧,尾音不被削) |
| --audio-fit=trim\|pad | 音画长度不一致时怎么办:trim 按音轨收尾(默认)/pad 给音频补静音、保住视频长度 |
| --gop=<秒> | 关键帧间隔,如 --gop=1 每秒一个关键帧,方便后期按秒 seek |
| --keep-frames | 成功也保留逐帧 PNG(换 CRF 重编码时不必重截) |
| --tmpdir=<目录> | 逐帧 PNG 放哪块盘(默认挨着 HTML)。1080p 一分钟约 2.4 GB,系统盘没余量时指到别的盘 |
| --resume | 上次渲到一半被打断?接着渲,已渲好的帧直接复用(参数和上次不一致会拒绝,见下) |
| --alpha | 透明背景输出(ProRes 4444 .mov),叠到实拍 / AI 生成画面上用,见下 |
| --srt=<file> | 外部字幕时间轴(SRT / VTT / JSON),注入 window.__cues,见下。同义参数 --cues |
| --cue-log=<file> | 导出 frame,t,cue_index,cue_start,cue_end CSV,用来核对字幕到底对不对轴 |
| --story=<file> | 镜头表 JSON,注入 window.__story,整份换掉剧本(见「多镜头与转场」) |
| --scene-log=<file> | 导出镜头时间轴 CSV;镜头表总时长与 --duration 不一致会告警 |
| --gif[=fps,宽] | 出片后顺手产 GIF(默认 15fps / 宽 960),两阶段 palette 优化,不重渲 |
| --poster=<秒> | 出片后顺手抽一张封面静帧 .jpg,发站 / 社媒用 |
| --batch=<file.json> | 一串任务按顺序渲,最后打汇总表;单个失败不连坐已渲好的,但整体非零退出 |
| --headed | 开着浏览器窗口渲(调试用;并发自动降到 1,免得弹一排窗口) |
| --allow-errors | 页面报错不判失败(默认:有报错 → 非零退出) |
| --keep-chrome | 不隐藏播放控件(调试用) |
| --readytimeout=8 | 等 __seek 就绪的秒数(启动慢的大字体/大数据可调大) |
| --no-serve | 用 file:// 加载页面(默认走本地 http server,见下) |
ESM / fetch 项目直接能渲。渲染器默认起一个只绑 127.0.0.1 的本地 http server 来加载页面 ——
file:// 下 <script type="module"> 和 fetch() 会被 CORS 拦死,用 Vite/esbuild 组织的动画、
读本地 JSON 的项目根本起不来;走 http 就没这些事。渲染开头会打印这个地址,排障时直接粘到浏览器里看控制台最方便。
服务器起不来会自动退回 file:// 并提示(只警告,不判失败)。
- 输出与 HTML 同名的
.mp4 - 帧数 =
fps × duration。12s@60fps = 720 帧,实测约 6~7 分钟(concurrency=4) - 编码约 1 分钟(crf 18 / preset medium)
渲染结束有页面报错会非零退出(但成片照样产出,方便你核对)。
渲到一半断了,别从零开始
长片子(60fps × 30s = 1800 帧)跑到 80% 崩了,从零重来最伤。加 --resume 就接着渲:
bash assets/render.sh animation.html --fps=60 --duration=30 --resume
# ▸ resume: 已复用 1432 帧,还需渲 368 帧
规则三条,都是为了「续出来的片子和一次渲完的片子一模一样」:
- 帧先写
.part再改名。被 kill 的那一帧不会留下半个 PNG 冒充「已完成」,所以复用的帧都是真画完的。 - 参数变了直接拒绝。上次 30fps、这次 60fps 会把两批帧混着编码,片子前后节奏不一致还不报错 ——
所以
fps / 尺寸 / 范围 / 渲染模式任一不同就退出并打印「上次 vs 这次」,让你自己决定删不删。 - 帧号必须连续。缺一张 ffmpeg 会静默提前收尾、成片莫名变短,所以编码前按
[起,止)逐个核号, 有洞就报出来并提示加--resume补。
临时目录固定在 HTML 旁边的 .seek-tmp-resume/(不加 --resume 时仍是一次性目录,并发渲互不干扰)。
渲完自动清掉;中途想留着就配 --keep-frames。
这是故意的:页面报错常常意味着「整片黑屏 / 缺了半屏内容」,以前的版本会一路说成功,
直到你回抽帧才发现——现在它会在编码前就把报错打出来,并在最后判失败。
透明输出:把文字层叠到别人拍的画面上
AI 生成的背景 + 代码生成的文字层,是现在最省钱的组合(模型画文字必糊,代码画文字精确到像素)。
--alpha 就是为这条路准备的:
bash assets/render.sh animation.html --duration=6 --fps=30 --alpha
# → animation.mov(ProRes 4444 / yuva444p10le,背景透明)
模板侧要配合一件事:读到 window.__transparent 为真时跳过背景层绘制。
目前 title-card、compare、flow-steps、subtitle-card、vertical-subtitle、
explainer 这 6 个已经这样写,直接加 --alpha 就有透明效果;
其余 5 个是满版图表(条形 / 折线 / 大数字 / 时间线 / 竖屏卡),本来就要底色,加了也只会得到不透明的片子。
自己写的动画照这个来:
const TRANSPARENT = !!window.__transparent;
function drawFrame(t) {
g.clearRect(0, 0, W, H);
if (!TRANSPARENT) {
// 底色 / 全屏渐变 / 光斑 —— 这些都要跳过
g.fillStyle = '#080A10';
g.fillRect(0, 0, W, H);
}
// 文字、图形照常画
}
全屏的半透明光晕也要一起跳过。哪怕它只有 5% 不透明度,叠到实拍上会让整片区域泛白, 剪辑师第一反应是「这素材脏」。实测:只跳底色、留着光斑时,四角 alpha=12(不是 0); 全跳之后四角 alpha=0、只有 3.7% 的像素不透明(全是文字)。
体积代价(960×540 / 2s / 20 帧实测):
| 输出 | 体积 | 用途 |
|---|---|---|
| H.264 .mp4 | 118 KB | 成片直接发 |
| ProRes 4444 .mov | 760 KB(6.5×) | 拖进剪辑软件叠层 |
只有 ProRes,没有 VP9。试过 --pix_fmt yuva420p + -auto-alt-ref 0,文件确实从 7.8KB
涨到 16.8KB(alpha 数据写进去了),但 Chromium 播出来整帧 alpha 全 0 —— 连文字都透明;
换 lossless、固定码率、-lag-in-frames 0 都一样。既然没法自证正确,就不把它作为选项发布。
要小体积透明素材,用 ProRes 导入剪辑软件后再导 webm,那是那边的活。
配音对齐:先有声音,再定画面长度
真实工作流是「写文案 → 配音 → 配画面」,而不是先定 6 秒再想办法把配音塞进去。
所以给了 --audio 又没给 --duration 时,视频按音频长度出片:
bash assets/render.sh title-card.html --audio=voice.m4a --story=shots.json
# ▸ audio: 音频 12.48s,未指定 --duration → 视频按音频定长(12.5s,向上取整到整帧)
- 向上取整到整帧,不是四舍五入:少半帧就会把最后一个字的尾音削掉。
- 显式给了
--duration且与音频差超过 0.35s 会明确告警,说清差多少、伤在哪边。 旧版本这里会静默出一支短片 —— 画面后半段整段消失,日志却只有一句✓ Done。 --audio-fit=pad:音频比视频短时补静音,保住整段画面(默认trim按音轨收尾)。
注意:trim 下成片不会精确等于音频秒数。视频流是 -c:v copy 直接复制的,
ffmpeg 只能按帧包边界收尾,实测会多留 0.3–0.5s。想要毫秒级对齐得重编码,
那是拿画质换精度,不值得 —— 片尾多留几帧通常看不出来。
一稿多发:一条命令出全套平台比例
同一条片子要发抖音、小红书、B 站,剪辑软件里得一个比例一个序列、导一次盯一次。 这里版式本来就是参数化的,多渲一遍只是多一次循环:
bash assets/render.sh bar-chart.html --duration=8 \
--presets=douyin,xiaohongshu,square --out=dist/chart.mp4
# → dist/chart-douyin.mp4 1080×1920
# dist/chart-xiaohongshu.mp4 1080×1440
# dist/chart-square.mp4 1080×1080
| 预设 | 尺寸 | 给谁用 |
|---|---|---|
| douyin / tiktok / vertical | 1080×1920 | 抖音、快手、视频号、Reels、Shorts |
| xiaohongshu / xhs | 1080×1440 | 小红书 3:4 |
| instagram / ig | 1080×1350 | IG 信息流 4:5 |
| square | 1080×1080 | 方版 1:1 |
| bilibili / youtube / landscape | 1920×1080 | 横屏 16:9 |
- 单个比例用
--preset=xiaohongshu;多个用--presets=a,b(至少两个,只想要一个就用--preset)。 - 预设名拼错会直接失败并列出可用名字 —— 不会悄悄按 1920×1080 渲一版比例
Truncated for display — read the full file on GitHub.
Related Skills
algorithmic-art
177.9kCreating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems.
pptx
177.9kUse this skill any time a .pptx or .potx file is involved in any way — as input, output, or both. This includes: creating slide decks, pitch decks, or presentations; reading, parsing, or extracting text from any .pptx or .potx file (even if the extracted content will be used elsewhere, like in an em…
design
143.4kComprehensive design skill: brand identity, design tokens, UI styling, logo generation (55 styles, Gemini, Atlas Cloud, or MuAPI AI), corporate identity program (50 deliverables, CIP mockups), HTML presentations (Chart.js), banner design (22 styles, social/ads/web/print), icon design (15 styles, SVG…
ui-ux-pro-max
143.4kUI/UX design intelligence for web, mobile, and desktop. This skill should be used when designing, building, reviewing, or fixing interfaces, including pages, components, design systems, accessibility, interaction, responsive layout, typography, color, charts, and stack-specific UI implementation.
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
