一次发几十条视频到 7 个平台,我用目录批量发布 + xlsx 声明文件做到了

26 阅读4分钟

做过自媒体矩阵的人都懂那种机械重复的痛苦。

手动发布的真实成本

假设你手上有 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.mp42026 年还在手动发布?自媒体,工具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}`)
        // 单平台失败不中断整批,继续下一个
      }
    }
  }
}

几个细节值得说一下:

  1. 单平台失败不中断:某个平台上传超时或登录态失效,只记录错误,不影响其他平台和其他视频继续发。
  2. 声明字段的平台差异:抖音和视频号的 AI 声明入口不在同一个位置,每个平台的 Publisher 内部各自处理,上层统一用 declaration 字段传值,外部调用者不用感知差异。
  3. 进度通知:通过 MCP 的 progressToken 机制,批量发布过程中会实时推送进度,Electron 主进程可以把进度更新渲染到 UI 上。

GUI 操作流程

打开 MatrixMedia,登录好各平台账号后,批量发布入口在主界面的「目录批量发布」按钮。

操作步骤:

  1. 点击「选择目录」,选中存放视频的文件夹
  2. 点击「选择声明文件」,选中填好的 xlsx 表格
  3. 界面会自动解析 xlsx,列出每行记录,并用绿色 ✓ / 红色 ✗ 标记文件是否在目录中找到
  4. 确认匹配无误后,点「下一步」进入平台选择
  5. 勾选要发布的平台,点「开始发布」,程序逐一驱动各平台上传

文件名对不上(红色 ✗)是最常见的问题,一般是 xlsx 里写了 video_01.mp4 但目录里实际是 video_01.MP4video01.mp4——大小写和空格都要完全匹配。程序会跳过没有匹配配置的文件,不会中断整批。


关于 MatrixMedia

这个项目从第一版只支持抖音单平台发布,到现在支持 7 个平台批量发布 + xlsx 声明文件,每一篇文章背后基本都有一个真实的使用痛点在推动。

项目开源在:github.com/hanliang97/…

如果你在用 MatrixMedia,或者有新的功能需求,直接开 Issue 或者留言,我都会看。

Star 和 Issue 都是对这个项目最直接的支持,也让我知道这东西还有人用。