做过自媒体矩阵的人都懂那种机械重复的痛苦。
手动发布的真实成本
假设你手上有 20 条视频,要同步发到抖音、快手、B 站、百家号、头条、视频号、小红书——先不算登录切号,光是填资料就要:
20 条视频 × 7 个平台 = 140 次重复操作
每次操作包括:上传视频文件、粘贴标题、填标签、选分类、打开「声明原创/AI 生成」开关……其中最烦的是「创作声明」。各平台对 AI 生成内容的披露要求不一样,有的要勾选,有的要在简介里加说明。忘了就可能被降权,不忘就得每次手动翻找。
140 次操作,哪怕每次 3 分钟,就是 7 个小时。
这还只是发布,不算后期改标题、补标签、查数据。
用 xlsx 声明文件管理批量发布
MatrixMedia 在最新版本里引入了两个配合使用的功能:目录批量发布 + xlsx 声明文件。
思路很简单:把视频统一扔进一个目录,用一张 Excel 表格声明每个视频的元信息,然后一条命令全部发出去。
xlsx 文件的结构长这样:
| 文件名 | 标题 | 标签 | 创作声明 |
|---|---|---|---|
| video_001.mp4 | 我用 AI 做了一个…… | AI,效率,工具 | ai_generated |
| video_002.mp4 | 这个方法能省 3 小时 | 教程,干货 | original |
| video_003.mp4 | 2026 年还在手动发布? | 自媒体,工具 | ai_generated |
字段说明:
- 文件名:与目录下视频文件名对应,程序自动匹配
- 标题:各平台发布时使用的标题(也可以按平台分列,目前默认全平台同一标题)
- 标签:逗号分隔,程序拆分后逐个填入
- 创作声明:
original(原创)/ai_generated(AI 生成)/repost(转载),程序根据值自动操作对应开关
这张表就是你整批视频的「发布说明书」,填一次,所有平台复用。
技术实现:xlsx 解析 + Puppeteer 批量驱动
从开发视角看,这个功能的核心就两件事:解析 xlsx 取元信息 + 用 Puppeteer 按顺序驱动各平台上传流程。
xlsx 解析
用 xlsx 这个库把表格读成 JS 对象数组:
const XLSX = require('xlsx')
const path = require('path')
const fs = require('fs')
function loadPublishConfig(xlsxPath) {
const workbook = XLSX.readFile(xlsxPath)
const sheet = workbook.Sheets[workbook.SheetNames[0]]
const rows = XLSX.utils.sheet_to_json(sheet)
// 把每行映射成标准结构
return rows.map(row => ({
filename: String(row['文件名'] || '').trim(),
title: String(row['标题'] || '').trim(),
tags: String(row['标签'] || '')
.split(',')
.map(t => t.trim())
.filter(Boolean),
declaration: String(row['创作声明'] || 'original').trim(),
}))
}
目录扫描 + 文件匹配
拿到配置数组后,扫描目标目录,按文件名做对应:
function buildPublishQueue(videoDir, configList) {
const files = fs.readdirSync(videoDir).filter(f =>
['.mp4', '.mov', '.avi'].some(ext => f.endsWith(ext))
)
return files
.map(filename => {
const config = configList.find(c => c.filename === filename)
if (!config) {
console.warn(`[skip] 没有找到 ${filename} 的配置,跳过`)
return null
}
return {
...config,
filePath: path.join(videoDir, filename),
}
})
.filter(Boolean)
}
Puppeteer 批量发布主循环
有了发布队列,剩下的是逐一驱动各平台的上传页面。MatrixMedia 对每个平台封装了独立的 Publisher 类,外层循环长这样:
async function batchPublish(queue, platforms, options = {}) {
for (const item of queue) {
console.log(`\n📦 开始发布:${item.filename}`)
for (const platform of platforms) {
try {
const publisher = createPublisher(platform, options)
await publisher.publish({
file: item.filePath,
title: item.title,
tags: item.tags,
declaration: item.declaration,
})
console.log(` ✅ ${platform} 发布成功`)
} catch (err) {
console.error(` ❌ ${platform} 发布失败:${err.message}`)
// 单平台失败不中断整批,继续下一个
}
}
}
}
几个细节值得说一下:
- 单平台失败不中断:某个平台上传超时或登录态失效,只记录错误,不影响其他平台和其他视频继续发。
- 声明字段的平台差异:抖音和视频号的 AI 声明入口不在同一个位置,每个平台的 Publisher 内部各自处理,上层统一用
declaration字段传值,外部调用者不用感知差异。 - 进度通知:通过 MCP 的
progressToken机制,批量发布过程中会实时推送进度,Electron 主进程可以把进度更新渲染到 UI 上。
GUI 操作流程
打开 MatrixMedia,登录好各平台账号后,批量发布入口在主界面的「目录批量发布」按钮。
操作步骤:
- 点击「选择目录」,选中存放视频的文件夹
- 点击「选择声明文件」,选中填好的 xlsx 表格
- 界面会自动解析 xlsx,列出每行记录,并用绿色 ✓ / 红色 ✗ 标记文件是否在目录中找到
- 确认匹配无误后,点「下一步」进入平台选择
- 勾选要发布的平台,点「开始发布」,程序逐一驱动各平台上传
文件名对不上(红色 ✗)是最常见的问题,一般是 xlsx 里写了 video_01.mp4 但目录里实际是 video_01.MP4 或 video01.mp4——大小写和空格都要完全匹配。程序会跳过没有匹配配置的文件,不会中断整批。
关于 MatrixMedia
这个项目从第一版只支持抖音单平台发布,到现在支持 7 个平台批量发布 + xlsx 声明文件,每一篇文章背后基本都有一个真实的使用痛点在推动。
项目开源在:github.com/hanliang97/…
如果你在用 MatrixMedia,或者有新的功能需求,直接开 Issue 或者留言,我都会看。
Star 和 Issue 都是对这个项目最直接的支持,也让我知道这东西还有人用。