SkillAgentSearch skills...

html-explainer

把一个主题做成有配音、字幕、封面的讲解分析类视频 —— 全本地、用 HTML 写画面,稳定音画同步。 面向 AI 编程智能体的确定性 HTML → MP4 渲染流水线。

Install / Use

npx skills add OneMoh/html-explainer

Installs into whichever agent you are using.

About this skill
📄

SKILL.md

Installable skill definition

Quality Score

84/100

Supported Platforms

Claude Code
OpenAI Codex

Tags

Our assessment of html-explainer

html-explainer scores 84/100 on our quality scale, 203rd of 1,340 Development & Engineering skills we index (top 16%).

Its SKILL.md is 12 KB long, well organised into 22 sections with 6 code examples: a thorough specification that gives an agent plenty to work with.

It has 47 GitHub stars, so there is little community track record yet; judge it on its content.

Substance
30/30
Structure
20/20
Description
12/15
Adoption
7/20
Freshness
15/15

Maintenance, license and trust

  • The repository was last updated today, so html-explainer is actively maintained.
  • It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
  • Its trust signals score 92/100, with 1 caution 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.

Safety scan

No issues found

Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands.

Automated pattern scan on 2026-09-24. It catches known dangerous patterns, not every risk — read a skill before letting an agent act on it.

html-explainer compared with similar skills

All 4 of these similar skills score higher than html-explainer; compare them before choosing.

SkillScoreStarsUpdatedFormat
html-explainer (this skill)by OneMoh8447todaySKILL.md
ai-job-searchby MadsLorentzen10043.8k3d agoCLAUDE.md
claude-howtoby luongnv8910041.6k4d agoCLAUDE.md
guizang-ppt-skillby op74189926.9k48d agoCLAUDE.md
gemini-cliby google-gemini97107.1ktodayMCP Server

Frequently asked questions

How do I install html-explainer?
Run npx skills add OneMoh/html-explainer. The install tabs above show the steps for each supported agent.
Which AI agents does html-explainer work with?
It is written for Claude Code and OpenAI Codex, as a SKILL.md file. Other agents that read the same format can often use it too.
Is html-explainer safe to use?
Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. It is MIT-licensed and scores 92/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-explainer still maintained?
The repository was last updated today, so html-explainer is actively maintained.
<div align="center">

html-explainer

一个 Agent Skill:给任意主题,产出一条带配音、硬字幕、封面的讲解视频。

HTML 写画面 → 确定性逐帧渲染 → 真 MP4。全本地跑,核心链路零 API key、零按次计费。

License: MIT Version Agent Skill Claude Code Codex WorkBuddy Python Node

简体中文 · English

<br/>

三条用本技能生成的成片——画面、配音、字幕、封面全部由流水线产出,无手工后期。 封面等素材托管在演示仓库,本仓库零体积。

https://github.com/user-attachments/assets/912e6c2d-831f-43dd-a39f-57b749bb417d

| 港股创新药 · 早盘 | 量化简史 | |---|---| | https://github.com/user-attachments/assets/8007843c-088d-457c-8550-81ec912e0add | https://github.com/user-attachments/assets/28949988-449b-4c4e-8d0f-6706af6f64ee |

欢迎关注测试账号,实时观看视频数据

| 抖音 · OnlyOneMoh | 主页实况 · Moen | 抖音 · Moen_xin | |---|---|---| | <img src="https://raw.githubusercontent.com/OneMoh/html-explainer-demos/main/images/douyin-qr-moh-onlyonemoh.jpg" width="240"> | <img src="https://raw.githubusercontent.com/OneMoh/html-explainer-demos/main/images/douyin-profile-moen.jpg" width="240"> | <img src="https://raw.githubusercontent.com/OneMoh/html-explainer-demos/main/images/douyin-qr-moenxin.jpg" width="240"> |

</div>

它是什么

html-explainer 把一个主题做成带配音、带硬字幕、带进度条的讲解视频,画面用 HTML/CSS/GSAP 写。

它是一个 Agent Skill(SKILL.md + scripts/ + references/),遵循 Agent Skills 约定,Claude Code / OpenAI Codex / WorkBuddy / Cursor / Gemini CLI 等都能直接加载。内部是普通的 Python 与 Node 脚本, 手工跑也完全没问题。

你只需要说一句:

把「为什么天空是蓝色的」做成一条 1 分钟的讲解视频。

技能会带着智能体走完:调研 → 解说词 → 配音 → 字幕与节拍 → 挑风格写画面 → 渲染 → 体检 → 封面。


安装

一句话安装(推荐)

把下面这句发给你的智能体:

给当前本地环境安装该 Skill:https://github.com/OneMoh/html-explainer.git
安装到你的技能目录,并检测安装必要的运行环境(Python 3.9+ / Node 18+ / Chrome 或 Edge / ffmpeg)

它会自己 clone 到对应目录、跑环境自检、把缺的东西装上。装完新开一个会话,让智能体重新 扫描技能目录。

手动安装

仓库根目录就是技能目录(SKILL.md 在根),直接 clone 进技能目录即可,不用再拷子目录:

git clone https://github.com/OneMoh/html-explainer.git ~/.workbuddy/skills/html-explainer
bash ~/.workbuddy/skills/html-explainer/setup_env.sh --install

Windows 上 ~ 就是 C:\Users\<你的用户名>。

各智能体的技能目录

| 智能体 | 个人级(全局) | 项目级(仓库内) | |---|---|---| | WorkBuddy | ~/.workbuddy/skills/ | <工作区>/.workbuddy/skills/ | | Claude Code | ~/.claude/skills/ | .claude/skills/ | | OpenAI Codex | ~/.codex/skills/ | .codex/skills/ 或 .agents/skills/ | | Gemini CLI | ~/.gemini/skills/ | .gemini/skills/ 或 .agents/skills/ | | Cursor | ~/.cursor/skills/ | .cursor/skills/ | | GitHub Copilot / VS Code | ~/.copilot/skills/ | .github/skills/ | | OpenCode | ~/.config/opencode/skills/ | .opencode/skills/ | | Windsurf | ~/.windsurf/skills/ | .windsurf/skills/ | | 其他(通用约定) | ~/.agents/skills/ | .agents/skills/ |

记不住放哪:优先 .agents/skills/,多数工具都认它(Claude Code 是例外,只认 .claude/skills/)。

环境要求

| 项 | 最低 | 说明 | |---|---|---| | Python | 3.9+ | edge-tts==7.2.8(刻意钉死 —— v7 改过边界 API)、numpy、pillow、imageio-ffmpeg。火山引擎引擎零额外依赖(只用标准库 urllib,不需要装 SDK) | | Node.js | 18+ | 渲染器与封面器用 | | 浏览器 | Chrome 或 Edge | 自动探测;都没有才下载 playwright chromium(约 115MB,只需一次) | | ffmpeg | 任意版本 | 先在 PATH 找;没有则用 imageio-ffmpeg 自带的静态二进制 | | 磁盘 | 每条成片约 2GB | 帧 PNG 体积大,合成后可删 |

bash setup_env.sh 只检查并报告缺什么,--install 才会装。全程不需要管理员权限。


配音:两个引擎

流水线开始前,智能体会先问你用哪个 TTS,再列候选音色让你挑(也可以直接给它音色 ID):

| | edge-tts | 火山引擎语音合成 2.0 | |---|---|---| | 你要做什么 | 什么都不用做 | 填一次 API Key | | 费用 | 免费 | 按字符计费 | | 音色 | 内置中英文若干 | 豆包 2.0 音色库,含声音复刻 | | 字级时间戳 | WordBoundary | sentence.words[] | | 额外依赖 | edge-tts==7.2.8、imageio-ffmpeg | 零 —— 只用标准库 urllib | | 什么时候选它 | 默认。开箱可用、够用 | 想要更自然的语气与更好音质 |

两者产出的 audio-manifest.json 结构完全一致,所以时间轴、字幕、渲染全都不用改 —— 换引擎只是换一个字段的事。

选火山时,你唯一要动手的地方

技能第一次跑火山时会生成一个 tts.env 并停下来,然后告诉你把 API Key 填进去 (火山控制台 → 语音技术 → API Key 管理)。你填好回来说一声,智能体就去测连接、确认音色, 然后接着往下跑。

这一步刻意不经过对话窗口 —— 密钥不发给智能体,智能体也不需要知道它。

内置常用音色(完整列表见官方音色文档):

| 男声 | 女声 | |---|---| | 云舟 2.0(默认)· 温暖阿虎 2.0 · 解说小明 2.0 · 磁性解说男声 2.0<br>悬疑解说 2.0 · 广告解说 2.0 · 儒雅青年 2.0 · 少年梓辛 2.0 · 深夜播客 2.0 | 小何 2.0 · Vivi 2.0 · 知性灿灿 2.0<br>甜美桃子 2.0 · 邻家女孩 2.0 · 温柔淑女 2.0 |

内置列表不够用时,也可以直接用声音复刻出来的音色 ID。

密钥纪律

API Key 只存在 tts.env 里,而且只有技能里的一个接口包读它。 智能体调的是那个接口包,拿不到、也不需要读密钥的值:

你(手工填一次)→ tts.env(已被 .gitignore 忽略)
                      ↓  只有接口包读
               合成调用  ← 智能体只调这个,永远拿不到密钥值
                      ↓
               火山引擎
  • 不进对话:问智能体密钥状态,它给你的是脱敏摘要(ef90******86c8)。
  • 不进仓库:.gitignore 覆盖 tts.env / *.env / *.key / *.pem / secrets/; 仓库自检里有专门的密钥防线,并且做过反向自证 —— 故意植入一个假密钥会被当场抓到。
  • 不进日志:出错信息过脱敏,只抹「这次实际用到的密钥值」与 AKLT… 形态的 token —— 刻意不用「长字符串就算密钥」这种宽规则,否则连排查要用的请求 ID 一起抹掉。
  • 不进分发:技能打包时排除密钥文件。
  • 兜底层(真正的安全边界):万一还是泄了,损失要可控 —— 建议在火山控制台用 子账号只授语音合成权限、设用量告警与限额,密钥可随时轮换。

说句实话:合成代码是在你本机执行的,运行时进程里密钥对那一段脚本可见, 「智能体绝对读不到」做不到。上面保证的是不进对话、不进仓库、不进日志、不进分发, 把泄露半径收敛成一次可撤销的事故。

另外别用环境变量存密钥 —— 很多宿主会把进程环境原样打进会话记录。

别把 tts.env.example 改名成 tts.env 去填:那是要留在仓库里的模板, 改名会让后来的人没模板可抄(仓库自检会报错并提示)。复制一份再填。


视频项目结构

说一句需求,智能体会在一个视频项目目录里走完整个流水线;产物落在 out/: slug.mp4、cover_169.png、cover_34.png、slug.srt、slug.vtt,外加 qc_report.md 与 qc_sheet.jpg。

项目目录长这样:

my-video/
├── project.json      # slug、fps、尺寸、音色、语速、场景顺序、章节
├── narration.json    # [{ id, text }] —— 用 "|" 切字幕块
├── theme.css         # 所有颜色,以 CSS 变量形式
├── frames/           # 一个场景一个 HTML;<id>.beats.js 自动生成,绝不手改
├── audio/  render/  research/  script/
└── out/              # MP4、封面、SRT/VTT、QC 报告

为什么不用录屏

多数「HTML 转视频」工具是启动浏览器、播放动画、录屏。这条路会生出一整类间歇性 bug —— 动画在录制开始前就播了、网络字体加载晚了导致半段视频用了错误字体、前几帧拍到的是动画前的状态。

html-explainer 不录制,它 seek:把 GSAP 时间轴定位到那一瞬间 (tl.pause(t, false)),同步所有 CSS 动画(document.getAnimations().currentTime), 等两个动画帧后截图。于是第 1204 帧与下一次渲染的第 1204 帧逐像素一致 —— QC 可以定点抽查、 单个场景可以独立重渲,一整类时序 bug 从根本上无法发生。

代价是每个动画都必须可 seek:墙钟动画(setInterval、requestAnimationFrame 计数、 CSS transition 入场)不可能工作,会被 lint_frames.py 直接拒绝。


特性

| | | |---|---| | 节拍锚定解说词 | 画面按匹配字幕文本定位动画(B('块文本')),绝不硬编码帧号。改解说词,全片自动重排时间,画面代码零改动。 | | 词边界字幕 | 时序来自 TTS 的字级时间戳,不按字数插值 —— 中文里两个同字数的短语时长可以差 3 倍。edge-tts 取 WordBoundary,火山引擎取 sentence.words[]。 | | 两个配音引擎 | edge-tts(免费、免密钥、默认)或火山引擎语音合成 2.0(音质更好,需 API Key)。两者产出的 manifest 结构一致,下游零改动。切换用 --provider。 | | 密钥不进 agent、不进仓库 | 火山 API Key 只存 tts.env(已 gitignore),只有接口包读它 —— agent 只调 tts_volcano.py,拿不到也不需读密钥。异常信息脱敏;check_integrity.py 有专门的密钥防线检查;打包排除密钥文件。 | | 两级时钟 | 帧长用 MP3 容器时长(保音画同步);末块字幕按语音真实结束收尾。 | | 23 种画面风格 | 8 个类别,每种都记录了画布、字阶、时间轴与配色纪律。不用对着空白页从零设计。 | | 封面双方案 | 每条成片附带 16:9 与独立重排的 3:4 封面 —— 不是裁切,裁切会丢掉 57.8% 的画面宽度。 | | 渲染前体检 + QC | lint_frames.py 在渲染前报出契约违规;qc_check.py 查响度、时长漂移、抽帧速览。 | | 结构性离线 | GSAP 内置;浏览器自动探测;ffmpeg 缺失时回退到 imageio-ffmpeg 静态二进制;网络字体被契约禁止。 |


流水线

flowchart LR
    A["主题"] --> B["调研<br/><i>每个数字带出处</i>"]
    B -->     C["narration.json<br/><i>竖线切字幕块</i>"]
    C --> S["tts_setup.py<br/><i>问 TTS 方案 · 配密钥 · 选音色</i>"]
    S --> D["tts_build.py<br/><i>edge-tts / 火山引擎 → MP3 + 词边界</i>"]
    D --> E["timeline_build.py<br/><i>全局轴 + 拼接音轨</i>"]
    E --> F["subs.py<br/><i>subs.json · srt/vtt · beats.js</i>"]
    F --> G["frames/*.html<br/><i>一句一场景,风格取自风格库</i>"]
    G --> H{"lint_frames.py<br/>八条契约"}
    H -->|不过| G
    H -->|通过| I["render_video.mjs<br/><i>逐帧 seek → PNG</i>"]
    I --> J["ffmpeg<br/><i>H.264 + AAC 合成</i>"]
    J --> K[("out/slug.mp4")]
    I --> L["qc_check.py<br/><i>响度 · 漂移 · 抽帧速览</i>"]
    K --> M["cover_build.mjs<br/><i>cover_169.png · cover_34.png</i>"]

    style K fill:#1f6feb,color:#fff
    style H fill:#8957e5,color:#fff
    style M fill:#238636,color:#fff

B() 节拍系统

subs.py 为每个场景生成一份 beats.js,把每块字幕按原文暴露出来,于是画面动画可以直接 锚在吐字时刻上:

tl.fromTo('.card',    { y: 60, autoAlpha: 0 }, { y: 0, autoAlpha: 1, duration: 0.7 }, B('右边卡片'));
tl.fromTo('.verdict', { scale: 0.8 },          { scale: 1, duration: 0.6 },        B('结论句') + 0.2);

B('块文本') 是「这几个字开始被念出」的时刻,Be('块文本') 是念完的时刻。

这是本项目自己的设计,也是让工作方式变掉的那一块:改一次解说词,重跑三条命令,所有场景自行 重排对时。对比帧号硬编码 —— 改一句话就是整片手工重新对位。

兜底写法是被禁止的。 B('x') || 3.2 会把「节拍查不到」藏在一个过期的数字后面。查不到 就应该让构建直接失败 —— 一条对错了时间的视频,比一次构建失败糟糕得多。


画面风格库

不要对着空白页从零设计画面。 23 种风格、8 个类别,每种都记录了画布、字阶、时间轴结构与 配色纪律 —— 完整目录见 references/style-catalog.md。

涵盖:大胆信号卡 / 奢华极简留白 / NYT 编辑级数据图表 / 瑞士网格 / 故障艺术 / 胶片漏光 / 流体 Hero / 品牌 Logo 收尾 / VFX 文字光标 / 社媒竖版(9:16)/ 产品演示等。

分成两类,改编成本差别很大:

  • rich(12 个) —— 单文件 + 纯 CSS @keyframes。seek 渲染器零改动即可驱动;改编 只要三步:换系统字体栈、把底部元素抬出字幕带、填进真实内容。
  • gsap(11 个) —— 多 composition + CDN 加载。不要搬代码。 只取它的视觉 DNA,用 CSS keyframes 重新表达。

一个项目建议轮换 2–4 种风格。8 个场景共用同一张脸会显得单调。


封面双方案

每条成片产出两张互为姊妹、而非裁切关系的封面。从 16:9 居中裁 3:4,1920px 只剩 810px —— 丢掉 57.8% 的画面宽度,任何横跨全宽的标题都会被切掉一半。所以两张共享同一套视觉基因, 但各自重新排一次版:

| 元素 | 16:9(1920×1080) | 3:4(1440×1080) | |---|---|---| | 悖论视觉 | 右侧,左右并置 | 上方,竖排堆叠 | | 钩子 | 左下,两行,≥96px | 下方,三行,≥120px | | 每行字数上限 | 7 字 | 5 字 |

两个尺寸的输出都由 new_project.py 直接生成模板,默认出 2 倍图。完整规则与上传前自检清单: references/cover-guide.md。


疑难排查

| 症状 | 原因 | 处理 | |---|---|---| | 每一帧都是静止首帧,且不报错 | 时间轴没注册到 window.__tl;或 page.evaluate 传了字符串而非函数字面量(Playwright 只求值一次,函数体根本不执行) | 传真正的函数字面量 | | 视频变成 1280×720 | viewport 传给了 browser.launch() —— 它是 context 级选项 | 传给 newPage() | | 封面出成 1 倍图 | 同上,deviceScaleFactor 的孪生坑 | 传 newPage() + screenshot({ scale: 'device' }) | | 数字能渲染但永远不动 | seek 抑制了 onUpdate 回调 | 渲染器已修(pause(t, false));帧里改用 transform 数字卷轴 | | Windows 上 No such file or directory | 非 ASCII 路径 —— Windows 的 ffmpeg 把 UTF-8 当 ANSI 读 | 路径保持 ASCII | | 字幕开始飘 / 位置对不上 | TTS 没返回字级时间戳,subs.py 退回按字数插值(只有一行 stderr 警告) | 看 tts_build 有没有打 ⚠ 未返回字级时间戳;换个受支持的音色(中英文 2.0) | | 火山报 resource ID is mismatched with speaker related resource | speaker 收到了中文显示名而不是音色 ID;或复刻音色配了预置资源 ID | 音色用内置名/ID(接口包会解析);复刻音色配 VOLC_RESOURCE_ID=seed-icl-2.0 | | 火山报 HTTP 401/403 | tts.env 里的 key 不对,或该服务未开通 | 核对 VOLC_API_KEY;tts_setup.py --status 看脱敏状态 | | 火山报 网络不可达 | 本包默认绕过系统代理直连(境内端点) | 确实需要代理时设 VOLC_PROXY=http://127.0.0.1:<port> | | 重跑后字幕整体晚一帧 | 命中缓存时丢掉了首裁量(历史 bug,已修) | 升级到 v1.3.0+;缓存格式已带 lead_cut_sec |

references/lessons.md 是这个仓库里最值钱的文件。 56 条编号记录,每一条都是一个 「成片看着挺正常、其实是错的」的 bug —— 包括它一开始是怎么被误判的。从零开始 debug 之前, 先读它。


适合谁

适合:想成规模地把文章 / 文档 / 某个主题做成带解说的视频;已经在用 AI 编程智能体, 且宁愿用 HTML 描述画面也不想学动效软件;需要可复现的输出;需要离线跑或拒绝按次计费。

不适合:实拍剪辑、真人口播、复刻已有视频;想要图形化拖拽编辑器(画面是代码,这是刻意 选择);想把 React 组件动画作为创作模型 —— 那是参考项目 anything2explainer 的领域。


参考项目思路

html-explainer 的方法论不是凭空来的。它有两处明确的思想来源,两个项目都由不同作者独立 开发,与本项目不是同一作者;本仓库不打包、运行时不依赖它们的任何代码 —— 吸收的是设计规范 与工程经验。

  • Vincentwei1021/anything2explainer (TypeScript / Remotion)—— 「主题进 → 带解说的讲解视频出」。本项目从这条线继承的是 解说与音画同步方法论:词边界字幕、两级时钟、语速标定、QC 判据。 差异:它是 Remotion + React 组件动画;本项目用 HTML/CSS/GSAP + 确定性 seek。

  • nexu-io/html-video(Apache-2.0,Open Design 团队)—— 「在本机把 HTML 变成真 MP4」。本项目从这条线继承的是 23 种画面风格目录, 转写自它的模板设计规范。其中 7 种又可追溯到 MIT 许可的设计作品。 差异:它靠实时录制;本项目靠 seek 逐帧渲染,帧可复现。

本项目自己的部分:确定性 seek 渲染器、B() 节拍锚定、封面双方案,以及 lint_frames.py / qc_check.py 的判据。完整的署名与逐风格对应关系见 THIRD_PARTY_NOTICES.md。

如果你要的是 Re

Truncated for display — read the full file on GitHub.

Related Skills

View on GitHub
GitHub Stars47
CategoryDevelopment
Updated14h ago
Forks8

Languages

Python

Trust signals

92/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

1 low1 info