blender-motion-state-inspection
AFaffaan-m/ECC278k近 7 天新增 4,046 个 star
Use when asked to make an explainer / walkthrough video (讲解视频、解题视频、例题精讲、微课) for a math problem (数学题, geometry, algebra, functions, motion/行程 problems), from a problem screenshot or text, with Chinese voice-over (GLM-TTS / 智谱 TTS), bilingual zh+en subtitles and hand-drawn canvas animation rendered to MP4.
把一道数学题做成 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、截图里有问题,都不能写"只是警告、不影响"然后继续。修好再往下走。
make_problem_png.py 生成的图),旁白逐条读条件,每读一条就在图上框出那一条。tts 字段只能是能念出来的中文。 不能有阿拉伯数字、= + − × ÷ / ^ √ ∠ △ ∥ ° ( ) 等符号:AC=3 写成 AC等于三,x² 写成 x的平方。字幕 zh 字段保留正常数学写法。--check 会报错拦住。--check 必须显示 未固定读音的生僻字/多音字: 0 且 script errors: 0。多音字的标注写在该字后面:长[cháng]、要[yào]求。不能写成 中点[zhōng](那会把"点"读成 zhōng)。GLM_API_KEY 时先问用户:配置 key(音质最好,推荐),还是用兜底引擎(edge-tts / macOS say,见 reference/glm-tts-setup.md)。不要编造 key、模型名或接口地址,不要把 key 打印出来或写进项目文件夹。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 根目录装一次,所有视频共享。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 引导用户配置(推荐放 ~/.config/math-problem-video/.env,所有目录通用),然后继续。不要去别的项目里找 .env 用,也不要因此换工作目录。 用户没有 key 或不想配:TTS_ENGINE=auto(默认)会自动改用兜底引擎,setup_check.sh 会显示用的是哪个;装 edge-tts 前先征得用户同意。setup_check.sh 输出 ALL OK。cd PROJ && PY build_audio.py --say "你好,我们来看一道数学题。"
WROTE build/say_xxxx.wav 和 voice: ...(edge: / say: 开头 = 兜底引擎)。401/403 = key 错或没余额,告诉用户,不要重试 10 次。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,文字完整(没有 ☒/□ 方框),每个框都恰好罩住对应文字。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 回顾 + 报答案。storyboard.md先读 reference/visual-design.md,再按 template/storyboard.md 的格式给每句旁白写一行:| 幕id 句号 | 旁白要点 | 指 | 动 | 留 | 板书 |。
cd PROJ && PY build_audio.py --check ; cat build/pron_report.txt
ERROR 行:按提示改 script.json(通常是 tts 里有数字/符号,或 anim.js 缺 SC.<id>;第 8 步写完 anim.js 前后者会报错,属正常)。⚠ 多音/生僻 行:按 reference/pronunciation.md 处理:该字后面加 [拼音],或反复出现的词加进 pron.json 的 words,确认默认读音正确的词加进 ok。未固定读音的生僻字/多音字: 0 且 script errors: 0,退出码 0。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。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 的审查清单:没有重叠、没有出界、没有挡住字幕、每句提到的东西都画出来了、数值与解答一致。motion check passed;全部截图检查通过(在回复里逐幕说明你看到了什么)。cd PROJ && PY build_audio.py && PY build_audio.py --asr && node render.mjs stills auto && PY SKILL/scripts/contact_sheet.py .
build/tts/,改了某句只会重新合成那一句。--asr 用智谱语音识别把每句配音转回文字,写入 build/asr_report.txt(结果有缓存)。字母序列对不上的句子标 ✗,退出码 1:修改那句(见 pronunciation.md 的"字母"一节)后重跑这两条命令。报告里的汉字也要扫一遍,发现明显读错的字(不是同音字,也不是 ASR 把"三"写成"3"这种)就按第 7 步处理。mix + srt written;--asr 显示 字母读错的句子: 0(没有 GLM key 时显示 ASR SKIPPED:交付时告诉用户字母读音没有机器核对,列出含点名的句子请用户重点听);截图检查通过。cd PROJ && node render.mjs video 6 # 6 = 并行浏览器页数(不是帧率!帧率固定 30)
WS/<output_name>.mp4 和 WS/<output_name>.srt(WS = 用户的当前目录)。2~3 分钟的视频约需几分钟。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,地址已写在 build_audio.py;只需用户提供 GLM_API_KEY,可选 GLM_VOICE |
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☒ 却没发现 | 审查时放大看文字;make_problem_png.py 已自动换字体 |
用编辑工具改 JSON 后出现弯引号 “,解析失败 | JSON 语法引号必须是英文 ";见 troubleshooting.md |
| 图一次画好,之后每句只多一条线/一个标签,解释全在板子上 | 每句都有"指→动→留";相等就滑过去重合,立体↔俯视用 camTween;render.mjs motion 必须通过 |
| 需要俯视图时在旁边另画一张图 | 同一个 3D 模型 camTween 转到 pitch = π/2 |
| 一句旁白塞三四个知识点 | 一句一个点,画面同步出现一个元素 |
.env、音色、语速、报错处理。引导用户配置时读这个。script.json 格式、幕的设计、数学式子的口语写法对照表。pron.json、数学常见多音字。AFaffaan-m/ECC278k近 7 天新增 4,046 个 star
ANanthropics/skills181k近 7 天新增 1,119 个 star
SHShubhamsaboo/awesome-llm-apps141k近 7 天新增 808 个 star
HAharry0703/MoneyPrinterTurbo130k近 7 天新增 1,722 个 star
PApaperclipai/paperclip101k近 7 天新增 2,948 个 star