DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

7gzgn /

7gzgn/dsh-douyin-publish

Verified

Take a local video all the way to a Douyin creator post: open the upload page, trigger the picker, hand the file over with verification, fill the title, set visibility - then stop before publishing unless explicitly told to publish.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@3413d538

dsh-douyin-publish(视频发布器 · 抖音 / B站)

把一段本地视频,一路送到投稿页的"待发布"状态。

打开投稿页 → 版式自检 → 把文件直接塞进页面自己的上传控件 → 填标题 → 填文案/话题 → 设可见性 → 默认停手。

这是九个作品里唯一的"功能"(其余多是工具):它不止给 AI 加一个动作, 而是替使用者跑完一条链 —— 开页面、交文件、填表、判断该不该发。 也正因为如此,它的默认值必须保守。


0.4.2:B站真正吃文件的是那个"藏着"的 input(2026-10-17 晚,真机)

第二次真机跑,卡在"等了 61 秒编辑表单没出来"。查下来:B站投稿页有三个 input[type=file] —— 一个隐藏的(外面包着 .bcc-upload-wrapper)、一个看得见的按钮里的、一个给字幕的 .txt。 真正驱动上传的是隐藏的那个;塞进看得见的那个,页面一动不动(文件在 input 里,但没人接)。

旧代码按"可见优先"挑,正好挑错。现在:

  1. 候选按 DOM 先后排,不再按可见性;
  2. 塞完先看页面有没有往前走(编辑表单出现),没走就换下一个候选试,最多 3 个;
  3. 回执里写明"塞进了第 N 个上传控件"。

0.4.1:真机上遇到的两个"不是改版"的情况(2026-10-17 晚)

第一次拿真 B站账号跑 v0.4.0,卡在"版式自检"——不是选择器坏了,是两件真事:

  1. 上传按钮比 input[type=file] 晚渲染。旧代码只要看到 file input 就去自检, 而 B站的上传区还在画 → 误报 layout-changed。现在会等上传区真的出现(最多 15 秒)。
  2. B站会提示"本地浏览器存在 N 个未提交的视频 → 继续编辑 / 不用了"。自动化不该接管别人的旧草稿: 现在看到这个提示会点「不用了」,从新稿开始(旧稿原样留着),并在回执里记一笔。 如果页面直接把旧稿恢复成编辑态(没给"不用了"),会明确报 resumed-draft, 让你先去处理那条旧稿——而不是猜成"改版"。

配乐:让用户自己在平台曲库里挑(v0.6.0)

不是本地音乐库。抖音自己的曲库里有搜歌、试听、使用那一套,那是平台的东西, 我们不去复制它 —— 我们只负责把那个面板打开、再往前送一步:

douyin_upload({ ..., pickMusic: true })                  // 打开面板 + 聚焦搜索框
douyin_upload({ ..., pickMusic: true, musicSearch: "轻快" })  // 打开面板 + 顺手搜「轻快」

流程是:填完标题/文案/话题/封面 → 点右侧「添加音乐」标签 → 等「选择音乐」侧边面板长出来 → 把「搜索音乐」框聚焦 → 停。剩下的打字/试听/点「使用」由人在浏览器窗口里做 (平台会自己把歌混进视频)。

真机核对的细节(2026-10-18):入口不是文案「添加音乐」,而是右侧那颗 div[class*=preview-button] 标签;点开后的面板里有一个 input[placeholder*="搜索音乐"],它外面盖着遮罩,点不可靠、el.focus() 可靠。 mode=publish 时不打开面板(避免和发布撞在一起);B站的曲库面板还没核对,传了会标 warn 跳过。

musicSearch 是实验性的:我在这台机器上没能稳定把词打进去 —— 脚本改 value(native setter、 execCommand)都能改值,但抖音的搜索只在真实键盘事件时才触发;而插件会话里的按键投递时好时坏。 所以它默认只做"打开面板 + 聚焦",词打不进去时回执会如实说"请你手动在搜索框里输",不会假装成功。 不想点的话,用下面的 bgmPath 走本地混音。

另一条路(可选):bgmPath 给一段本地音频,它会先用 ffmpeg 混好再上传(原视频不动), bgmVolume 默认 0.35 —— 适合"我就要这一首,别让我点"的场景。

两条默认值是刻意的

参数 默认 要改成别的必须显式说
visibility private(仅自己可见) visibility: 'public' / 'friends'
mode draft(不点投稿) mode: 'publish'

发布是不可逆且对外可见的动作。所以这个插件默认只做到"表填好、停投稿前", 你要发,就再说一次。想先看看会发生什么,用 dryRun: true。

平台没有你要的可见性时,插件直接拒绝(visibility-unsupported), 不会"默认当你没说过"然后按公开发出去。

文件是怎么交给页面的(v0.4 的关键改动)

以前靠"真点上传按钮 → 等系统『打开文件』对话框 → 用 UI 自动化填路径", 那条路要碰另一个进程的窗口、会挡住使用者、还得起 PowerShell, 而且它出过一次"看起来成功、其实没交上"的事故(见下)。

现在默认走注入:

  1. 本机在 127.0.0.1 的一个随机端口起一个只读、只服务这一个文件、带随机令牌的小服务;
  2. 页面自己 fetch 回来,用 DataTransfer 造一个真 File,塞进页面的 input[type=file], 派发 input/change;
  3. 之后就是页面自己的上传逻辑在跑 —— 和"人手选文件"完全一样,但不弹对话框、不挡人。

安全边界写死:只绑回环地址、只认一条路由(令牌不对一律 404)、不列目录、用完就关(另有空闲超时兜底)。

什么时候退回系统对话框:文件超过 maxInjectBytes(默认 512MB)、 或注入被页面拦下(CSP/CORS)。退回时会回读校验,读不回来就判失败 —— 不点确认、不假装成功。

它做什么(每一步都留证据)

步 动作 细节
① 检查视频 大小 / 分辨率 / 时长 / 编码(ffprobe,拿不到也不拦)
①' 配乐(可选) 给了 bgmPath 就先用 ffmpeg 混一段新视频:原视频有声→与原声混合(bgmVolume 默认 0.35)、无声→BGM 铺满;原视频不动,混音失败直接报错不硬发
② 借浏览器会话 用自己的会话键,和别的任务不串台
③ 打开投稿页 平台档案里的地址(抖音 / B站)
④ 等上传控件 轮询到 input[type=file] 出现为止
④' 版式自检(投稿页) 上传控件 / 「上传视频」区域缺一个 → 立刻报 layout-changed 并点名,不硬着头皮跑
⑤ 交文件 注入(默认);大文件或注入失败才退回系统对话框
⑥ 等编辑页 按平台的"编辑控件是否出现"判(B站不换 URL,URL 只当旁证)
⑥' 版式自检(编辑页) 标题框 / 投稿按钮缺一个 → 同样当场报 layout-changed
⑦ 填标题 整段写入后回读(B站会预填文件名,所以要覆盖而不是追加)
⑦' 填文案 + 代填话题 抖音:文案与 #话题 都进简介,打完回读;B站:文案进简介,话题进「标签」并回车确认
⑧ 设可见性 抖音按中文标签点 checkbox;B站展开「更多设置 → 可见范围」再选,回读选中态
⑧' 设封面帧 只有抖音做:打开「选择封面」→ 时间轴挪到 coverTime(默认第 1 秒,第 0 帧常是黑场);设不上只标 warn
⑨ 投稿,或故意不投稿 mode=draft 时这一步记 skipped

失败会分类说清:no-browser / platform-unsupported / visibility-unsupported / upload-page-timeout / edit-page-timeout / layout-changed / handover / visibility / bgm。

平台

平台 状态 差异
抖音 ✅ 真机核对过 话题写进简介;可见性三档(公开/好友/仅自己可见);封面帧可设
B站 ✅ 真机核对过(2026-10-17) 不换 URL就切到编辑态;标题预填文件名;话题进「标签」(回车);可见范围在「更多设置」里(公开可见/仅自己可见,没有好友);封面帧未核对
小红书 / X ⛔ 还没核对 传 platform="xiaohongshu" 之类会明确拒绝(platform-unsupported),不拿别的平台的选择器去瞎点

要扩到别的平台,前提是先真机把那个平台的投稿页走一遍(登录态、上传入口、标题/简介框、 话题落地方式、可见性入口、投稿按钮),再往 lib/platforms.js 补一份档案 —— 这是"给别人用"的底线,不能拿猜的选择器充数。

它依赖什么

  • 浏览器插件(借宿主的 ctx.browser 服务)—— 没有时明确报错,不会假装能用。
  • 可选:ffprobe(没有也能发,只是少了元信息)。
  • 大文件才需要的退路:自带 lib/handover.ps1(与作者的 dsh-file-handover 同源, 但各作品独立成仓,不互相依赖)。

安装

市场收录后在 DSH 里搜 dsh-douyin-publish 安装。手动安装:

New-Item -ItemType Junction -Path "$env:USERPROFILE\.dsh\profiles\desktop\node_modules\dsh-douyin-publish" -Target "D:\dsh\projects\dsh-douyin-publish"
# profile 的 package.json:dependencies 加 "dsh-douyin-publish": "link:D:/dsh/projects/dsh-douyin-publish"
# 并把 "dsh-douyin-publish" 加进 dsh.profile.bundles(漏了不加载)→ 重启 DSH

发布前先做这两件事:① 装好浏览器插件;② 在浏览器窗口里登录对应平台的创作中心 (登录态存在浏览器 profile 里,一次登录可跨重启复用)。

用法

douyin_upload videoPath=D:\videos\a.mp4 [platform=douyin|bilibili] title="标题" \
  [description="文案"] [topics="猫,狗"] [coverTime=1] [visibility=private] [mode=draft|publish] [dryRun]

典型流程:dryRun: true 看一眼 → 正式跑一次(停投稿前)→ 到浏览器里核对 → mode: 'publish' 真发。

已知限制

  • 版式绑定:选择器基于真机实测(抖音 2026-10-16、B站 2026-10-17); 平台改版后需要同步更新。插件先自检再动手:关键控件缺一个就当场报 layout-changed 并点名缺什么。
  • 注入会把文件读进浏览器渲染进程:所以设了 maxInjectBytes(默认 512MB)上限,超过自动退回系统对话框。
  • 抖音话题是"联想式"的:代填是把 #话题 打字进简介框,是否被转成真标签由页面决定; 所以填完一定回读,读不齐就明说"请在页面上看一眼",不假装成功。
  • B站标签上限 20 字:超长的话题会被页面截断,回执里会提醒。
  • 封面是尽力而为(仅抖音):靠封面弹窗里的时间轴定位;弹窗里没有时间轴时只标 warn、保留默认封面。
  • 验证码 / 风控不硬试:检测到就停下请人到浏览器窗口处理,再继续。
  • 系统对话框那条退路仅 Windows:注入这条路是跨平台的。
  • 不做内容创作:剪片、封面图、文案是内容管线的事(用 ffmpeg 等),这个插件只负责"送上去"。

自测

node test/smoke.mjs   # 165 项:假浏览器 + 假 spawn + 真起一个回环小服务;断言编排序列、默认值、失败分类、版式自检、话题/标签、可见性、平台拒绝

License

MIT

—/ 5

No ratings yet

Verified DSH bundle

Commit 3413d538e2b4

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout