微信视频号一直是个「看得见摸不着」的地方——你能在微信里刷、能点赞、能转发,但想把它存到本地,官方几乎不给你任何按钮。第三方录屏、视频号缓存文件又被加密过,普通用户基本无从下手。

GitHub 上有一款关注度持续走高的开源项目 wx_channels_download(仓库名也叫 wx_video_download,可执行文件就叫 wx_video_download),作者 ltaoo 把整套方案做成了一个只有 8 MB、跨平台、双击就能跑的 Go 二进制。今天这篇文章就带大家把这个项目完整拆开,看看它做了什么、怎么用、能玩出什么花样。

项目地址:https://github.com/ltaoo/wx_channels_download
许可证:MIT + Commons Clause(可以免费使用、修改、再分发,但不得以本软件为主体转售商业服务)
技术栈:Go 1.x + Gin + SQLite + WebSocket + Cloudflare Workers + MCP
代码规模:442 个 .go 文件 + 80 个 .js 文件(含前端 + 注入脚本)


一、它到底解决了什么问题

视频号的内容并不是简单放在一个 mp4 URL 后面就能下载的。它的播放链路大致是:

  1. 客户端先发起 getFeedProfile 拿到视频元信息(含一个加密用的 decode_key)。
  2. 元信息里的播放地址返回的是一个被加密的二进制流(俗称「SPH」格式),不在浏览器里跑一段解密代码根本拿不到明文。
  3. 微信 PC 端是一个内嵌的 Chromium 容器,运行时网络请求可以被本地 HTTP(S) 代理截获,但只靠抓包是拿不到明文的。

wx_channels_download 的思路非常直接:自己起一个本地 HTTPS 代理,安装一个根证书,让微信 PC 端信任我,由我去拦截播放请求、还原明文,再在前端页面里塞一个下载按钮。

代理服务启动成功

整个项目就是围绕这个思路长出来的,所以它的能力边界远超「下载视频」本身——任何能注入到视频号页面的能力,它都能做。


二、三分钟跑起来

1. 下载与启动

到 Releases 页选择对应平台:

系统 文件后缀
macOS Apple Silicon darwin_arm64
macOS Intel darwin_x86_64
Windows windows_x86_64(带 safe 后缀的没有 UPX 压缩)
Linux x86_64 / arm64 linux_x86_64 / linux_arm64

首次启动必须用管理员 / sudo 权限,因为要安装根证书并改系统代理。证书安装完毕后,后续双击就能运行。

Windows 安装根证书

终端出现「代理服务启动成功」之后,打开微信 PC 端的视频号页面,会发现视频下方的操作按钮栏里多了一个 下载 按钮——这就是注入成功的标志。

2. 下载第一个视频

等到视频开始播放(必须),然后暂停,点击下载按钮。

视频下载成功

注意:默认会下载当前正在播放的规格(一般是最小体积),点击下拉菜单可以选 1080P 等更高画质,或者打印 ffmpeg 命令自己导。

如果微信改版导致按钮插错位置也没关系,项目内置了兜底悬浮按钮:

首页兜底悬浮按钮

详情页兜底悬浮按钮

3. 没有按钮?先排查这三件事

  1. 终端是否显示「代理服务启动成功」
  2. 系统代理是否指向 127.0.0.1:2023
  3. 如果你开着 Clash / Surge,把 proxy.system 设为 false,然后让科学上网工具把视频号流量转发到下载器的端口

三、不止是「下载按钮」——核心功能盘点

下载视频只是入口。下面这些能力才是 wx_channels_download 真正有意思的地方。

1. 多场景下载按钮

场景 行为
视频号首页推荐 操作栏插入「下载」按钮
视频详情页 操作栏插入「下载」按钮 + 「更多」菜单
直播页 插入「下载图标」按钮,可复制 ffmpeg 命令
公众号文章 底部插入「下载」按钮,把整篇文章存成 HTML
任意页面 兜底悬浮按钮,永远兜底

视频号详情页

视频号首页

首页下载按钮

2. 批量下载作者全部视频

在作者详情页会出现「批量下载」按钮,点击后会拉取该作者所有视频并创建排队任务,默认同时跑 3 个,剩下的进入 wait 状态等位。

批量下载按钮 下载队列
批量下载按钮 下载列表

自 251226 起,长视频默认在后台下载,刷新页面也不会中断;退出下载器会中断所有正在进行的任务。

3. 直播下载(需要 ffmpeg)

直播详情页右上角会出现「下载图标」,点击后创建一个直播下载任务;点击下拉菜单可以把 ffmpeg 命令复制到剪贴板,自己用终端录。

直播下载按钮

4. 一键 MP3

如果只想保留音频,下拉菜单里有「下载为 mp3」。需要先把 channels.download.frontend 设为 true,否则会在后台先把 mp4 拉下来再用 ffmpeg 转。

5. 公众号文章 / RSS

打开 mp.enabled: true 后,公众号文章底部出现「下载」按钮,能把整篇推文导出成 HTML。还有实验性的「推送列表」和「下载所有推送」。

公众号文章下载按钮

通过 wx_video_download deploy mp 一键部署到 Cloudflare Worker,就能得到一个属于自己的公众号 RSS:

公众号 RSS

6. 自定义文件名 / 路径

项目抛弃了旧的 YAML 模板,改为在工作目录里写 hooks.js,自定义程度直接拉满:

1
2
3
4
5
6
function onFilename(meta) {
return {
directories: [meta.author], // 按作者建子目录
name: [meta.title, meta.spec, meta.idx].filter(Boolean).join("_"),
};
}

再比如想在文件名里加上视频发布日期:

1
2
3
4
5
6
7
8
9
10
11
12
function secondsToYMD(seconds, startTimestamp = 0) {
const d = new Date((startTimestamp + seconds) * 1000);
return `${d.getFullYear()}${String(d.getMonth()+1).padStart(2,"0")}${String(d.getDate()).padStart(2,"0")}`;
}

function onFilename(meta) {
return {
directories: [],
name: [meta.author, meta.title, secondsToYMD(meta.created_at), meta.spec, meta.idx]
.filter(Boolean).join("_"),
};
}

最终得到的文件名类似 作者_标题_20260710_xWT111_1.mp4,存到 NAS 里也好检索。

7. 任务级 Hook

hooks.js 里还能注册 onTaskSuccess / onTaskFailed / onTaskFinish,自动把下载完成的视频推到 Notion / WebDAV / 自己写的服务里。

1
2
3
4
5
6
function onTaskFinish(ctx) {
if (ctx.status === "success") {
// ctx.filePaths 是刚刚下载好的全部本地路径
console.log("下载完成:", ctx.filePaths);
}
}

8. 自定义菜单:下载视频 + 封面打成 ZIP

在 global.js 里 WXU.unshiftMenuItems([...]),可以新增一个「下载视频和封面」按钮——视频拉下来后用 WXU.Zip() 打包成 zip 保存。

9. MCP:让 AI 直接调用下载器

这是项目最「潮」的一块。wx_channels_download 内置了 Model Context Protocol 服务,地址是 http://127.0.0.1:2022/mcp(默认关闭,需在「设置 → MCP」里启用)。一旦启用,Claude Desktop、Codex、Cline 等 MCP 客户端就能直接调用下载器的能力。

官方文档里给了一段非常直白的示例:

使用 dm MCP 服务 查找昵称为「我不叫龙虾」的视频号账号,获取最新的 10 条视频。

可用的 MCP 工具大致分为几类:

  • 应用配置:get_config / update_config / get_restart_status / deploy_sph_worker
  • 下载行为:fetch_content / download_content / decrypt_wxchannels_video
  • 视频号数据:search_wxchannels_accounts / get_wxchannels_account_videos / get_wxchannels_live_replays / get_wxchannels_video_profile / get_wxchannels_video_comments / get_wxchannels_play_history / get_wxchannels_followed_accounts / get_wxchannels_interacted_videos / get_wxchannels_video_share_url
  • 本地数据:get_download_tasks / delete_download_tasks / get_accounts / get_browse_history / get_logs / get_certificate_status / get_platform_status

所以理论上你只要跟 AI 助手说「把『我不叫龙虾』最新 10 条视频全部下到 /Users/me/Videos 目录,跳过已下载的」,AI 就会自动串联工具完成任务。

10. Bridge:把设备能力暴露到公网

如果想做一个「在家里的 Mac 上跑下载器,从公司通过 API 触发下载」的场景,可以用 Bridge:

1
外部程序 ── HTTPS ── Bridge Worker ── WebSocket ── 家里 Mac 上的下载器

部署方式是 wx_video_download deploy bridge,会在 Cloudflare 上同时拉起一个 Durable Objects Worker 和一个受密码保护的 Pages 管理页面。Bridge 按调用计费,每个 Call Token 每成功发起一个调用消耗 1 积分,避免被人白嫖。

可调用的方法大致是这一组(节选):

method 作用
wxchannels.fetch 通过 URL 获取规范化内容
wxchannels.contact.search 搜索视频号账号
wxchannels.contact.feed.list 获取账号视频列表
wxchannels.feed.profile 获取单条视频详情
wxchannels.feed.comment.list 获取评论
wxchannels.live.replay.list 获取直播回放
wxmp.biz.msg.list 获取公众号消息
download.create 在指定设备创建下载任务

并且项目内置了 JavaScript / Python / Go / Java / PHP / C# / Rust 七种语言的示例,复制粘贴就能跑。

11. Cloudflare 一键部署

deploy 命令本身是个父命令,下面挂了三套:

1
2
3
wx_video_download deploy mp       # 部署公众号 RSS / API Worker
wx_video_download deploy sph # 部署视频号查询页面(基于元宝 cookie)
wx_video_download deploy bridge # 部署 Bridge + 管理页面

每一套部署都会自动绑定 Durable Objects / D1 / Secrets,免去手动拖代码的麻烦。


四、它是怎么做到的——架构视角

只看 README 可能以为它就是个抓包脚本,其实整个项目已经是个相对完整的 Go 后端:

模块 作用
cmd/ Cobra 命令树:server / mcp / update / uninstall / deploy / version
internal/application/ 主流程编排、权限提升、应用更新
internal/api/ Gin HTTP 服务,全部 REST API + WebSocket
internal/services/ 下载任务、账号、浏览记录等业务逻辑
internal/database/ SQLite 封装,存任务、账号、配置
internal/interceptor/inject/ 注入到视频号页面的前端脚本(TS 编译成 JS)
internal/workers/ Cloudflare Worker 模板(mp / sph)
pkg/certificate/ 跨平台证书安装/卸载/信任状态查询
pkg/scraper/ 抓取 + 解密 SPH 视频
pkg/flowengine/ 下载流程引擎(多任务排队、Hook 调用)
pkg/hermes / pkg/minib 微信小程序协议封装
pkg/platform/ 各平台(视频号、公众号等)适配层
frontend/ 自带的管理面板(Vite 编译,go:embed 进二进制)

前后端都在同一个二进制里:

  • 前端页面(http://127.0.0.1:2022/)用 Vite 打包后 go:embed 进 Go 二进制
  • 注入到视频号页面的脚本通过 MITM 在响应里塞一段 <script>
  • 浏览器内的事件回调会通过 WebSocket 把数据回流到 Go 后端,落库 SQLite

所以本质上它是一个 本地优先的全栈下载器。


五、进阶玩法

1. 监听视频号事件,写自动化

在工作目录的 global.js 里:

1
2
3
4
5
6
7
8
WXU.onFeed(async (feed) => {
const [err, res] = await WXU.request({
method: "POST",
url: "http://127.0.0.1:1234/api/feed",
body: feed,
});
if (err) WXU.error({ msg: err.message });
});

再起一个 Go HTTP 服务接住数据,就能:

  • 自动备份所有刷过的视频到 NAS
  • 自动归档某个作者的全部视频
  • 跟 RAG / 向量数据库结合做视频内容分析

2. 用 aria2 / curl 替代内置下载

如果内置下载器不够快,MCP 里的 fetch_content 返回值里有个 download_resources 字段,里面有 download_url 和 decode_key:

1
aria2c --out video.mp4 "<download_url>"

下载完后再调用 decrypt_wxchannels_video,传入文件绝对路径和 decode_key,原地解密覆盖原文件。这种方式在千兆宽带 + NAS 上非常爽。

3. 把下载器装到 Docker 里跑

官方提供了镜像 ghcr.io/ltaoo/wx_video_download:latest,里面跑的是 Linux + WeChat + 下载器,通过 Webtop 暴露端口:

1
2
3
4
5
6
7
docker run -d \
--name=wx_account1 \
--security-opt seccomp=unconfined \
--cap-add=NET_ADMIN --device /dev/net/tun \
-p 3000:3000 -p 2022:2022 -p 2023:2023 \
-v ./wx_account1:/config \
ghcr.io/ltaoo/wx_video_download:latest

打开 http://127.0.0.1:3000 就是带桌面环境的 Linux 微信 + 下载器。注意官方明确建议用小号登录,不要同时跑多容器多账号,「可能封号风险很大」。

4. TUN 模式

proxy.tun: true 会创建一个虚拟网卡,从网络层把视频号流量劫持过来,不需要改系统代理。和 Clash 共存时建议别开 TUN,而是把 system: false、通过 Clash Script 把流量转发到下载器端口。


六、需要注意的点

  1. 免责声明:作者在 README 明确声明仅用于技术交流学习,请勿用作任何非法用途。视频号内容多有版权问题,请尊重作者。
  2. 证书风险:默认安装的根证书会拦截视频号请求,影响范围止于本机。要卸载的话可以用 wx_video_download uninstall,或者手动从系统的「受信任的根证书颁发机构」里移除 SunnyNet。
  3. 微信风控:视频号本身对自动化行为敏感,过度刷接口会被临时封禁下载/播放。建议不要在循环里高频触发。
  4. Linux 平台:需要 ffmpeg(直播、MP3 转换要用到);macOS 自带 ffmpeg,Windows 需要自己装。
  5. 长视频:默认后台跑,但退出程序会中断所有进行中的任务。
  6. GitHub 仓库常更:版本号格式像 260907 / 260502,作者保持每周级迭代,建议固定关注 Releases。

七、写在最后

wx_channels_download 不只是一个「下载视频号」的小工具,它把整套「拦截 → 解密 → 注入 → 后台调度 → 远程调度 → AI 接入」链路都打通了一遍。对于想理解 MITM 代理、客户端解密、Cloudflare Workers 边缘计算、MCP 集成的开发者来说,这个项目的代码是非常值得读的实战教材。

如果你只想用它的核心功能,安装包 + 双击就能跑,几分钟内就能在微信里看到下载按钮。如果你想自己魔改,它的 pkg/scraper、pkg/flowengine、pkg/certificate 三个包都设计得很干净,可以直接拿来复用。

提醒:再次强调,请务必仅将本项目用于个人备份、学习研究,遵守相关法律法规与平台协议。

相关阅读

标签

开源项目 微信视频号下载 Go 二进制 MITM 代理 MCP 接入 Cloudflare Bridge 公众号下载 批量下载