BiliParse —— Typecho 哔哩哔哩视频解析插件
把 iuroc/bilidown(server/bilibili 解析模块,Go 语言实现)
用 PHP 重写,做成一个 Typecho 插件:在文章里写一行短代码,就能嵌入 / 解析 B 站视频。
下载
功能
| 能力 | 说明 |
|---|
| 文章短代码 | [bili]BV1xx411c7mD[/bili],也支持 [bilibili] 标签与整段链接 |
| 独立成行的链接 | 正文里单独一行的 B 站链接自动转成播放器(可在设置里关闭) |
| 单视频解析 | BV 号 / av 号 / bilibili.com/video/... / b23.tv 短链 |
| 番剧影视 | ss 季 ID、ep 集 ID、md 媒体 ID(bangumi/media/mdxxx,会自动换成 season_id),自动列出分集 |
| UP 主合集 | collectiondetail?sid=xxx |
| 收藏夹 | favlist?fid=xxx |
| 分 P | 支持 ?p=2 或短代码 p=2 |
| 画质 | 360P ~ 1080P / 4K / 8K、Hi-Res 音频、杜比(取决于账号权限与 SESSDATA) |
| 扫码登录 | 后台扫码即可写入 SESSDATA,无需手动复制 Cookie |
| 视频流代理 | 内置代理转发,绕过 B 站 Referer 防盗链,支持 Range 与断点续传 |
| CDN 智能选路 | 解析后先展示 B 站封面,等页面空闲再在访客浏览器里实测各节点速度,自动选最快的播放和下载(详见下文) |
| 独立解析页 | 你的域名/biliparse,粘贴链接即可解析、切换分集、下载 |
安装
把整个 BiliParse 目录上传到 usr/plugins/,保证结构为:
usr/plugins/BiliParse/
├── Plugin.php
├── Action.php
├── Client.php
├── Parser.php
├── Store.php
├── Util.php
├── assets/
│ ├── player.js
│ ├── player.css
│ ├── page.js
│ └── admin.js
├── tests/
│ └── selftest.php (可选,离线自检用)
├── cache/ (运行时自动创建,也可不存在)
└── README.md
- 后台「控制台 → 插件」启用 BiliParse。
- 点击插件「设置」,建议先在「B 站扫码登录」处扫码获取 SESSDATA。
- 需要站点开启伪静态(地址重写),否则接口地址会形如
你的域名/index.php/biliparse/api/parse,
插件会自动适配,但更推荐开启重写。
要求:PHP 5.6+(Typecho 1.2 本身要求 7.4+)、curl 扩展(无 curl 时降级为
file_get_contents,但不支持视频流代理的断点续传)、Typecho 1.1 ~ 1.3 均已做兼容处理。
使用方法
短代码
[bili]BV1xx411c7mD[/bili]
[bili p=2]BV1xx411c7mD[/bili] 指定分 P
[bili mode=dash]BV1xx411c7mD[/bili] 强制用本地解析播放
[bili mode=iframe]https://www.bilibili.com/video/BV1xx411c7mD[/bili]
[bili]https://www.bilibili.com/bangumi/play/ss48831[/bili]
支持属性:p(分 P)、mode(iframe / dash)、title(自定义标题)。
两种播放模式
- iframe(默认):内嵌 B 站官方播放器,零服务器开销、永远可用,但清晰度和弹幕由官方控制。
纯 BV 号时由服务端直接输出 iframe,即使主题没有调用 footer() 也能正常显示。 - dash:走本插件的解析接口,用 dash.js 播放。可切换清晰度、拿到直链下载,
支持 1080P/4K/8K。需要 dash.js(默认 jsDelivr CDN,可在设置里换成自己的地址)。
设置项
| 项 | 说明 |
|---|
| 默认播放模式 | iframe / dash |
| SESSDATA | B 站登录凭证,扫码或手动填写。不填时 dash 模式通常只能解析到 360P |
| 附加 Cookie | 接口返回 -412 风控时,粘贴 buvid3、b_nut 等 |
| 默认清晰度 | 自动 ABR 或锁定指定档位 |
| 解析结果缓存时间 | 默认 1800 秒,B 站播放地址有有效期 |
| 视频流代理 | 关闭时接口直接 302 跳源站(大概率 403) |
| CDN 智能选路 | 关闭后直接使用 B 站返回的默认地址,不做测速 |
| 自动解析纯链接 | 关闭后只处理短代码 |
| 解析工具页 | 是否开放 /biliparse |
| dash.js 地址 | 可换成本地文件 |
CDN 智能选路
B 站 playurl 返回的是它替你的服务器挑的节点,对访客未必最快。而且接口其实给了完整备选列表:
base_url 只是推荐项,backup_url 里还有其它节点——bilidown、bilibili-parse 以及大多数同类实现
都只取了 base_url,访客就被固定在这个未必最优的节点上(BiliBili-JX 则是让用户手动从下拉框选域名)。
本插件的做法是让访客的浏览器自己实测:
- 服务端把
base_url + backup_url 全部收集起来,再按一份 CDN 域名池
(参考 BiliBili-JX)补出同源的其它节点,
每条流最多 8 个候选; - 播放器先展示 B 站封面(解析接口返回的
cover),不阻塞首屏; - 等页面
load / 浏览器空闲后,再对每个节点取 128 KB 做实测(并发 3 个),
算出实际速度——不在解析完成时立即抢带宽; - 选最快的节点,把该节点的地址写进 MPD 与下载链接;若想立刻看,点封面上的
「播放」会马上用默认节点开播,测速结果随后只刷新提示与下载项,不打断播放; - 结果按域名缓存在
localStorage(30 分钟),同一访客后续播放不再重测。
要点:
- 测速走的是本插件自己的代理(直连 B 站会被 Referer 校验挡掉),所以测到的是
访客 → 服务器 → 节点这条完整链路的真实表现,比服务端 ping 更接近访客的实际体验。 - 每个节点只测一次、只取 128 KB,开销很小;全部候选都失败时自动回退到 B 站默认地址。
- 页面
load 被大图/字体拖住时,测速最多延后 5 秒兜底执行,不会一直等待。 - 不想用时在插件设置里关掉「CDN 智能选路」即可,行为退回成直接播放默认地址。
接口
| 地址 | 说明 |
|---|
/biliparse/api/parse?u=<链接或BV号>&p=1 | 解析,返回元信息、分集、清晰度、代理后的播放地址、下载链接 |
/biliparse/api/mpd?bvid=&cid=&s=[&cdn=] | 生成 DASH 清单(MPD),带签名校验;cdn 指定用哪个节点 |
/biliparse/api/proxy?u=&s=[&dl=1&n=] | 媒体流代理,带签名校验,只放行 B 站域名 |
/biliparse/api/qrcode | 获取登录二维码(仅管理员) |
/biliparse/api/qrpoll?k= | 轮询扫码结果(仅管理员) |
/biliparse | 独立解析页 |
parse 返回示例(节选):
{
"success": true,
"data": {
"type": "video", "bvid": "BV1xx411c7mD", "cid": 123456,
"title": "视频标题", "cover": "https://i2.hdslb.com/...", "duration": 300,
"pages": [{"page": 1, "cid": 123456, "part": "P1", "duration": 300}],
"qualities": [{"id": 80, "desc": "1080P 高清", "height": 1080}],
"cdnHosts": ["upos-sz-mirrorali.bilivideo.com", "upos-sz-mirrorcos.bilivideo.com"],
"mpd": "https://your.site/biliparse/api/mpd?...",
"downloads": [{"label": "1080P 高清", "video": "...", "audio": "..."}]
}
}
dash.video[i] / dash.audio[i] 中每条流都带 hosts 与同序的 urls,
即该流的全部候选节点;downloads[i] 同样带 hosts、videoUrls、audioUrls。
从 bilidown 移植过来的部分
| bilidown(Go) | 本插件(PHP) |
|---|
server/bilibili/client.go → BiliClient.SimpleGET / MakeHeader / 扫码登录 | BiliParse/Client.php → request() / makeHeader() / newQRInfo() / getQRStatus() |
server/bilibili/wbi.go → getWbiKeyRemote / GetMixinKey / WbiSign | Client.php → getWbiKey() / getMixinKey() / wbiSign() |
server/bilibili/video.go → GetVideoInfo / GetSeasonInfo / GetPlayInfo / GetFavlist / GetSeasonsArchivesList | Client.php 同名方法(返回数组而非结构体) |
server/bilibili/type.go → VideoInfo / SeasonInfo / PlayInfo / Dash / Media | Parser.php 里按需取字段,不做结构体映射 |
server/router/video.go → getVideoInfo / getSeasonInfo / getPlayInfo | Action.php → parseAction() 统一入口,自动识别链接类型 |
server/util/util.go → CheckBvidFormat / MD5Hash | Parser::parseInput() / md5() |
差异与增强:
- 原项目把 WBI 签名写好了但只用在测试里,实际请求没带签名;本插件在
wbi/view、wbi/playurl 上都会真正签名,并在失败时自动退回旧接口。 - 新增 WBI Key 24 小时缓存、解析结果缓存、视频流代理(原项目是本地下载,博客场景改为转发)。
- 登录凭证存进插件配置,扫码即写,不用手抄 Cookie。
- 补上了
bangumi/media/md 这类分享链接(media_id → season_id 二次查询,
参考 injahow/bilibili-parse 的 pgc/review/user 用法)。 - 未移植 bilibili-parse 的「付费课程 cheese /
pugv 接口」,它需要 access_key,博客场景用不上;
它那套 interface/app 旧版 API 签名(setAppkey)与随机 X-Real-IP 现在也已失效,没有参考。
离线自检
服务器上有 PHP 命令行时,可以不开浏览器先验证核心逻辑:
php usr/plugins/BiliParse/tests/selftest.php
会跑 76 项断言,覆盖链接识别(BV/av/ss/ep/b23.tv/合集/收藏夹)、WBI 签名与密钥重排、
代理域名白名单、MPD 生成、短代码渲染与转义、缓存读写过期、路由与钩子注册。
不联网、不碰真实数据库。只校验纯逻辑,不代表一定能解析成功(那取决于 B 站接口与你的 SESSDATA)。
注意事项
- 缓存目录优先用系统临时目录;若不可写会退到插件目录下的
cache/,再不行就禁用缓存。 - 代理只对
*.hdslb.com、*.bilivideo.com、*.bilibili.com 等白名单域名生效,
且地址带 HMAC 签名,不会被当作开放代理滥用。 - B 站 DASH 的音频与视频是分开的两条流,浏览器里通过 dash.js 合成播放;
「下载」拿到的是未合并的 .m4s,需要 ffmpeg 或播放器自行合并。 - 视频版权归 UP 主 / 哔哩哔哩所有,请仅用于个人学习或已获授权的转载。
许可
解析逻辑源自 iuroc/bilidown(MIT 风格开源项目),
本插件 PHP 实现部分同样遵循宽松开源精神,仅供学习交流。