使い方
- インストールコマンドをコピーし、自分の環境へ導入する前にソースを確認します。
- 必要なツール、認証情報、対応環境を原文で確認します。
- 入力と成果物を指定し、出力を資料と照合します。
npx skills add https://github.com/wy51ai/edulab --skill edu-math-video開始前の確認
- 導入にはモデル契約、API枠、ファイルへのアクセス許可は含まれません。
- スター数や導入数は活動の指標であり、独立した品質・安全性試験ではありません。
見出し、例、コード、表、リンク、参照画像を含む原文を表示しています。
数学题讲解视频 (edu-math-video)
把一道数学题做成 16:9、1920×1080、带中文配音 + 中英双语字幕 + 手绘笔记本风格动画的 MP4。
流水线(每个视频一个文件夹):
script.json ──build_audio.py──► build/timeline.json + build/mix.wav + ../<name>.srt
(旁白) (GLM-TTS + 合成音乐) │
anim.js + engine.js ◄─────────────────────────┘ (按旁白时间点驱动动画)
└──node render.mjs video──► ../<name>.mp4核心原则:画面跟着旁白走,而且图会"讲题"。 每句旁白,图上都有一个动作把这句推理演出来(线段滑过去重合、三角形叠上去、相机转到俯视、动点移动……),不是只多出一条线、一个标签。每个动画都用"第 k 句旁白开始的时刻"S.at(k, f) 定时,绝不写死秒数。
本技能自带全部代码,不要从别的项目复制文件:
template/:可直接运行的完整示例项目(直角三角形斜边中线题)。engine.js是通用引擎(不改),anim.js/script.json/episode.json/problem.png是每道题都要重写的。shared/pron.py+shared/pron.json:读音控制(GLM-TTS 没有 SSML/拼音输入)。examples/cone-parallel/:立体几何完整示例(anim.js + storyboard.md + script.json):相机斜视↔俯视、侧面展开成扇形、内错角旋转、平面平移。做立体几何、圆、多问题时先读它。scripts/:new_video.sh(建项目)、setup_check.sh(查环境)、make_problem_png.py(文字题→图片+高亮框)、problem_boxes.py(截图→高亮框坐标)、contact_sheet.py(截图拼图审查)。
下文 SKILL = 本文件所在目录,WS = 用户当前所在的目录(你的工作目录,`$PWD`):视频文件夹建在这里,mp4/srt 也输出到这里。不要因为别的目录(包括本技能所在的项目)已经有 `.env`、`node_modules`、`pron.json` 就把 WS 换过去,缺什么由 new_video.sh 和第 2 步补齐。PROJ = 本视频文件夹,PY = setup_check.sh 报告的 python(macOS 上一般是 /usr/bin/python3;PATH 里的 python3 可能没有 numpy)。
必须遵守的规则
退出码不是 0 就是没完成。 --check 退出码 1(哪怕只剩一个 ⚠ 多音字)、motion 退出码 1、截图里有问题,都不能写"只是警告、不影响"然后继续。修好再往下走。
- 严格按下面 10 步顺序做,每步的"通过标准"满足了才能进入下一步。 不要跳步,不要"最后一起检查"。
- 先讲清楚题目。 视频第一幕必须展示原题图片(截图或
make_problem_png.py生成的图),旁白逐条读条件,每读一条就在图上框出那一条。 - `tts` 字段只能是能念出来的中文。 不能有阿拉伯数字、
= + − × ÷ / ^ √ ∠ △ ∥ ° ( )等符号:AC=3写成AC等于三,x²写成x的平方。字幕zh字段保留正常数学写法。--check会报错拦住。 - 读音必须固定。 调 TTS 之前
--check必须显示未固定读音的生僻字/多音字: 0且script errors: 0。多音字的标注写在该字后面:长[cháng]、要[yào]求。不能写成中点[zhōng](那会把"点"读成 zhōng)。 - API Key 只能由用户提供。 缺
GLM_API_KEY时先问用户:配置 key(音质最好,推荐),还是用兜底引擎(edge-tts / macOSsay,见 reference/glm-tts-setup.md)。不要编造 key、模型名或接口地址,不要把 key 打印出来或写进项目文件夹。 - 所有画面内容在 y ≤ 860 以内(y≈914~1044 是字幕框)。图形放左半边 x 60~900,推导文字写在右边的横线板
board()上。 - 先写分镜,再写动画。
storyboard.md给每句旁白规划"指/动/留",按 reference/visual-design.md 的动作表选动作;node render.mjs motion必须通过。 - 先预览再花钱。 用
--preview+stills auto检查版面,没问题再跑真正的 TTS。 - 看图验证。 每次渲染截图后都要打开
build/sheet.png亲眼检查(用读图工具),不能只看命令有没有报错。汇报时写你实际看到了什么,不要凭印象全部打勾。 - 不要修改 `engine.js`,除非用户要求换风格;需要新图形就在
anim.js里写函数。 - 不要把 `node_modules`、`package.json
复制进视频文件夹**,依赖在WS` 根目录装一次,所有视频共享。
11 个步骤
第 1 步:弄清题目,自己先把题解对
- 拿到题目文字(有截图就先读图)。先自己完整解一遍并验算,写下:已知条件清单、所求、关键思路(1~2 个)、每一步计算、最终答案、验算方法。
- 答案不确定或题目看不清时,问用户,不要猜。
- 通过标准: 你能用 3~6 个"幕"讲完,每一幕一句话说清目的;答案已验算。
第 2 步:建项目、查环境
bash SKILL/scripts/new_video.sh "$PWD" <ascii_folder_name> # WS 就是当前目录
bash SKILL/scripts/setup_check.sh WS/<ascii_folder_name>new_video.sh会把pron.py/pron.json链接到技能自带的共享词表,并在找得到时把node_modules链接到已有安装(不复制);找不到才需要在WS下npm install。python 包用PY -m pip install --user numpy requests pypinyin pillow。new_video.sh报ERROR: ... is where the skill is installed说明你把 WS 设成了技能所在的项目,改用当前目录。- 默认音色是
chuichui(锤锤),用户可以在.env里用GLM_VOICE换。 - 缺
GLM_API_KEY:停下,按 [reference/glm-tts-setup.md](reference/glm-tts-setup.md) 引导用户配置(推荐放~/.config/math-problem-video/.env,所有目录通用),然后继续。不要去别的项目里找 `.env` 用,也不要因此换工作目录。 用户没有 key 或不想配:TTS_ENGINE=auto(默认)会自动改用兜底引擎,setup_check.sh会显示用的是哪个;装 edge-tts 前先征得用户同意。 - 通过标准:
setup_check.sh输出ALL OK。
第 3 步:测试 TTS(验证 key 和音色)
cd PROJ && PY build_audio.py --say "你好,我们来看一道数学题。"- 成功会打印
WROTE build/say_xxxx.wav和voice: ...(edge:/say:开头 = 兜底引擎)。401/403 = key 错或没余额,告诉用户,不要重试 10 次。 - 第一次给这个用户做视频时,把这个 wav 路径告诉用户试听,确认音色(音色表见 glm-tts-setup.md)。
- 通过标准: 生成了 wav。
第 4 步:准备题目图片 problem.png 和高亮框
二选一(细节见 reference/animation.md):
- 只有文字:
PY SKILL/scripts/make_problem_png.py --text "完整题目" --mark "条件1" "条件2" ... "所求" --out PROJ/problem.png,它直接输出srcW/srcH/boxes。 - 有截图:复制到
PROJ/,必要时problem_boxes.py crop裁掉无关部分并存为problem.png;然后problem_boxes.py grid出坐标网格图,读出每个条件的像素框;再problem_boxes.py check画框确认。 - 把尺寸和框填进
anim.js顶部的PROBLEM。 - 通过标准: 你打开了
*.preview.png或*.check.png,文字完整(没有 ☒/□ 方框),每个框都恰好罩住对应文字。
第 5 步:写 episode.json 和 script.json
按 reference/script-writing.md 写。要点:
episode.json:title(视频标题)、output_name(输出文件名,如斜边中线_Median_to_Hypotenuse)、pop_scenes(要加"啵"音效的幕)。script.json:幕的数组,每幕{"scene": "英文id", "lines": [{"zh","tts","en"}, ...]}。第一幕intro读题,最后一幕outro回顾 + 报答案。- 每句旁白 ≤ 36 个汉字宽(否则字幕折两行),一句只讲一件事。
- 通过标准: JSON 合法;每一幕的 id 都有计划好的画面。
第 6 步:写分镜 storyboard.md
先读 [reference/visual-design.md](reference/visual-design.md),再按 template/storyboard.md 的格式给每句旁白写一行:| 幕id 句号 | 旁白要点 | 指 | 动 | 留 | 板书 |。
- "指":这句提到的元素怎么点亮。"动":图上一个体现推理的动作,从动作表里选(相等→复制滑过去重合,全等→三角形叠上去,立体↔平面→相机转动,求长度→数字计数……)。"留":动作后留下的标记。
- 除第一幕和最后一幕外,"动"不能空,也不能只写"出现/显示"。每幕至少一个连续运动。
- 先想清楚:只看图、不看板子,观众能不能看懂这一步为什么成立?不能就换动作。
- 先在 storyboard.md 顶部写图形清单:题目里所有的点、线段、平行/垂直/中点关系、已知长度,全部要画出来,位置按数据计算。
- 通过标准: 每句都有一行;图形清单完整;你能说出每一幕里"最能让人看懂"的那个动作。
第 7 步:读音与脚本检查,修到 0
cd PROJ && PY build_audio.py --check ; cat build/pron_report.txtERROR行:按提示改script.json(通常是 tts 里有数字/符号,或 anim.js 缺SC.<id>;第 8 步写完 anim.js 前后者会报错,属正常)。⚠ 多音/生僻行:按 reference/pronunciation.md 处理:该字后面加[拼音],或反复出现的词加进pron.json的words,确认默认读音正确的词加进ok。- 通过标准:
未固定读音的生僻字/多音字: 0且script errors: 0,退出码 0。
第 8 步:写 anim.js
按 storyboard.md 逐句实现,API 见 reference/animation.md。先通读 template/anim.js(示例)再动手,结构保持一致:
PROBLEM(第 4 步的数据)、TAGS(每幕左上角标签)、图形函数(如fig(st))、SC.<id> = (lt, S) => {...}(每幕一个)。- 每个元素的出现时间 = 旁白提到它的时刻:
S.P(S.at(k, f), 时长)。 - 每句:
glow(..., bump(lt, at(k)))点亮提到的元素 → 分镜里的动作(slideSeg、movePoly、camTween、动点、countTo…)→ 留下标记。 - 右侧
board()+bl(行号, 文字, S.at(k, f), lt)逐行写推导(与图同色),最后stamp()盖章给答案。 - 通过标准:
PY build_audio.py --check无 ERROR。
第 9 步:免费预览:动作检查 + 版面检查
cd PROJ && PY build_audio.py --preview && node render.mjs motion && node render.mjs stills auto && PY SKILL/scripts/contact_sheet.py .motion在每句里取 6 帧,比较左半边图形区的变化:STATIC(没变化)必须修;每幕至少一句MOVE。不通过就回到分镜换更好的动作,不要只加一个无意义的晃动来凑数。stills auto在每句旁白快结束时截一帧(此时这句该出现的东西都应在画面上)。命令输出FAILED: page error说明 anim.js 有 JS 错误,先修。- 打开
build/sheet.png(多于 12 张时是sheet_1.png、sheet_2.png…)逐张检查,对照 reference/animation.md 的审查清单:没有重叠、没有出界、没有挡住字幕、每句提到的东西都画出来了、数值与解答一致。 - 有问题 → 改 anim.js → 重跑本步。
- 通过标准:
motion check passed;全部截图检查通过(在回复里逐幕说明你看到了什么)。
第 10 步:真正生成配音,自动听写核对,再检查一次画面
cd PROJ && PY build_audio.py && PY build_audio.py --asr && node render.mjs stills auto && PY SKILL/scripts/contact_sheet.py .- TTS 按文本缓存在
build/tts/,改了某句只会重新合成那一句。 --asr用智谱语音识别把每句配音转回文字,写入build/asr_report.txt(结果有缓存)。字母序列对不上的句子标 ✗,退出码 1:修改那句(见 pronunciation.md 的"字母"一节)后重跑这两条命令。报告里的汉字也要扫一遍,发现明显读错的字(不是同音字,也不是 ASR 把"三"写成"3"这种)就按第 7 步处理。- 真实时长与预览不同,重新看一遍 sheet。
- 通过标准: 打印
mix + srt written;--asr显示字母读错的句子: 0(没有 GLM key 时显示ASR SKIPPED:交付时告诉用户字母读音没有机器核对,列出含点名的句子请用户重点听);截图检查通过。
第 11 步:渲染视频并交付
cd PROJ && node render.mjs video 6 # 6 = 并行浏览器页数(不是帧率!帧率固定 30)- 输出
WS/<output_name>.mp4和WS/<output_name>.srt(WS = 用户的当前目录)。2~3 分钟的视频约需几分钟。 - 交付时告诉用户:mp4/srt 路径、时长、各幕内容;说明你无法听音频,请用户试听读音,特别列出你标注过读音的字。用户反馈读错时:加到
pron.json或行内标注 → 再跑第 10、11 步(只会重合成改过的句子)。
常见错误(真实发生过)
| 错误做法 | 正确做法 |
|---|---|
当前目录没有 .env/node_modules,就把项目建到有这些东西的别的目录(例如技能所在的项目) | WS 永远是用户当前目录;缺依赖由 new_video.sh 链接,缺 key 请用户配置 ~/.config/math-problem-video/.env |
| 从别的视频文件夹(化学 chem 等)复制代码 | 用 new_video.sh 从本技能 template/ 建项目 |
编造 GLM_MODEL=glm-4-voice、api.zhipuai.cn 等配置 | 模型只有 glm-tts,地址已写在 buildaudio.py;只需用户提供 `GLMAPIKEY`,可选 `GLMVOICE` |
node render.mjs video 24 以为是 24fps | 参数是并行数;预览版面用 stills auto,不要反复渲染整段视频 |
中点[zhōng] | 标注只作用于紧挨着的前一个字:中[zhōng]点(其实"中点"不需要标) |
tts 里写 AC=3、60 − 7t、x² | AC等于三、六十减七t、x的平方 |
| 题目截图随便放在 (50,50) 400×400 | 用 PROBLEM + problemCard() 自动适配到标题下方的卡片里 |
用绝对秒数定时 if (lt > 12.5) | S.at(k, f):第 k 句开始后 f 比例处 |
| 渲染完不看画面就交付 | 每次都看 build/sheet.png |
tts 里手动写 C、O 或 C,O 来分开字母 | 不用管:pron.py 自动把相邻字母拆成 C O(实测逗号、顿号会多出停顿) |
--check 还有 ⚠ 就调 TTS | 修到 0;否则会花钱合成出错误读音 |
为了"保险"把常见词都加进 pron.json 或行内标注 | 只标会读错的字;替换成同音字会破坏断句(直搅三搅形),pron.py 已经只在上下文会读错时才替换 |
| 一个分句二十多个字不加标点 | 在换气处加逗号,分句 ≤ 18 字(--check 会 warn),否则 TTS 自己在词中间停 |
题目图片里 x² 显示成 x☒ 却没发现 | 审查时放大看文字;makeproblempng.py 已自动换字体 |
用编辑工具改 JSON 后出现弯引号 “,解析失败 | JSON 语法引号必须是英文 ";见 troubleshooting.md |
| 图一次画好,之后每句只多一条线/一个标签,解释全在板子上 | 每句都有"指→动→留";相等就滑过去重合,立体↔俯视用 camTween;render.mjs motion 必须通过 |
| 需要俯视图时在旁边另画一张图 | 同一个 3D 模型 camTween 转到 pitch = π/2 |
| 一句旁白塞三四个知识点 | 一句一个点,画面同步出现一个元素 |
参考文件
- reference/glm-tts-setup.md:智谱 GLM-TTS 注册、API Key、
.env、音色、语速、报错处理。引导用户配置时读这个。 - reference/script-writing.md:
script.json格式、幕的设计、数学式子的口语写法对照表。 - reference/pronunciation.md:读音控制原理、标注语法、
pron.json、数学常见多音字。 - reference/visual-design.md:讲解动画怎么设计:指→动→留→连、推理→动画动作表、立体转俯视、圆锥展开、分镜格式。写分镜前必读。
- reference/animation.md:engine.js API、场景写法、版面坐标、几何/函数/立体/行程题画法、审查清单。
- reference/troubleshooting.md:报错与处理。


