视频分发助手 · Video Publisher
SkillMediaPublish local videos to WeChat Channels or Bilibili via the logged-in creator dashboard, gated by media pre-checks, description source freezing, field read-back, cover safe-zone checks, final draft confirmation, and list read-back. Use when users ask to publish, draft, schedule, or check a video pos
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the 视频分发助手 · Video Publisher skill
What this skill tells your AI
The instructions your AI receives, as published by lovstudio/skills in skills/media-publisher/SKILL.md and read by ahel’s review.
只操作平台自己的创作者后台可见网页。把页面当作动态界面:每一步重新读取当前页面, 按语义定位控件,不依赖历史 CSS 选择器、旧句柄或坐标。
平台路由
默认依次发布到微信视频号,再发布到 B 站,平台队列为
[wechat-channels, bilibili]。用户只说「发布」「发出去」且没有指定平台时,直接采用这份
默认队列,不再泛问发布目的地。
- 当前请求明确指定平台时,仅处理指定的平台;明确指定顺序时按该顺序执行。条目链接或
BV 号已能确定平台的
status请求,只查询该条目,不扩展到默认双平台队列。 - 选择两平台但未另指定顺序时,先完成视频号本次动作并回读列表状态,再进入 B 站流程。 视频号出现阻塞时先处理并报告具体阻塞,不自行跳过它、提前改发 B 站。
- 素材、账号或必要字段缺失时,先按本 Skill 的输入和预检流程自行查明;只有确实无法解决 的具体缺项才询问,不把缺项重新解释成平台选择问题。平台限制、DOM 写法和状态分别核验。
| 平台 | --platform | 入口 | 结构 | 页面细节 | 平台约束 |
|---|---|---|---|---|---|
| 微信视频号 | wechat-channels | https://channels.weixin.qq.com/platform/post/create | wujie 微前端 + shadow DOM | 创建页结构 | 视频号约束 |
| Bilibili | bilibili | https://member.bilibili.com/platform/upload/video/frame | 普通 Vue 应用 | 投稿页结构 | B 站约束 |
四条会反复咬人的平台差异,先记住再动手:
- 可逆性不同:视频号发布后不可撤改;B 站稿件投出后可
?type=edit&bvid=改标题、 简介、标签、封面、合集,但改完必须重新点「立即投稿」。终稿确认门禁两边都走, 只是报告口径要跟着变,不要把 B 站的错发渲染成灾难。 - 硬限制差一个数量级:视频号 4 GiB / 2 小时,B 站 16 GB / 10 小时。拿一边的默认值
去卡另一边就会得到假结论,所以脚本一律显式传
--platform。 - 写值方式完全不同:视频号的描述是 contenteditable、话题必须由平台按钮生成; B 站的输入框要用原生 setter,简介是 Quill 实例。不要互相套用。
- 控件类名一律从 page-anatomy 抄,不许猜:两边都是自研组件库(视频号 wujie +
shadow DOM,B 站
data-v-*scoped CSS)。套 antd 或通用猜测(.ant-select-*、[role="combobox"]、.choose-btn、.category-item)一个都命中不了,而且查不到 不报错,表现为「点了没反应」,极易被误读成时机未到而空等几轮。填任何字段前 先打开该平台的 page-anatomy 对一遍选择器表——2026-08-18 EP.03 就是跳过这一步, B 站的分区、合集、封面三项全填不进去,最后由用户手填。
平台成片映射门禁
平台允许某种画幅,不代表本期就该选那一版。打开发布页前,先从 Creator 交付报告、平台文件名、
Composition 或本期清单确定本期目标平台对应的已批准成片:例如本期明确有
Episode-Horizontal 与 Episode-Vertical,且竖版文件名为 wechat-channels 时,B 站应先导出
横版平台 MP4,不能拿竖版“先发了再说”。Studio 里的 Composition 和 review-ready 预览都不是
可上传文件;缺少目标平台 MP4 时,状态记为 blocked-on-platform-variant 并交回
lov-media-creator 渲染、解码和质检。
预检用两层硬门禁:
python3 $SKILL_DIR/scripts/check_video.py PLATFORM_MP4 \
--platform bilibili --expected-orientation horizontal --json
- 文件名明确含另一平台标识(例如 B 站任务选中
wechat-channels)时默认失败;只有用户明确要求 跨平台复用,才可加--allow-cross-platform-name。 --expected-orientation来自本期交付契约,不从“B 站一定横版”之类平台刻板规则擅自推断; B 站本身支持竖版,但项目已批准横版时传入竖版必须失败。- 用户可在提交前改选平台文件或明确覆盖画幅;任何覆盖都要重跑预检并写进终稿字段表。
两个平台共用的部分只有:浏览器工作流(helper 签名、 控制权、任务空间生命周期)、发布门禁清单、 重压方案、视频描述结构。
Triggers
Activate when
- 用户要求把本地视频发布到微信视频号或 B 站,或保存成草稿。
- 用户要求安排定时发布、核验发布状态,或 publish a video to Bilibili / video channels。
- 用户要求基于本会话上一版内容重发同一个本地视频。
Do not activate when
- 用户只要求发布微信公众号文章或调用公众号接口。
- 用户只要求本地媒体预检或转码,不涉及平台页面发布。
- 用户要求剪辑、渲染或生成视频素材本身(那是
lov-media-creator的职责)。
读取输入
开始前取得以下输入:
- 必填:按上节解析的目标平台队列(未指定时为视频号 → B 站)、目标动作
draft/schedule/publish/status,以及各平台预期账号名称。 draft/schedule/publish必填:本地视频路径;schedule还需带时区的发布时间。status必填:条目链接、条目 ID / BV 号,或足以唯一定位的文案前缀、文件名和提交时间窗口。- 可选:文案、话题/标签、封面、位置、合集、原创声明、分区、类型等当前页面支持的设置。
publish 还隐含一项不可省的输入:提交前用户对终稿的明确同意。会话开头的「发吧」
只授权启动流程,见下节。
把当前会话中用户已确认的主题、标题、描述、话题、封面和原创要求视为本次输入;用户说 「基于上一版」「重新发一遍」或指出某字段漏填时,沿用本会话最后一版已确认的内容,并把 纠正后的要求持续应用到后续步骤。不要补写与主题无关的事实或宣传语。
描述来源按以下优先级解析,命中高优先级后不得再用低优先级覆盖:
- 用户在当前平台页面手动修改后的实际文本;
- 用户在当前会话逐字给出的描述;
- 同一项目中最近一次明确批准的发布文案;
- 仅在以上均不存在且编辑区为空时,才按
references/description-template.md生成草稿。
用户说“你的描述不行”、已经接管页面修改,或页面文本与 agent 上次写入值不同,都视为
description_source=user-edited。此时立即冻结全文:后续封面、合集、原创、位置和话题操作
不得重建描述编辑区,也不得为了“符合模板”润色用户版本。模板是生成草稿的约束,不是覆盖
用户终稿的许可证。
用户进一步给出实际发布文本并说明“已经修改并发布”时,这份文本立即成为本期最高优先级
gold reference,同时也是后续平台的表达策略来源:保留它的钩子、语气、大小写和关键词,只做
平台机制所需的最小适配(例如把视频号 #话题 迁移到 B 站标签字段、在 B 站钩子后追加批准
章节),不得恢复 agent 旧稿、系列介绍或冗长摘要。把用户报告与平台验证分开记录;未从内容
列表回读前,不把“用户说已发布”写成已验证的 published。
知识技巧短视频(通常约 10 分钟以内)没有用户终稿时,默认用“真实痛点问句 → 能力承诺问句
→ 5–10 个精准关键词”,而不是强制“系列第 N 期 + 内容说明 + 客套收尾”。长访谈、长教程或
资源密集内容才启用完整章节与链接骨架。具体判据见 references/description-template.md。
系列名默认用全称。撞到字数上限时不要直接降级用短名——先分别读创建表单和编辑表单
的 maxLength,两者不一定相同(B 站创建弹窗 20 字但编辑表单 50 字,先建短名再改名即可)。
只有两个表单都装不下时才用短名,并在报告里说明。
提交前必须由用户确认终稿(publish 硬门禁,两平台都适用)
publish 不是「字段齐了就发」。所有必填项 pass 之后,状态先进 awaiting_confirmation,
把终稿交给用户过目,得到明确同意才点主提交按钮。用户说过「发吧」「可以」属于启动
授权,不替代终稿确认——两者之间发生了上传、平台改写和字段回读,用户当时还没看见
最终结果。
确认动作分三步,缺一步都不算通知到:
-
一次
js()读完整个字段表(做法见对应平台的 page-anatomy),读真实value/checked/ 标签节点,不用外观推断。 -
发系统通知 + 语音播报——用户可能不在终端前:
python3 $SKILL_DIR/scripts/notify_user.py \ --title "视频号发布 · 终稿待确认" \ --message "标题/描述/话题/封面已就位,确认后我再提交" \ --speech "终稿已准备好,请确认后我再发布" -
把字段表连同平台改写过的地方一起呈现,然后停下等用户回话。这里与「等控制权」 不同:控制权是轮询等待,终稿确认必须等到用户真的答复,不设超时、不默认同意、 不自行放行。
被平台改写的字段要单独标出来,这是用户最需要看见的部分。观测过的例子:视频号短标题
因 16 字上限或禁用符号被改写、封面槽位数与预期不一致、位置被平台自动带入;B 站标签被
「当前tag为话题专用,不允许自定义添加」拒掉后换了同义词、平台按账号名自动塞进
手工/生活记录 之类的标签。用户只批准过原始文案,没批准过这些改写。
draft / schedule / status 不要求终稿确认:草稿可改,定时在到点前可撤,status 只读。
发布完整性门禁
对 publish,默认要求标题、非空描述、至少一个话题/标签,以及当前页面实际存在的
每一个封面槽都有可用内容。用户未逐字给出这些文本时,可从当前会话、同一项目的明确
文案和视频可见主题中整理克制版本;证据不足时停在提交前指出缺项,不发布空白或半成品
内容。draft 可保留用户明确允许的未完成字段。
B 站有已核验章节就必须在简介加入可点击时间轴。 时间码只能取自最终成片时间轴,格式为
每行一个 MM:SS 章节名(超过一小时用 HH:MM:SS),不得从源录屏、旧剪辑版或人工记忆
抄写。若项目已有已批准章节而简介缺少时间轴,完整性门禁为 fail。对于已经冻结的
description_source=user-edited,不得静默覆盖全文:按用户明确要求做最小追加,或停下展示
缺项;修改后重新冻结全文并重跑文案预检、字段回读和终稿确认。
B 站 tags 要做发布后公开回读。 投稿表单里的标签节点只能证明提交前状态;发布后额外调用
/x/tag/archive/tags?bvid=BV... 读取 data[].tag_name,并在公开页核对
.video-tag-container a.tag-link。/x/web-interface/view 本身不返回 tags,简介里没有
#标签 也不代表 tags 丢失。平台会重排标签顺序,所以按精确名称集合比较,不按顺序比较;
接口与公开页都命中预期集合时,不要为了展示误判重新编辑或投稿。
封面槽位数按页面实测,不写死。 视频号 2026-08-17 实测创建页只有一个槽(标签 「个人主页和分享卡片(3:4)」),两个预览由同一张 3:4 裁出;B 站有两个互相独立的槽 (4:3 首页推荐 / 16:9 个人空间),而列表、空间和信息流用的都是 16:9 那个——只传 4:3 等于没传。读到几个槽就传几张,并在报告里说明未用到的备用件。
封面存在不等于合格。 对页面上实际存在的每一个槽逐个打开编辑器,通过截图或效果
预览确认标题主体位于该槽的裁切安全区内。B 站的 16:9 槽尤其不能凭弹窗内预览判定,
唯一可信验证是投稿后拉一次公开接口读 pic(做法见
B 站投稿页结构「封面是两个独立的槽」)。
详见 发布门禁清单。
封面素材有既定来源,不许现场生成。 每期的封面在 output/covers/<ep>/
(lov-channels-cover 产出的 cover_3x4.png / cover_4x3.png)和
output/deliverables/…-封面-<宽x高>-v*.png 里,找不到就去问,不要自己造。
那套只产 3:4 和 4:3,B 站的 16:9 槽是已知缺口:缺就明说缺,让用户补一张,
绝不用 ffmpeg -vframes 1 抽首帧顶替——首帧是片头静帧或正片第一帧,当封面
等于没有封面。2026-08-18 EP.03 我抽了首帧当两个槽的素材,用户手动换成了正式
封面(线上 16:9 实际是 1440×810 的人像+标题版)。
原创(视频号):创作者账号默认勾选,除非用户在同一任务里明确说「不勾原创」「非原创」
等否定词。教训来源(2026-08-21 EP.01):用户连续多期要求勾原创,agent 一直停在
「用户没明说就不勾」的被动逻辑,每期都要用户提醒。原创是创作者账号的常驻权益,不是
需要用户重申才启用的选项。勾选原创时必须完成原创权益弹窗中的须知/条款勾选,并在
弹窗关闭后读取主复选框的真实 checked=true,不能只凭视觉样式或点击动作判断。终稿
确认时把「原创:已勾选」列入字段表,让用户看到而不是默认隐藏。
合集:先读取页面实际选中值与现有候选;创建新合集仍需用户明确同意,因为视频号合集创建后
不可改名。用户已在接管期间选择合集,或明确说“合集已勾选并已发布”时,不再询问、不清空、
不重新创建;能回读就记录实际合集名,页面已跳转而名称不可见时只记录 user-selected,不得
从本地候选猜名字。教训来源(2026-08-21 EP.01):agent 把合集当「未提出则默认」的可选项
跳过;2026-08-26 EP.01 则在用户已自行勾选后仍不能继续沿用旧的未选择字段表。
描述/标题等文案:以用户手改的最终版本为准。用户修改过描述、标题、话题后,不要 用 agent 自己整理的版本覆盖,也不要在终稿确认时展示旧版。教训来源(2026-08-21 EP.01): agent 展示了旧版描述,用户已自行改好。
实现上不能只靠记住这句话:接手或恢复发布页后的第一个只读动作是读取描述全文,并记录
description_source、精确文本和长度。每次与描述无关的页面写操作后重新读取一次;若与冻结
快照不同,立即停止并恢复前先让用户确认。终稿字段表的 expected 取冻结后的用户文本,不能
仍引用本地 publish-copy.md 或 agent 旧草稿。用户编辑后不要再调用描述区的清空、fill、
execCommand 或 Quill setText()。
生成内容标注必须依据素材来源,不能依据视频话题。 讲解 AI 产品、演示 AI 案例,以及使用 AI 辅助剪辑、字幕或调色,都不能单独证明成片含生成/合成素材。先核对用户对素材来源的明确 说明与可验证的制作证据,不臆测屏幕演示片段的来源;按 素材来源与生成内容标注记录依据并回读字段。
广告、可见范围、位置、分区、类型和评论属于会改变发布语义的选项:用户明确提出 时执行,未提出时保持平台默认。位置若由平台自动带入,也要在提交前回读并列入字段表。
如果用户只说「我的号」,且页面仅展示一个清晰的已登录账号名称,记录该名称并在提交前 回报;出现账号选择器、多个账号或模糊头像时先确认。若用户要求的标题、描述、话题或原创 声明在页面回读中缺失,停在提交前,指出具体缺失字段,不点击发布。
发布协作节奏(硬约束)
- 开页前冻结素材清单:先把平台成片和所有封面解析为存在、可读的绝对路径, 并记录版本、尺寸和平台槽位。不能只把路径藏在文件输入或工具日志里。
- 只按依赖等待:视频输入一旦开始上传,标题、简介、标签、合集、原创和其他 已挂载的独立字段立即进入写入/回读通道。只有封面编辑器、视频解析结果和提交动作 等真实依赖继续等待;不得为了轮询上传进度把全表串行化。
- 人工交接必须可执行:只有登录、平台阻断或真实遮挡无法自动化时才交接。交接同时:
- 在对话中给出可点击的成片与封面绝对路径;
- 系统通知写清平台、当前阻塞和唯一需要用户完成的动作;
- 优先用火山 TTS 播报同一条指令,并明说「不要点发布」或「可以点发布」的边界;
- 交出控制权后只等待归还,不再读页、点击或自行接管。
- 失败立即降级:自动上传或封面写入遇到确定阻塞后,不重复同一无效动作。 先保留已填字段,再交付精确文件路径和单一人工步骤;用户操作后只回读变更区域。
执行流程
-
对
draft/schedule/publish,先读该平台的 platform-constraints,再运行只读视频预检 (必须带--platform,两个平台的硬限制差一个数量级):python3 $SKILL_DIR/scripts/check_video.py <视频路径> --platform wechat-channels --json python3 $SKILL_DIR/scripts/check_video.py <视频路径> --platform bilibili \ --expected-orientation "$EXPECTED_ORIENTATION" --jsonEXPECTED_ORIENTATION必须先从本期交付契约读取并设为horizontal/vertical/square; 没有项目证据时不得仅凭平台名称猜值。硬错误出现时停在预检阶段并回报;警告不阻断,但需在上传前明确列出。若页面明确显示 账号已放宽(视频号 20 GiB / 8 小时),记录页面原文后以
--max-gb/--max-hours覆盖重跑。 实时页面限制更低时服从更低限制。status是只读查询,跳过视频预检与上传。长视频(约 30 分钟以上)或大文件例外:此时把
warnings当作实际门槛,先按 重压方案 消除偏离项再上传,尤其是video_bitrate_high。 平台的转码拒绝只在整包传完、服务端解析后才返回,长视频一次失败就是数小时代价。 -
同一时刻把文案也预检掉,不要等页面来拒。这些全是纯字符串判定,撞一次就多一个 「填入 → 失焦 → 读校验 → 改写」的页面往返:
# 视频号:短标题 16 字上限 + 禁用逗号 + 合集 10 字且创建后不可改 python3 $SKILL_DIR/scripts/check_copy.py --platform wechat-channels \ --short-title "第一时间读 Harness 架构" --description "$(cat 描述.txt)" \ --topic DeepSeek --collection "学 Harness" --json # B 站:标题 80 / 简介 2000 / 标签 ≤10 且部分名字是话题专用 python3 $SKILL_DIR/scripts/check_copy.py --platform bilibili \ --title "如何快速上手一个新项目" --description "$(cat 简介.txt)" \ --topic 架构设计 --topic 开源 \ --collection "手工川与你一起学 DeepSeek Harness" --collection-stage edit --jsonstatus: fail时先改文案再开浏览器。它只覆盖能离线判定的部分,通过不等于平台一定 接受,仍要在填入后读一次校验提示与 toast。两条要看清:视频号合集限 10 字且创建后 不可修改,超长时停下来重新起名而不是截断照建;B 站的话题专用标签名单只覆盖已实测被 拒的名字,新名字仍会在页面上被拒。 -
读 浏览器工作流,按
ego-browser任务空间流程打开该 平台入口:ego-browser nodejs <<'EOF' const task = await useOrCreateTaskSpace('media publish') await openOrReuseTab(ENTRY_URL, { wait: true }) await snapshotText() cliLog('task space: ' + task.id) EOFhelper 一律传 id 不传 task 对象(
handOffTaskSpace(task)会抛task space not found: [object Object]),完整签名坑表在同一份文档里。 -
先
snapshotText()再定位账号、账号状态与页面可见控件;每次关键操作后回读快照。 -
若出现登录二维码或账号选择,
handOffTaskSpace(task.id)交给用户,待用户返回后再续接, 不代填凭据、也不绕过登录。视频号本机微信已登录时优先点「快捷登录」,不要为了扫码 多做一次交接。交出控制权后只能通过waitForAgentControl(task.id)等待归还,任何情况 下都不得自行takeOverTaskSpace()——包括只想读一次快照、或页面看起来已经就绪时。 交出时先展示素材清单,再发系统通知并语音播报 ($SKILL_DIR/scripts/notify_user.py --tts-provider auto),然后在后台轮询控制权状态,不要停下来 要求用户回话。用户明确说「已登录」「好了」之后才接手。 -
读取页面展示的账号名并与预期逐字核对。只有一个清晰账号且用户说「我的号」时记录该 名称;账号不符、多个候选或只有模糊头像时停下确认。
-
汇总本会话已确认的字段,形成提交前字段表,每项记录
required / source / expected / actual / result。接手页面先读取描述;页面已有非空描述且 与 agent 上次写入值不同,source=user-edited,当场冻结,不进入描述写入分支。 通用项:账号、标题、描述、话题/标签、封面(按页面实际槽位数逐槽一行)、合集、定时。 视频号加:短标题、位置、原创、视频标注、评论、可见范围。B 站加:分区、类型、 已核验章节的可点击时间轴、16:9 封面的pic回读结果。字段表全文见 发布门禁清单。 账号、目标动作及所需输入均明确后,把状态记为prepared。 -
status直接打开内容管理列表并跳到第 12 步。其他动作通过主上传区关联的文件输入 提交原视频——两个平台都存在多个accept相同的 file input,必须按平台文档里的判据 锚定,不能取第一个。观察到上传进度后记为uploading;进度 100% 后仍等待转码、缩略图 或素材解析,记为processing。上传开始后,只要字段区已经挂载且连续两次回读稳定,就并行 填写不依赖素材解析的标题、描述、话题、合集、原创和标注;不要为了等待上传完成把这些字段 串行化。每次写入仍须遵守描述冻结规则。素材解析完成后统一重读一次,发现平台重渲染清空时 才做最小补写。 -
素材解析完成且页面未显示视频错误后,填写封面等依赖素材的字段,并完成全表回读。写入前先按 来源优先级判断每个字段;
description_source=user-edited时跳过描述写入,只做只读回读。按各平台 page-anatomy 的写值方式操作,并逐项回读实际值:- 视频号:短标题读输入框
value,平台报特殊字符时按提示做最小修正并确认警告消失; 描述读编辑区实际文本;话题必须读平台已识别的独立标签节点,不只检查原始#文本; 封面的图片文件输入只在编辑器打开后才存在;原创要生效需先勾须知再读主复选框属性。 合集默认询问用户归属哪个合集(创作者按系列发内容时尤其如此);原创默认勾选并 完成须知弹窗确认(见上文「原创」段),不要等用户重申。 - B 站:输入框用原生 setter 写值,
inputType不能省;写完的计数器必须下一轮js()再读(同一轮读到的是nextTick前的旧值,0/20是假失败);简介用 Quill 用.ql-container.__quill.setText(text, 'user')后blur(),下一轮从.ql-editor或getText()逐字回读;填标签前先清掉平台自动猜的那几个;svg.close与.hot-tag-item只吃 CDP 真鼠标。项目存在已核验章节时,从最终成片时间轴生成完整的MM:SS 章节名列表并写进简介;下一轮逐条回读全部时间码和标题,缺一条都不能提交。 封面右侧「首页推荐 / 个人空间」按钮只切换效果预览;真正上传槽是包住#editor_4_3/#editor_16_9的 canvas wrapper,必须逐槽回读active、上传并截图,且关闭双比例同步。 每个与描述无关的写操作后都要断言冻结描述逐字未变。任何必填字段未持久化、用户描述被改动 或校验仍有警告时,停在提交前。
- 视频号:短标题读输入框
-
publish在此停下等用户确认终稿:一次js()读完整个字段表,跑notify_user.py发通知与播报,把终稿(尤其被平台改写过的字段)交给用户过目,状态记为awaiting_confirmation。得到明确同意才继续。draft/schedule/status跳过本步。 如果用户接管页面后返回并说“我已改好并发布”,不要把这句话当成让 agent 再点一次的确认: 立即冻结用户给出的实际文本,停止所有表单写入,直接进入内容列表只读回读;回读前保留上个 已证实状态,并另记user_reported_published=true。 -
按目标动作进入对应分支:
draft:选「保存草稿」语义动作,确认完成后进入草稿列表并重载。schedule:启用定时发布,核对页面时区、日期和时间,确认提交后进入内容列表并重载。publish:所有必填项pass且用户已确认终稿后,点主提交动作(视频号「发表」/ B 站「立即投稿」),只提交一次,再进入内容列表并重载。未得到确认时不要点击, 也不要因为等待而改用draft绕过。主提交按钮常落在视口外(视频号观测 y=726 / 视口高 727,B 站观测 y=1380 / 视口高 731),坐标点击会静默丢;先scrollIntoView再按新 rect 操作,点完回读页面状态确认真的生效。B 站先做一次语义/直接点击;仅在确认真实遮挡且 没有任何提交态时交用户操作,禁止隐藏遮挡层或盲点第二次。status:不修改条目;打开与目标标识匹配的内容列表并重载,读取平台状态原文。
-
用账号及当前可用的条目 ID / BV 号、链接、视频文件名、文案前缀、提交时间、封面等组合 指纹查找唯一条目。记录列表状态、条目链接或 ID、回读时间与页面 URL。B 站的管理页拒绝 直链(
upload-manager/all与/season会跳回首页),要从侧边栏点进去。B 站还要分别 回读view.data.title、view.data.desc、view.data.pic与x/tag/archive/tags.data[].tag_name;前三项逐字/目视核对冻结终稿,公开 tags 按集合验收, 不能从简介里是否出现#推断。公开字段缺失时只编辑同一 BV 并重投一次,不创建重复稿件。
状态契约
状态只使用下列值;出错时保留最后一个已确认状态,把错误另列:
| 状态 | 成立证据 |
|---|---|
prepared | 平台与账号已核对,动作所需输入完成;写入动作也已通过只读预检 |
uploading | 页面出现本次文件的实际上传进度 |
processing | 上传完成,平台仍在转码、解析或生成封面 |
awaiting_confirmation | 仅 publish:字段表全项 pass,已通知用户并把终稿交他过目,等待明确同意 |
draft_saved | 草稿列表重载后找到唯一匹配条目 |
scheduled | 内容列表重载后找到匹配条目和正确定时时间/状态 |
platform_pending | 内容列表重载后找到唯一条目,状态明确为转码、审核或发布处理中 |
published | 内容列表重载后找到匹配条目,且列表明确显示已发布/已发表状态 |
publish_failed | 内容列表重载后找到唯一条目,且列表明确显示失败、拒绝或终止状态 |
成功提示、按钮消失、请求返回或页面跳转都不单独证明 published。没有列表重载回读时,
停留在最后一个已证实状态。B 站还必须用公开 view 的 title / desc / pic 证明终稿与 16:9
封面真的落库,不要用表单内预览或成功页代替。
收口错误
- 提交后超时或状态不明时,不要再次点击发布;先去内容列表重载回读,防止重复内容。
- 主提交按钮进入加载态、页面跳转或出现成功提示后,均视为已经尝试提交;后续只做列表回读。
- 上传或处理失败时记录页面原文、文件名、预检摘要、账号、当前 URL、最后状态与发生时间; 保留源视频不变。
- 页面显示转码失败(如「视频转码失败,调整视频导出参数后重试」)时,这是服务端拒绝, 不是网络问题:重传同一文件只会再失败一次。先核对文件大小与时长确实在页面显示的限制内, 再按 重压方案 消除预检偏离项、重压并重新验证。
- 重发同一素材时列表里会同时存在旧条目与新条目,且文件名、时长、首帧完全相同。此时禁止 用这些字段做指纹,改用提交时间、标题、话题组合、新封面或条目 ID / BV 号;无法区分时保留 最后确认状态并报告全部候选。旧条目是否删除由用户决定。
- 页面结构变化时重新获取快照,以角色、可见名称、标签和邻近文案定位;多个候选时停止点击 并报告候选。
- 控件查不到不代表控件不存在:视频号的表单在
<wujie-app>的 shadow root 里,document.querySelector一律返回空且不报错,容易被读成「还没渲染完」而白等几轮;文件输入 连 shadow root 都查不到,只有DOM.getDocument({ pierce: true })能看见。B 站没有这个问题, 但换成了「Vue 不吃合成事件」。各自的定位表与可复用探针在两份 page-anatomy 里。 - 视频号的弹窗是预渲染的,按可见性过滤而非存在性:约 35 个弹窗全部在 DOM 里,只靠尺寸
隐藏。读
.weui-desktop-dialog的innerText会拿到与当前状态无关的文案(观测实例:上传 封面后读到「将此次编辑保留?」,屏幕上并无此弹窗),据此点按钮就是点空。用getBoundingClientRect().width > 100过滤。 - 点了没反应且没报错时不要重试同样的点法:先判断是落在视口外(滚进来再按新 rect 点),
还是控件只吃真鼠标(用
cdp('Input.dispatchMouseEvent', ...))。观测实例:B 站报告删了 12 个 标签,实际一个没少。 - 列表若显示「原创审核中」「审核中」「转码中」等处理中原文,状态用
platform_pending,即使 已出现成功提示或已跳转列表也不要写成published。 - 用户未答复终稿确认时,
awaiting_confirmation就是本次任务的最终状态,照实回报——这不是 失败,也不要为了收尾而改走draft或自行放行。此时保留任务空间与页面。 - 用户报告自己已修改并发布时,禁止再次点击主提交按钮,也禁止用旧字段表覆盖页面;后续只做
内容列表回读。列表尚未回读时说明“用户报告已发布、平台状态未验证”,不要误报
published。 - 用户在任务任意阶段明确要求「发布后不要关闭」「保留页面 review」时,该要求持续生效直到
明确撤销。收尾必须使用
completeTaskSpace(task.id, { keep: true })并检查返回的done。 - 最终回报平台、目标动作、账号、最后状态、平台状态原文、列表回读证据、警告和未完成项。
只有满足状态契约时才使用
draft_saved/scheduled/platform_pending/published/publish_failed。B 站的报告要额外说明稿件仍可编辑,视频号的不要这么说。
与相邻 Skill 的分工与不做什么,见 组合决策。
Signals
- GitHub stars
- 66
- Forks
- 17
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
lov-media-publisher- Source
- github.com/lovstudio/skills