- 桌面应用
- 音视频
【免费下载链接】BiliTools
本项目已停止维护。
本文以 BiliTools 的“资源解析”功能为主线,系统讲解搜索页如何识别并解析哔哩哔哩的各类资源标识(AV/BV 号、短链、番剧、课程、音乐、图文、用户空间等),解析完成后如何选择资源并触发常规下载与 JSON 数据导出。阅读本文后,你将掌握该项目的输入识别规则、底层parseId解析流程、MediaInfo数据结构,以及各资源类型对应的 B 站 API 调用链路,可直接对照 解析入口实现 与 媒体数据服务 进行实战验证。
一、搜索页与输入方式
在应用左侧边栏点击搜索图标,即可切换到搜索页(对应视图组件 SearchPage.vue)。页面顶部搜索组件由三部分组成:
- 左侧:文本输入栏,支持直接粘贴链接或编号;
- 中部略靠右:资源分类下拉栏(默认“自动检测”,可手动指定具体类型);
- 最右侧:搜索按钮。
在“自动检测”模式下,程序会对输入内容自动判型。以下两种情况下需要手动选择对应资源分类:
- 仅输入了纯数字(如空间 UID、收藏夹 fid)的情况,自动检测无法区分数字归属;
- 仅输入了课程的 SS 号 / EP 号的情况(课程与番剧共用
ss/ep前缀,需显式指定为课程类型)。
提示:哔哩哔哩正在将“专栏”与“动态”合并为“图文”,BiliTools 也做了对应处理。解析图文内容时请注意区分资源分类类型,其媒体类型在 shared.d.ts 中定义为
Opus/OpusList。
二、支持的输入格式与自动识别规则
2.1 常规链接 / B23.TV 短链 / AV 号 / BV 号
视频类资源支持以下输入形式:
https://www.bilibili.com/video/av11451 https://www.bilibili.com/video/BV1tx411c77w https://b23.tv/pigt3PQ av11451 BV1tx411c77w其中b23.tv短链会先被请求并跟随重定向,再递归解析真实链接(见 utils.ts 中parseId对b23.tv域名的处理)。纯av/BV编号则直接命中正则^(av\d+|BV\w{10})$,映射为MediaType.Video。
2.2 分享链接
从哔哩哔哩客户端复制出的带share_source=copy_web&vd_source=xxx后缀的分享链接可直接粘贴解析,例如:
【【手描き】 End of Daylight PV 【描いてみたよん】】 https://www.bilibili.com/video/BV1tx411c77w/?share_source=copy_web&vd_source=xxxparseId在解析 URL 时会从输入中提取第一个形如bilibili.com/b23.tv域名的片段(见 utils.ts),因此标题文字不会影响识别。
2.3 稍后再看
https://www.bilibili.com/watchlater/list https://www.bilibili.com/list/watchlater/?bvid=BV1tx411c77w&oid=11451前者解析为MediaType.WatchLater(稍后再看列表);后者则从查询参数中提取bvid/oid/aid,按视频类型解析(utils.ts)。
2.4 番剧 / 影视:SS 号 / EP 号 / MD 号
https://www.bilibili.com/bangumi/play/ss2539 https://www.bilibili.com/bangumi/play/ep341254 https://www.bilibili.com/bangumi/media/md28228367 ss2539 ep341254 md28228367ss→ 季(season);ep→ 集(episode);md→ 媒体库编号。- 三者均映射为
MediaType.Bangumi。其中md号需先调用pgc/review/user接口换取season_id后再获取季信息(见 data.ts)。
2.5 课程:SS 号 / EP 号
https://www.bilibili.com/cheese/play/ss61 https://www.bilibili.com/cheese/play/ep812 ss61 ep812课程使用cheese域名段,解析为MediaType.Lesson,内部调用pugv/view/web/season接口(data.ts)。这也是上文提到需要手动指定分类的场景之一。
2.6 音乐 / 歌单:AU 号 / AM 号
https://www.bilibili.com/audio/au3741236 au3741236 https://www.bilibili.com/audio/am86055 am86055au→ 单曲,MediaType.Music;am→ 歌单,MediaType.MusicList;- 识别逻辑见 utils.ts。
2.7 图文合集(专栏 & 动态)
https://www.bilibili.com/read/readlist/rl380536 rl380536解析为MediaType.OpusList,内部调用/x/article/list/web/articles接口拉取合集下的图文列表(data.ts)。
2.8 用户空间:投稿视频 & 合集
https://space.bilibili.com/8047632 https://space.bilibili.com/8047632/video https://space.bilibili.com/8047632/upload/video https://space.bilibili.com/8047632/lists https://space.bilibili.com/8047632/lists/5747470 8047632- 空间主页 /
video/upload/video→MediaType.UserVideo(用户投稿视频); lists及其后的数字 → 指定合集(season / series),解析时会从 URL 中提取合集 ID 作为target(utils.ts);- 纯数字 UID 需要手动选择分类后才能正确解析为用户空间。
2.9 用户投稿图文(专栏 & 动态)
https://space.bilibili.com/8047632/article https://space.bilibili.com/8047632/upload/opus https://www.bilibili.com/read/cv1 https://www.bilibili.com/opus/38554821905721204 cv1 38554821905721204- 空间专栏 / 动态页 →
MediaType.UserOpus(utils.ts); - 单篇图文
cv号或opus链接 →MediaType.Opus。其中cv号会先请求https://www.bilibili.com/read/{id}并从中提取对应的/opus/{数字}ID 再查询详情(data.ts)。
2.10 用户投稿音频
https://space.bilibili.com/8047632/audio https://space.bilibili.com/8047632/upload/audio解析为MediaType.UserAudio(utils.ts)。
2.11 用户收藏夹
https://space.bilibili.com/8047632/favlist https://space.bilibili.com/8047632/favlist?fid=338926432 338926432- 收藏夹页解析为
MediaType.Favorite,URL 中的fid参数作为target传入; - 纯数字
fid需要手动指定分类(utils.ts)。
2.12 类型汇总
下表汇总了全部输入前缀与媒体类型的映射关系(依据 utils.ts 与 shared.d.ts):
| 前缀 / 路径段 | 媒体类型(MediaType) | 说明 |
|---|---|---|
av/BV | Video | 普通视频 |
b23.tv | 递归解析 | 短链重定向 |
watchlater | WatchLater | 稍后再看列表 |
ss/ep(bangumi) | Bangumi | 番剧 / 影视 |
md | Bangumi | 番剧媒体库,需换 season_id |
ss/ep(cheese) | Lesson | 课程 |
au | Music | 单曲 |
am | MusicList | 歌单 |
rl | OpusList | 图文合集 |
space.bilibili.com(主页 / video / lists) | UserVideo | 用户投稿视频及合集 |
space(article / opus)、cv、opus | UserOpus/Opus | 图文(专栏 & 动态) |
space(audio) | UserAudio | 用户投稿音频 |
space(favlist)、fid | Favorite | 用户收藏夹 |
三、解析的底层实现:parseId与getMediaInfo
3.1 输入解析函数parseId
搜索动作会先调用 utils.ts 中导出的parseId(input, ignore),将原始输入归一化为{ id, type, target }:
- 纯编号匹配:先用正则
^(av\d+|BV\w{10}|ep\d+|ss\d+|md\d+|au\d+|am\d+|cv\d+)$直接判型(utils.ts); - URL 提取:对包含链接的输入,从空白字符分隔的片段中挑出符合
bilibili.com/b23.tv域名的片段构造URL对象(utils.ts); - 域名分发:
b23.tv走重定向递归;space.bilibili.com按路径段分发到收藏夹、视频/合集、图文、音频等用户空间类型;其余bilibili.com子域名按video、audio、bangumi、cheese、read、opus等路径段逐层匹配(utils.ts)。
在手动指定分类时,parseId的ignore参数为true,纯数字输入会直接作为id返回,交由后续指定类型处理(utils.ts)。
3.2 媒体信息获取getMediaInfo
解析出的{ id, type }会传入 data.ts 的getMediaInfo(id, type, options),根据类型分发到不同的 B 站接口,最终统一封装为MediaInfo:
| 媒体类型 | 核心接口 | 返回结构 |
|---|---|---|
Video | /x/web-interface/view | 分 P 列表、合集(ugc_season)、互动视频(edge) |
Bangumi | /pgc/view/web/season | 分集、分节(PV/花絮)、演员表、评分 |
Lesson | /pugv/view/web/season | 课程剧集列表 |
Music | audio/music-service-c/web/song/info | 单曲信息 |
MusicList | audio/music-service-c/web/menu/info | 歌单信息 |
WatchLater | /x/v2/history/toview/web | 稍后再看列表 |
Favorite | /x/v3/fav/folder/created/list-all+/x/v3/fav/resource/list | 收藏夹列表(媒体类型经typeMap映射,支持 2=视频、12=音乐、24=番剧) |
Opus | /x/polymer/web-dynamic/v1/forward/preview | 图文详情 |
OpusList | /x/article/list/web/articles | 图文合集列表 |
UserVideo | /x/polymer/web-space/home/seasons_series+ 合集/系列归档接口 | 投稿视频及合集 |
UserOpus | /x/polymer/web-dynamic/v1/opus/feed/space | 用户图文流(offset游标分页) |
UserAudio | /audio/music-service/web/song/upper | 用户投稿音频 |
值得注意的实现细节:
- 视频含合集(
ugc_season)时,返回的sections.tabs提供各分集标签;当分 P 数大于 1 时以分 P 为单位展开(data.ts)。 - 互动视频(
rights.is_stein_gate为真)会额外调用getPlayerInfo与getEdgeInfo(/x/stein/edgeinfo_v2),生成edge字段(含剧情分支choices与隐藏变量vars),用于 SearchPage.vue 中的剧情线切换(extras.ts)。 - 音乐、番剧的参演与制作人员信息会被规整为
credits.actors/credits.staff(data.ts)。
四、解析功能区:选择资源与执行操作
解析完成后,页面左侧展示资源列表,右侧展示可用的解析功能按钮(对应 SearchPage.vue 的布局)。
4.1 资源列表与多选
- 点击每行左侧复选框可选中单个项目;
- 按住Shift键点击可选中连续区间;
- 右上角的“全选”按钮可一键选中/取消当前页全部项目(SearchPage.vue)。
关于选择数量的注意事项,参见 关于风控:不建议一次性选中超过 30 个项目。代码中当选中数量超过 30 时也会弹出警告日志(SearchPage.vue)。风控文档进一步建议大量下载时每次勾选不超过 15 个任务以保障账号安全。
对于合集、番剧等,右下方会展示对应标签页(如 PV、花絮等分节);对于收藏夹、歌单等,右下方会展示“页面”控件用于翻页,而非无限滚动(
pn分页字段由getMediaInfo的options.pn控制)。
4.2 常规下载
点击“常规下载”按钮会弹出参数页面(对应 Popup.vue),用于确定需要处理的任务与参数。详细注意事项请参见 选择资源。流程上,选中项会先补全缺失的cid(调用getCid),再经selectPopup.getSelect生成参数并加入下载队列(SearchPage.vue)。
4.3 导出数据
“导出数据”功能可将当前媒体信息以 JSON 格式存档。前端通过commands.exportData(path, mediaInfo)调用 Tauri 后端命令,将MediaInfo序列化为美化后的 JSON 并写入用户选择的文件(默认文件名形如{标题}_{时间戳}.json,见 SearchPage.vue)。后端实现为serde_json::to_string_pretty后fs::write落盘(commands.rs)。
五、MediaInfo数据结构(JSON 导出格式)
MediaInfo定义于 src/types/shared.d.ts,是导出 JSON 的核心结构:
export interface MediaInfo { type: MediaType; id: string; pn?: boolean; // 是否支持翻页 nfo: MediaNfo; // 元信息:标题、简介、标签、统计数据、UP 主、缩略图等 edge?: MediaEdge; // 互动视频剧情分支数据 offset?: string; // 游标分页偏移(如用户图文流) sections?: { target: number; tabs: { id: number; name: string }[]; }; list: MediaItem[]; // 资源列表 }其中MediaNfo(shared.d.ts)包含:
showtitle:展示标题(合集/剧集取合集名,否则取视频标题);intro:简介(番剧取evaluate,课程取副标题 + FAQ,图文取正文);tags:标签(视频来自/x/tag/archive/tags,番剧来自styles,音乐来自歌曲标签接口);stat:播放 / 弹幕 / 回复 / 点赞 / 投币 / 收藏 / 分享等统计数据;thumbs:封面与公开图集(id+url);premiered:发布时间戳(秒);upper:UP 主(name/mid/avatar,头像与名字在解析界面右上角展示,可点击跳转空间);credits:番剧演员 / 制作人员,或音乐参与成员。
MediaItem(shared.d.ts)则描述列表中的每个条目,携带aid、bvid、cid、epid、ssid、opid、rlid等各类 ID,供下载任务后续使用。解析界面的信息卡组件 MediaInfo.vue 正是渲染这些字段的实例。
六、从解析到下载的完整调用链
一次完整的“解析 → 下载”流程可概括为:
- 输入文本 →
parseId归一化为{ id, type, target }(utils.ts); getMediaInfo按类型请求 B 站接口,封装为MediaInfo(data.ts);- 用户在资源列表勾选项目(支持 Shift 连续多选、全选);
- 点击“常规下载” → 弹出参数界面 →
queue.submit加入下载队列(SearchPage.vue); - 队列调度器处理任务,最终经 Tauri 后端调用 aria2c / ffmpeg 等二进制完成下载与处理(download.md)。
需要特别说明的适用前提:本项目当前已停止维护,文档与源码所描述的解析规则基于历史版本(对应v1.4.4时代的MediaInfo定义)。哔哩哔哩接口与网页结构持续变化,若个别解析规则失效,请以项目 CHANGELOG.md 与 风险说明 中的说明为准。
- 桌面应用
- 音视频
【免费下载链接】BiliTools
本项目已停止维护。
相关推荐
突破B站资源获取限制:BiliTools多媒体工具全解析
突破B站资源获取限制:BiliTools多媒体工具全解析 在数字内容爆炸的时代,高质量视频和音频资源的获取与管理成为创作者、学习者和娱乐爱好者共同面临的挑战。B
桌面应用音视频LaunchRocket替代方案对比:为什么它仍然是Mac用户的首选工具
LaunchRocket替代方案对比:为什么它仍然是Mac用户的首选工具 在Mac开发环境中,服务管理是一个至关重要的环节。LaunchRocket作为一款专门
开发工具BV收藏系统:多分类收藏与批量管理
BV收藏系统:多分类收藏与批量管理 引言 在哔哩哔哩的生态系统中,收藏功能是用户内容管理的重要环节。BV作为第三方Android TV应用,实现了完整的收藏系统
移动开发音视频
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考