news 2026/8/22 14:10:39

如何备份B站收藏夹?mybili弹幕下载背后的WBI签名与protobuf解析完全揭秘

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何备份B站收藏夹?mybili弹幕下载背后的WBI签名与protobuf解析完全揭秘

如何备份B站收藏夹?mybili弹幕下载背后的WBI签名与protobuf解析完全揭秘

【免费下载链接】mybili哔哩哔哩收藏夹备份程序 ~ アレ 视频不见了哟!项目地址: https://gitcode.com/gh_mirrors/my/mybili

mybili是一款开源的哔哩哔哩收藏夹备份程序(README.md),它能把你的 B 站收藏夹视频、封面、弹幕定时同步到本地 NAS,实现"视频不见了也有备份"的安全感。其中最有技术含量的部分,就是它如何绕过 B 站的接口保护:用 WBI 签名算法合法请求弹幕接口,再把返回的 protobuf 二进制数据手工解析成可读弹幕。本文将带你完整看懂这套逆向实现。


📺 mybili 是什么:一句话看懂功能

mybili 是一个部署在 NAS 上的后台服务,核心能力包括:

  • ⏰ 定时 5 分钟拉取收藏夹所有视频信息(标题、封面、简介)
  • 🚀 按最高画质自动下载视频到本地
  • 💬全量下载并缓存每个分 P 的弹幕,支持在线播放装载
  • 📂 生成 Emby 等媒体库可读的目录结构
  • 📡 订阅 UP 主 / 合集,自动发现新视频

先看它的 Web 管理界面长什么样:

进入具体收藏夹后,可以看到所有已备份的视频,右上角可以切换下载状态:

下载进度页会展示已缓存视频比例、有效/失效/冻结视频分类统计:


🎫 为什么需要 WBI 签名?

B 站为了保护接口不被滥用,在 2023 年给一批重要接口(包括弹幕接口)加上了WBI 签名校验:请求 URL 必须携带一个由动态密钥计算出的w_rid参数,否则服务端直接拒绝。

传统做法是解析 B 站前端混淆 JS 来还原算法。而 mybili 的工程师选择了更"硬核"的路线——纯 PHP 逆向复现整个签名流程,全部逻辑集中在一个文件里:app/Services/BilibiliService.php。

第 1 步:从导航接口偷取动态密钥

WBI 密钥不是固定的,每次都要实时获取。mybili 请求 B 站网页导航接口/x/web-interface/nav,从返回的wbi_img字段中取出两张图片 URL(img_keysub_key):

https://i0.hdslb.com/bfs/wbi/xxxxxx.png ← img_key https://i0.hdslb.com/bfs/wbi/yyyyyy.png ← sub_key

注意取 key 的技巧(BilibiliService.php 第120-121行):从 URL 中截取去掉扩展名的文件名作为密钥字符串——图片本身只是幌子,真正有用的是文件名。

第 2 步:固定乱序表混合出 32 位密钥

拿到两个 key 后拼接,再通过一张写死的 64 位乱序索引表重新洗牌:

混合表(前10位)464718253823321550

按索引从拼接串中逐个取字符,取满 32 位,得到mixin_key。这张表是逆向前端代码时挖出来的常量,只要 B 站不改混淆逻辑它就永远有效(encWbi 函数)。

第 3 步:参数排序 + MD5 出 w_rid

签名最后一步非常朴素:

  1. 把所有请求参数值中的特殊字符(!'()*)过滤掉
  2. 按键名字典序排序
  3. 拼成查询串,末尾追加mixin_key
  4. 整串做MD5→ 得到w_rid参数
w_rid = md5(排序后的query字符串 + 32位混合密钥)

整个签名只有约 40 行 PHP 代码,没有任何外部依赖。这套算法的完整实现见 encWbi()。


🧩 弹幕接口:按 6 分钟一片分段请求

弹幕接口/x/v2/dm/wbi/web/seg.so有两个特点:

  • 必须带 WBI 签名(就是上面破解的那套)
  • 按时间段分片返回:每 6 分钟(360 秒)一个分段,长视频要循环请求多段

mybili 的处理方式很聪明(getDanmaku 方法):

$segmentCount = ceil($duration / 360); // 视频时长 ÷ 6 分钟 = 分段数

一个 30 分钟的视频会被拆成 5 段依次请求,每段都独立签名,最后把各段弹幕合并成一个完整数组。

更关键的是:这个接口不返回 JSON,而是返回 protobuf 二进制流


🔬 硬核部分:手工解析 protobuf 二进制

protobuf 是 Google 的高性能二进制序列化格式,一般解析需要引入google/protobuf库并预先生成 PHP 类文件。但 B 站弹幕接口的结构并不公开 proto 定义文件,mybili 选择了一条更野的路:逐字节手写解析器,不依赖任何 protobuf 库。

先搞懂 protobuf 的两个基本功

① Varint(变长整数):每个字节只取 7 位有效数据,最高位是"是否还有下一字节"的标记位。小于 128 的数只占 1 字节,越大占得越多。

② Tag 字节:每个字段开头都有一位 tag,高 5 位是字段编号,低 3 位是线型(wire type)

线型含义读取方式
0Varint循环读,直到最高位为 0
164 位固定长度直接跳过 8 字节
2长度前缀(字符串/嵌套消息)先读 varint 长度,再读对应字节
532 位固定长度直接跳过 4 字节

外层结构:找出"弹幕数组"字段

解析器从二进制流第 0 字节开始循环(parseDanmakuProtobuf):

  • 读到字段编号 = 1且线型 = 2 → 这就是"弹幕条目",读出长度后截取该段,交给单条弹幕解析器
  • 其他字段 → 按上表线型规则直接跳过(B 站以后加新字段也不会导致解析崩溃)

内层结构:字段编号对照表

单条弹幕的子字段解析在 parseSingleDanmaku,逆向还原出的字段表如下:

字段编号名称线型含义
1idvarint弹幕唯一 ID
2progressvarint出现时间(毫秒
3modevarint弹幕模式(1-3 滚动 / 4 底部 / 5 顶部)
4fontsizevarint字号
5colorvarint颜色(十进制,如 16777215 = 白色)
6midHashbytes用户哈希(脱敏 mid)
7contentbytes弹幕文本内容
8ctimevarint发送时间戳
9weightvarint弹幕权重(决定优先显示)
12actionbytes动作类弹幕标记

解析结果长这样(getDanmaku 中的注释):

{ "progress": 390379, "mode": 1, "color": 16777215, "content": "是我", "id": 162000000000000000 }

从一坨不可读的二进制字节,到结构化弹幕数据,全程不到 200 行代码,且每个读取点都有边界检查防止越界崩溃——这就是"手工逆向"的完整闭环。


📥 从二进制到屏幕:弹幕的入库与展示

解析完只是开始,mybili 的弹幕链路还包含三个环节:

  1. 异步下载:DownloadDanmakuJob 队列任务驱动 DownloadDanmakuAction,用 Redissetnx加锁防止同一分 P 重复下载,按分片全量拉取
  2. 增量入库:解析后的弹幕按 1000 条一批插入 SQLite 的 danmaku 表,通过弹幕 ID 去重只存新增
  3. 格式转换:Web 端播放时,DanmakuConverterService 把 B 站原始字段转成播放器通用格式——毫秒转秒、十进制颜色转#FFFFFF十六进制、高级模式(6-9)降级为滚动模式,高级弹幕还会自动降级提取纯文本

前端弹幕播放器通过 /danmaku 接口 获取转换后的数据,即可在本地备份的视频上还原出"原汁原味"的弹幕体验。


📚 相关代码导航

模块路径说明
WBI 签名 + 弹幕获取app/Services/BilibiliService.phpgetDanmaku / encWbi
protobuf 解析器app/Services/BilibiliService.phpparseDanmakuProtobuf / parseSingleDanmaku
弹幕下载动作app/Services/VideoManager/Actions/Danmaku/DownloadDanmakuAction.php加锁、分片、增量入库
弹幕格式转换app/Services/DanmakuConverterService.phpB 站格式 → 播放器格式
弹幕表结构database/migrations/2025_06_14_130110_create_danmaku_table.phpSQLite 存储

✅ 总结

mybili 用一次教科书级的逆向实践证明了:没有公开 API 文档 ≠ 数据不可得

  • WBI 签名:导航接口取动态 key → 固定乱序表混合 → 参数排序 MD5,40 行代码复现 B 站前端混淆逻辑
  • protobuf 解析:不装库、不要 proto 文件,靠 Varint + Tag 两个基本功手写逐字节解析器,兼容 B 站后续字段变更

对于想学习逆向分析的开发者,app/Services/BilibiliService.php 这一个文件就是绝佳的实战教材:WBI 签名与 protobuf 二进制解析两大硬核技术,都浓缩在其中。

【免费下载链接】mybili哔哩哔哩收藏夹备份程序 ~ アレ 视频不见了哟!项目地址: https://gitcode.com/gh_mirrors/my/mybili

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/22 14:06:17

sg-exam:从克隆到跑通的在线考试平台完整部署教程

sg-exam:从克隆到跑通的在线考试平台完整部署教程 【免费下载链接】sg-exam 基于Spring Boot搭建的新一代教学管理平台,提供权限管理、考试、问卷、练习等功能 项目地址: https://gitcode.com/gh_mirrors/sg/sg-exam sg-exam 是一个基于 Spring B…

作者头像 李华
网站建设 2026/8/22 14:05:32

免费QQ空间备份工具GetQzonehistory:扫码导出你的全部历史说说

免费QQ空间备份工具GetQzonehistory:扫码导出你的全部历史说说 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 去年整理旧照片时,你想从QQ空间里翻出大学时期的几…

作者头像 李华