下载地址
https://www.zhengdianxue.com/wp-content/uploads/skills/org-pkxr6r79--hengpingdonghua.zip将提示词发送给你的 AI 安装该 skills
请根据 https://skillhub.cn/install/skillhub.md,安装 @org-pkxr6r79/hengpingdonghua。把一份「解说型演示稿」一键录成 16:9 高清横屏演示视频(1920×1080、30fps、无音轨),并附「每页从第几秒开始」的配音对时表 ——B 站、公众号、电脑投影直接用,配音在剪映里加。 当用户说「做成视频 / 录成视频 / 横屏视频 / 做一版发到 B 站或公众号 / 投影用 / 电脑上看」,或手上已有一份解说型演示稿想变成 MP4 时使用。
自带完整链路:稿子 HTML → 派生录制版(页间交叉淡入 + 跳页接口)→ 逐页结构自检 → 无头 Chrome 录屏 → 按帧时间戳还原真实时长 → 生成配音对时表。画面干净:无鼠标、无窗口边框,节奏按稿子设计,不是普通录屏。 不适用于竖屏 / 微信视频号 / 手机信息流(那是 explainer-deck-video-portrait);只要可翻页网页稿、不录视频(那是 explainer-deck-source)。
阅读全文 (展开查看完整说明)
概述
演示稿 → 横屏 16:9 视频
把一份能翻页的 HTML 演示稿录成 1920×1080 / 30fps / 无音轨 的 MP4,并给出一张「每页从第几秒开始」的对时表,供在剪映里配音卡点。
不是屏幕录制:脚本用无头 Chrome 逐页切换 + CDP screencast 抓帧,再按每帧的真实时间戳重建时长,最后 ffmpeg 编码。所以画面干净、没有鼠标、没有窗口边框,节奏也是设计好的。
本技能为 SkillPay 付费技能,按次计费(¥0.1/次,微信支付)。支付成功后执行完整录制流水线并交付 MP4 + 对时表。
输入参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| html_deck | string | 二选一 | 已有可翻页的稿子 HTML(本地路径或 URL) |
| topic | string | 二选一 | 要讲什么、给谁看(无现成稿子时用,执行方按 explainer-deck 系列先出稿再录) |
| resolution | string | 否 | 输出分辨率,默认 1920x1080(必须 16:9,否则露背景色) |
| skip_pages | string | 否 | 要跳过的页号(逗号分隔,1 起算,如 19,20) |
| title | string | 否 | 视频标题(用于对时表) |
html_deck与topic至少提供一个。都没给时先问清「讲什么、给谁看、有没有现成材料」,不要凭空造内容。
输出协议
- 200 OK:支付成功且录制完成,返回 MP4 视频、配音对时表及访问方式。
- 402 PAYMENT REQUIRED:需要支付。响应头
WeixinPay-Required携带 paymentCode,X-Out-Trade-No携带订单号。调用方应引导用户完成微信支付授权后,携带 paymentCode 重试。 - 4xx:请求错误或业务异常,见下表。
| code | HTTP | 含义 | 处理 |
|---|---|---|---|
| BAD_REQUEST | 400 | 参数缺失或格式错误 | 检查必填参数(html_deck/topic 至少其一)后重试 |
| NOT_PAID | 402 | 未支付或未携带 paymentCode | 完成支付后重试 |
| PAY_EXPIRED | 402 | 订单过期 | 重新下单 |
| UPSTREAM_ERROR | 502 | 无头 Chrome / ffmpeg / 依赖安装等上游异常 | 检查环境后重试 |
| INTERNAL_ERROR | 500 | 服务内部错误 | 稍后重试 |
付费前置检查(第 1 项核心特征 · 触发条件)
- 插件检查(必做):执行调用前,Agent 先检查
weixinpay支付插件(weixin_pay 能力)是否已安装并可用;若未安装/不可用,提示用户先安装 weixinpay 插件后重试,不得跳过支付直接执行业务。 - 输入必填项满足二选一(html_deck 或 topic)。
- 执行环境:本技能需要 Node.js + Python + ffmpeg + 无头 Chrome(首次运行需安装
playwright-core/ffmpeg-static依赖,约 80MB,见下「前置」)。环境缺失时如实说明,不得降级交付。 - 用户只说「做成视频」、没说画幅 → 先问一句发哪里(横屏/竖屏),画幅猜错要全部重做。
调用流程
- 发起请求
POST https://pay.gkyzcloud.com:8443/create_order/explainer-deck-video-landscape(body 含必要参数)。 - 收到
402 PAYMENT REQUIRED+WeixinPay-Required+X-Out-Trade-No→ 向用户申请微信支付授权(paymentCode = WeixinPay-Required 的值)。 - 用户完成支付后,携带 paymentCode 重试原请求。
- 支付校验通过后执行完整录制流水线(见「五步流水线」),产出 MP4 + 对时表。
- 返回 200 + 视频与对时表访问方式。
超时与取消
- 本任务为长时录制任务:每页约 4.8s 录屏 + ffmpeg 编码,20 页左右全程约 2–4 分钟。执行期间应分段反馈进度(出稿 → 自检 → 录屏 → 编码 → 抽帧核对),不得让用户干等。
- 支付订单有有效期,过期未支付须重新下单(PAY_EXPIRED)。
- 用户可在任务开始后 5 分钟内取消;取消后已完成的工作不重复计费。
一、前置:装一次依赖
NODE_DIR=$(ls -d ~/.workbuddy/binaries/node/versions/*/ | tail -1) # 目录名会变,别写死
mkdir -p <工作目录>/.video-tools && cd <工作目录>/.video-tools
"$NODE_DIR/npm.cmd" install playwright-core ffmpeg-static --no-fund --no-audit --ignore-scripts
# ffmpeg-static 的官方 release 在国内 502,从镜像取二进制:
curl -L -o node_modules/ffmpeg-static/ffmpeg.exe
https://registry.npmmirror.com/-/binary/ffmpeg-static/b6.1.1/ffmpeg-win32-x64装完确认两个东西在位:node_modules/playwright-core(目录)与node_modules/ffmpeg-static/ffmpeg.exe(约 80MB)。若本机已装过(例如 蒸馏skill/.tools/deck-video),直接复用,不要重装。
Chrome 不用装依赖,脚本自己找(先看 PLAYWRIGHT_CHROMIUM_PATH,再找默认安装位置)。
二、五步流水线
设 $A = 本 skill 的 assets 目录,$JOB = 本次工作目录,$FF = ffmpeg 全路径,$NODE = node 全路径。
第 0 步 · 拿到稿子 HTML(没有才做)
若用户已经给了能翻页的稿子 HTML,跳到第 1 步。否则先出稿:
- 骨架用
explainer-deck-spine(是什么→为什么→代价→换语境→收尾),
配图用 explainer-deck-diagrams,外壳配色用 explainer-deck-visual-system;
- 以
$A/解说型演示稿模板.html为基底改文字最省事(它已含 9 种图式组件与全部外壳); - 稿子里不要有「模板说明 / 使用指引」这类页,或记下它们的页号,第 2 步要跳过。
出稿后先自检,别带着布局塌陷去录:
"$NODE" "$A/check-deck.mjs" "$JOB/稿子.html" "$JOB/shots" 1920 1080必须 6/6 通过(逐页不溢出白卡、装饰不压正文、章节号单调)。有 FAIL 就先修稿。
第 1 步 · 派生录制版
python "$A/make_landscape.py" "$JOB/稿子.html" # → $JOB/稿子-横屏.html只加三样与版面无关的东西:页间 0.26s 交叉淡入、window.__deck 跳页接口、隐藏 .pip/.subtitle(CAM 圆圈与红底大字幕,交给剪映加)。版式一个字不动。
第 2 步 · 录屏
DECK_VIDEO_MODULES="$JOB/.video-tools/node_modules"
"$NODE" "$A/record-deck.mjs" "$JOB/稿子-横屏.html" "$JOB/frames" 4800 "19,20" 1920 1080参数:HTML、帧目录、每页停留毫秒、要跳过的页号(1 起算)、宽、高。跑完打印每页起始时间并发 pages.json / meta.json / timing.json。
DECK_VIDEO_MODULES必须给 —— 依赖(80MB)装在别处,而 ESM 的import只从脚本所在目录向上找
node_modules,指不到就会报 "Cannot find package"。也可以用
PLAYWRIGHT_CHROMIUM_PATH指定 Chrome;不给就自动找默认安装位置。
- 分辨率必须 16:9。横屏舞台逻辑尺寸是 1280×720,viewport 给 1920×1080 时缩放正好 1.5,
画面铺满不留黑边;换成非 16:9 会露出背景色。
- 有数字滚动动画的页,停留别低于 4000ms。
- 重录前先
rm -rf "$JOB/frames"—— 脚本覆盖同名帧但不会删旧帧,
新录制页数变少时会残留旧的高编号帧,混进视频里。
第 3 步 · 合成 MP4
"$NODE" "$A/mkvideo2.mjs" "$JOB/frames" "$JOB/视频.mp4" "$FF"它只生成 concat.txt 并打印 ffmpeg 命令,不自己调 ffmpeg(原因见下「环境坑」第 3 条)。把它打印的命令贴到 shell 里跑:
"$FF" -y -loglevel error -nostats -f concat -safe 0 -i "$JOB/frames/concat.txt"
-r 30 -c:v libx264 -crf 18 -preset slow -pix_fmt yuv420p -movflags +faststart -an "$JOB/视频.mp4"-an = 不要音轨。验证:"$FF" -i "$JOB/视频.mp4" 看 Duration 与 1920×1080。
第 4 步 · 出配音对时表
python "$A/make_timing_table.py" "$JOB/frames" "$JOB/稿子-横屏.html" "$JOB/对时表.md"
--title "演示视频" --hold 4800 --frame-size 1920x1080 --mp4 "$JOB/视频.mp4" --ffmpeg "$FF" --skip 19,20第 5 步 · 交付前抽帧核对(别省)
按 pages.json 的每页起始时间抽帧,拼成一张总览图,逐格确认「顺序对、无重页漏页、无黑边」:
"$FF" -y -loglevel error -ss 2 -i "$JOB/视频.mp4" -vf "fps=1/<每页秒数>,scale=320:180,tile=6x3"
-frames:v 1 "$JOB/contact.jpg"单页抽帧号 ≈ (该页起始秒 + 1.5) × 30,用select='eq(n,N1)+eq(n,N2)+...' 精确抽更可靠。同时抽一帧页间转场的中点,能看到两页文字叠加就说明交叉淡入生效(而不是硬切)。
三、五个必须知道的环境坑
- screencast 只在画面变化时给帧。 一页静止 4.8 秒期间可能一帧都不给。
所以每帧都记了时间戳,mkvideo2.mjs 按「下一帧 − 本帧」写 duration。直接用帧序号拼成恒定帧率的话,静止的 4.8 秒会被压成 0.1 秒,全片节奏报废。
- 最后一页的停留会整段丢掉。 末帧停在「最后一页刚出现」那一刻,之后静止期没有新帧。
所以脚本单独记了录制结束时间(timing.json),倒推末帧该持续多久。
- 本机 Node 调不了子进程。
spawnSync连cmd.exe都报EBUSY
(与中文路径无关,复制到 C: 下同样失败;但 playwright 启动 Chrome 正常,所以录屏不受影响)。→ ffmpeg 一律由 shell 执行,别指望脚本自己调。(Python 的 subprocess 不受此限制。)
- ffmpeg 这个构建不支持 glob。
-pattern_type glob会报 "globbing is not supported"。
拼 contact sheet 要先把文件复制成 s01.jpg / s02.jpg … 再用 -i "s%02d.jpg",或用 select='eq(n,N)...' 按帧号抽。
--compact-last之类的压紧手段只对内容密的页有用。 如果稿子末尾是内容很密的说明页,
而它又要进视频,别硬压 —— 拆页更体面;横屏比竖屏宽,通常不需要压紧。
四、验收标准(交付前逐条过)
check-deck.mjs6/6 通过(在对派生后的 HTML 上跑,画幅 1920 1080)- 视频
1920x1080 / 30fps / 无音轨,时长 ≈页数 × 4.8s + 1.4s - 抽帧总览图:格数 = 录制页数,每格内容互不相同、顺序与稿子一致、无黑边
- 抽帧能证明页间是交叉淡入而非硬切
- 对时表里每页的起始时间与抽帧结果吻合(时间码对不上就是
pages.json没用上)
五、边界与判停
- 用户只说「做成视频」、没说画幅 → 先问一句:「发哪里?手机竖屏(视频号/抖音)还是
电脑、投影、横屏(公众号/B站)」。画幅决定了整套版式,猜错要全部重做。(本项目用户看过两版后说过「还是横屏好看」,但不代表每次都要横屏 —— 还是要问。)
- 用户要竖屏 / 视频号 / 手机上看 → 转
explainer-deck-video-portrait,别用本 skill 硬缩横屏
(竖屏是重排版式,不是缩放;直接缩会在手机上一半屏幕是空的)。
- 用户只要一份能翻页的网页稿、明确不要视频 → 转
explainer-deck-source,
直接交付 assets/解说型演示稿模板.html,不要再讲录制流程。
- 用户要的是配音(人声讲解)→ 本 skill 只出无音轨画面,配音在剪映里做;
若用户要我配旁白,先确认是否允许用语音合成。
- 用户没给稿子、也没给内容 → 先问清「讲什么、给谁看、有没有现成材料」,不要凭空造内容。
六、assets 清单
| 文件 | 作用 |
|---|---|
解说型演示稿模板.html | 稿子基底(20 页示例 + 9 种图式组件),改文字即出新稿 |
make_landscape.py | 派生横屏录制版(补淡入与跳页接口,版式零改动) |
record-deck.mjs | 无头 Chrome 逐页录屏,产出帧 + pages.json + timing.json |
mkvideo2.mjs | 按帧时间戳生成 concat.txt 并打印 ffmpeg 命令 |
check-deck.mjs | 逐页结构自检 + 截图(零依赖 CDP) |
make_timing_table.py | 生成配音对时表 |
怎么用.md / 怎么重新录.md | 给人看的说明 |
版本历史
| 版本 | 日期 | 变更 |
|---|---|---|
| 1.0.0 | 2026-10-08 | SkillPay 付费改造版:frontmatter 补 name + slug/displayName/version,新增计费与支付头信息(¥0.1/次)、付费前置检查(weixinpay 插件检查)、输出协议(200/402/4xx)、调用流程、超时与取消;原免费版全部能力与脚本保留不变 |