B站视频时长统计:一段JS脚本搞定分P/合集总时长(附倍速计算)
前言
追B站的分P教程或合集剧时,经常想知道"全P看完要多久""2倍速几天能刷完"。网上流传的书签脚本大多基于 DOM 类名(如 .duration、.cur-list)解析,B站 2023 年改版后选择器换成 video-episode-card__info-duration,老代码基本失效。
本文提供一个更抗改版的思路:直接调 B 站官方接口 api.bilibili.com/x/web-interface/view 拉取分P/合集数据,不依赖页面 DOM,只要接口在就能用。
支持两种运行方式:Console 控制台版(推荐)和书签版,均支持指定集数区间 和倍速换算。
方式一:Console 控制台版(推荐)
- 打开任意带分P或合集的B站视频页(URL 形如
bilibili.com/video/BVxxxx/?p=1) - 按
F12打开开发者工具,切到 Console 标签 - 粘贴以下代码,回车运行
⚠️ Chrome/Edge 首次粘贴会提示安全警告,需先手动输入
allow pasting回车开启粘贴权限。
js
(async () => {
// ① 从 URL 抠出 BV 号
const m = location.href.match(/BV[0-9A-Za-z]+/);
if (!m) { alert('请在 B 站视频页运行,未识别到 BV 号'); return; }
// ② 调 B 站官方接口拿视频信息(含分P / 合集)
const r = await fetch(`https://api.bilibili.com/x/web-interface/view?bvid=${m[0]}`)
.then(res => res.json());
if (r.code !== 0) { alert('接口返回异常:' + r.message); return; }
// ③ 兼容两种形态:单视频多P / 合集
let items = [];
if (r.data.pages && r.data.pages.length > 1) {
items = r.data.pages.map(p => ({ title: p.part, dur: p.duration }));
} else if (r.data.ugc_season) {
r.data.ugc_season.sections.forEach(sec =>
sec.episodes.forEach(ep =>
items.push({ title: ep.title, dur: ep.duration })));
}
if (!items.length) { alert('该视频只有一P,也没在合集里'); return; }
// ④ 统计区间
const input = prompt(`共 ${items.length} 个视频。\n输入区间如 5-20(直接确定=全部)`, `1-${items.length}`);
if (input === null) return;
let [a, b] = input.trim().split('-').map(Number);
if (!a || a < 1) a = 1;
if (!b || b > items.length) b = items.length;
const slice = items.slice(a - 1, b);
// ⑤ 求和 + 格式化
const total = slice.reduce((s, it) => s + (it.dur || 0), 0);
const fmt = s => {
const h = Math.floor(s/3600), m = Math.floor(s%3600/60), sec = s%60;
return h ? `${h}小时${m}分${sec}秒`
: m ? `${m}分${sec}秒`
: `${sec}秒`;
};
// ⑥ 倍速换算
const sp = parseFloat(prompt('按几倍速看?(直接确定=原速)', '1')) || 1;
const spTotal = Math.round(total / sp);
alert(`📊 统计结果\n━━━━━━━━━━\n范围:第 ${a} ~ ${b} 集(共 ${slice.length} 个)\n原时长:${fmt(total)}\n${sp}x 倍速看完:${fmt(spTotal)}`);
})();
运行效果(以 84 集合集为例):
📊 统计结果
━━━━━━━━━━
范围:第 1 ~ 84 集(共 84 个)
原时长:33小时35分12秒
1x 倍速看完:33小时35分12秒
方式二:书签版(可反复点击)
代码与上面完全一致,只是换个存放位置:
- 书签栏右键 → 添加网页/新书签
- 名称随意(如"B站时长统计"),网址栏粘贴整段代码
- ⚠️ Chrome/Edge 会自动吞掉开头的
javascript:,粘贴后手动补上,否则点击会变成搜索跳转 - 打开B站视频页 → 点击书签即可
常见问题排查
| 报错/现象 | 原因 | 解决 |
|---|---|---|
控制台报 Refused to paste |
Chrome/Edge 首次粘贴拦截 | Console 输入 allow pasting 回车后重贴 |
接口返回 -412 |
触发B站风控(登录态失效/频率过快) | 重新登录B站,或稍等几秒再跑 |
| 提示"只有一P,也没在合集里" | 打开的是单P视频 | 换带分P列表/合集侧栏的视频页 |
| 书签点完没反应 | javascript: 前缀被浏览器吞掉 |
编辑书签,确认开头为 javascript: |
原理说明
为什么不用 DOM 解析:
- 老方案依赖页面类名(
.duration等),B站前端一改版就失效 web-interface/view是B站官方公开接口,返回 JSON 中直接带有:pages[]:多P视频的每P标题与duration(秒)ugc_season.sections[].episodes[]:合集内每个视频的标题与时长
- 时长单位为秒,累加后做一次进制换算即可
局限与备注
- 仅适用于分P视频 和UGC合集页面,单P视频、收藏夹、搜索页无数据可拉
- B站接口存在风控升级的可能(如 WBI 签名),若日后大量返回
-403/-412,需适配新签名 - 嫌每次粘贴麻烦的话,也可以在 Greasy Fork 搜索"B站合集时长统计"类油猴脚本,装完自动显示
总结
本文提供了一个基于B站官方 API 的视频时长统计脚本,相比老版 DOM 解析方案更抗改版,支持集数区间选择和倍速换算。Console 版适合临时用一次,书签版适合高频使用。觉得有用的话点个赞吧~