sph-player —— 视频号播放预览与批量下载(按次付费版)
计费模式
Pay Skill · 按次计费 ¥0.99/次(实际金额以账单 protocol.amount 为准,下单时必须如实告知用户)。
- 一次付费 = 一次技能调用,可覆盖本次调用内解析/下载的多条链接。
- 付费产出物:视频 mp4、音频 mp3、逐字稿 txt、封面 jpg(含解析出的 CDN 直链与预览页)。
- 门禁基于支付宝 AI 按量付费协议(402 → 扫码 → 验付 → 履约确认)。未完成付费时,
四个产出脚本全部输出PAYMENT_REQUIRED并 exit 2 —— 不得绕过门禁免费产出。
能力概览
| 需求 | 实现 | 是否受门禁约束 |
|---|---|---|
| ⓪ 付费门禁 | payment_gate.py 执行支付宝按次付费闭环,生成付费回执 |
—(门禁本身) |
| ① 识别视频号视频 | sph_resolve.py 提取链接 + 多源回退解析 |
✅ 强制 |
| ② 播放预览页 / 截图 | sph_preview.py 生成预览页;sph_snapshot.py 落盘封面 jpg |
✅ 强制(含可下载直链/封面) |
| ③ 下载 mp4/mp3/逐字稿 txt | sph_batch_download.py 批量下载,幂等可续传 |
✅ 强制 |
> 四个脚本都调用同一个 paywall.ensure_paid():回执有效即放行,回执有效期 6 小时,
> 有效期内重复调用不重复扣费。
前置条件
- 付费服务地址:已内置,禁止询问用户。
默认为https://pay.seayl.top/demo/a2m/sph-player(paywall.DEFAULT_RESOURCE_URL)。
可用config.json → payment.resource_url覆盖(自建后端/调试沙箱)。
收款与验付均在技能作者侧后端完成,本技能只需要这一个地址;
技能包内不含任何商户私钥 / sellerId / appId,使用端无需也无法配置收款账户。
付费流程与排错见references/pay_backend_notes.md。 - 买家侧支付 CLI:
%USERPROFILE%\.openclaw-autoclaw\alipay-bot-cli\bin\alipay-bot.exe
(也可在config.json → payment.alipay_bot填绝对路径)。 - 视频号链接格式:
https://weixin.qq.com/sph/<id>(可从整段分享文案中自动提取)。 - 解析源
aido依赖爱豆笔记助手技能(~/.workbuddy/skills/@user_0a46cba7/aido-note-assistant)
的config.json中已配置有效 token,或通过环境变量AIDO_SKILL_DIR指向其他位置。 - Python:任意 3.10+(脚本只用标准库)。
- Windows 沙箱注意:bash 命令前先
export PATH="/c/Windows/System32:/c/Windows:/usr/bin:/bin:$PATH"。
工作流
第 0 步:付费门禁(强制前置,未付费不得解析/下载)
cd <技能目录>/scripts
python payment_gate.py # 完整闭环:probe → pay → poll → complete → ack
python payment_gate.py --check # 仅校验已有回执
python payment_gate.py --dry-run # 仅探测账单(不发起付款,自查配置用)
python payment_gate.py --complete-only --out-shake-no <付款单号> # 已扣款但回执丢失时恢复
Agent 执行要点(照 wechat-article-pipeline 第〇章的成熟模式):
- 收到解析/下载请求后直接跑
payment_gate.py,不要询问服务地址
(已内置);唯一需要用户参与的环节是扫码付款。 - probe 拿到 402 账单后,把
BILL:行里的金额和商品名如实告知用户。 PAY_QR:行输出二维码图片路径与短链——把二维码展示给用户(present_files),
请用户用支付宝扫码;短链作兜底。- 展示二维码后脚本会自动轮询(最多约 6 分钟),不要停下来等用户说"付完了"。
- 全部通过后脚本打印
PAYMENT_OK:并把回执写入
<技能目录>/payment_receipt.json(可用--receipt指定路径)。
回执有效期 6 小时;有效期内再次调用解析/下载不会重复扣费。
踩坑与排错(2026-09-22 按当前 CLI 版本实测复核,改动时务必保持):
| 现象 | 原因与处理 |
|---|---|
PAYMENT_REQUIRED(exit 2) |
尚未付费或回执过期/不匹配,重跑第 0 步 |
content is neither valid JSON nor valid Base64/Base64URL-encoded JSON |
-f 传了整段 HTTP 响应。必须只传 Payment-Needed 头的原始 Base64URL 值(脚本已落盘为 challenge_pn.b64) |
BIZ_ORDER_NOT_FOUND |
complete 用了支付宝交易号。必须用 --out-shake-no <pay 返回的付款单号>;当前 CLI 该字段名是 tradeNo(旧版为 outShakeNo,脚本已兼容) |
SYSTEM_ERROR 系统异常,支付失败 |
账单金额与支付宝平台该服务注册单价不一致(实测唯一判定字段,goods_name/resource_id 都不校验),属作者侧配置问题、重试无用。把账单 amount 反馈给技能作者核对,见 references/pay_backend_notes.md 第三节 |
TRADE_ALREADY_PAID |
订单已付但凭证未回传,不要重复下单;用 --complete-only --out-shake-no <单号> 恢复 |
RESOURCE_REQUEST_FAILED |
付款已完成、服务端交付超时;不要重新付款,稍候用 --complete-only 恢复(服务端幂等) |
| 逐字稿 txt 只有标题 / 没有 mp3 | ASR 仍在排队(后端用标题文案占位 transcript)。脚本已按 asr_queued 自动轮询;若仍超时,在回执有效期内稍后重跑即可补齐——不重复扣费,且会用更长的真实逐字稿覆盖占位稿 |
| 付费地址 404 | 该资源路径尚未在后端注册,见 references/pay_backend_notes.md 第一节(现网 /demo/a2m/sph-player 已注册,返回 402) |
| 用户取消/超时 | 如实终止本次调用,不得跳过门禁继续产出 |
> 轮询拉起链接用的是 payScheme(当前 CLI 返回的是可直接使用的 alipays://... 串,
> 不要对它整体 unquote,否则会破坏内层 %3D/%26)。
第 1 步:识别 + 解析(付费后放行)
cd <技能目录>/scripts
python sph_resolve.py "用户给的全部文本(可含多条链接)" --no-transcript
- 输入可以是整段分享文案,脚本自动提取其中所有
sph/链接并去重。 - 每条输出一行
RESULT:{...}(成功)或FAILED:{...}(失败)。 - 字段:
sph_id / author / title / desc / stats{likes,favorites,forwards,comments} / cover_url / video_url / audio_url / transcript / source。 - ASR 是异步的(重要):逐字稿与音频 mp3 由后端后台转写。排队期间后端会把
标题文案填进transcript字段当占位,只看"transcript 非空"会误判为已就绪。
脚本已改为以顶层asr_queued为准轮询(默认最多 18 次 × 10s),
拿到真实逐字稿与audio_url才返回;实测排队约 2 分钟。 - 只想要视频直链、不需要逐字稿/音频时,加
--no-transcript --no-audio最快。 - 限流保护:后端对连续请求限流(429),脚本内置等待重试;
多条链接时用--interval 12(默认)拉开间隔。
常见失败:
- 解析失败,链接可能无效 → 链接是直播回放/已删除/仅自己可见;换普通短视频分享链。
- HTTP 429 → 请求过密,等 60s 后重试。
- Token 无效(401)→ 引导用户重新配置 aido 技能的 token。
第 2 步:生成播放预览页(含截图)
python sph_resolve.py "<全部链接>" --no-transcript > resolve_out.txt
python sph_preview.py --from-resolve resolve_out.txt --out preview.html
用 present_files 打开 preview.html:每条视频一张卡片,
含封面图、播放按钮(点击即内嵌播放)、点赞/收藏/转发/评论、下载按钮。
落盘截图(供笔记/报告引用):
python sph_snapshot.py --url "<链接>" --cover "<cover_url>" --out-dir <截图目录>
# 若已下载本地 mp4 且装有 ffmpeg,可抽真实视频帧:
python sph_snapshot.py --from-video <本地.mp4> --sph-id <id> --out-dir <截图目录>
截图策略:优先封面图(后端返回 finder CDN JPG,实测稳定可用);
--from-video 时尝试 ffmpeg 抽帧,失败自动回退封面。
第 3 步:批量下载
python sph_batch_download.py "<链接1>" "<链接2>" ... \
--out-dir "C:/Users/Administrator/WorkBuddy/<workspace>/downloads" --audio --cover
--out-dir默认用当前工作区downloads/(每个视频按
<sph_id>_<作者>_<标题>.mp4命名,另附逐字稿 txt)。- 幂等:同名文件已存在即跳过,可反复运行续传。
- 容错:单条失败不中断,最后打印
SUMMARY: total=N ok=X partial/fail=Y。 - 下载走 CDN 直链(自动带
Referer: https://weixin.qq.com/)。 - 若响应头
X-enclen>0且带 decode key,自动用 ISAAC-64 解密
(isaac64.py,移植自开源 WechatSphDecrypt);当前后端返回的直链
X-enclen=0,为未加密 mp4,直接可播可下。
技术说明(references/)
- 解析字段与直链结构:见
references/api_notes.md - 付费流程、¥0.99 定价与排错速查:见
references/pay_backend_notes.md - ISAAC-64 解密算法:见
isaac64.py顶部注释(Go 源:wxianfeng/WechatSphDecrypt)
边界与合规
- 付费门禁是本技能的核心商业逻辑:任何情况下都不得在未完成付费闭环时产出
解析结果或下载文件;--receipt校验不通过一律拒绝。四个产出脚本均已接入门禁。 - 仅处理用户主动提供的分享链接,用于个人保存学习,不用于商业再分发。
- CDN 直链有有效期,解析后应尽快下载。
- 不绕过任何付费/权限墙:内容本身需公开可看(登录可见的直播回放等无法解析)。
- 后端限流是保护机制,不要用并发压测的方式规避;批量场景请保持默认间隔。