插件出处链接:
这个是一个可以统计b站分时长的javascript插件,
由于b站更新了html结构,导致原来的插件代码根据类名获取到对应的结构,因此我做了一些修复
将代码复制到浏览器书签保存即可使用
下面是我修复稍微改进了一下的版本,增加了关闭按钮,和鼠标拖拽功能。防止出现遮挡:
javascript: (function () {
var hostname = window.location.hostname;
var pathname = window.location.pathname;
if (hostname !== "www.bilibili.com" || !pathname.startsWith("/video/BV")) {
alert("该代码仅在 B站视频页面 (https://www.bilibili.com/video/BV...) 上运行");
return;
}
var hour = 0;
var minute = 0;
var second = 0;
var durations = document.getElementsByClassName('duration');
var page = durations.length;
function f1() {
hour = 0;
minute = 0;
second = 0;
var min = 0;
var sec = 0;
if (document.getElementById('divChild')) {
document.getElementById('divChild').remove();
}
if (
parseInt(input1.value) >= 1 &&
parseInt(input1.value) <= page &&
parseInt(input2.value) <= page &&
parseInt(input1.value) <= parseInt(input2.value)
) {
for (var i = parseInt(input1.value) - 1; i < parseInt(input2.value); i++) {
var time = durations[i].innerHTML.trim();
var t = time.split(':').map(Number);
if (t.length == 3) {
var h = t[0];
var m = t[1];
var s = t[2];
} else {
var h = 0;
var m = t[0];
var s = t[1];
}
hour += h;
minute += m;
sec += s;
}
minute += Math.floor(sec / 60);
second = sec % 60;
minute += min;
hour += Math.floor(minute / 60);
minute = minute % 60;
if (input3.value != 1) {
var total = hour * 3600 + minute * 60 + second;
total = total / input3.value;
hour = Math.floor(total / 3600);
minute = Math.floor((total % 3600) / 60);
second = Math.floor(total % 60);
}
var d1 = document.createElement('div');
d1.style.cssText = "margin-top:15px";
d1.setAttribute("id", "divChild");
d.appendChild(d1);
var t1 = document.createTextNode(
"全" + (parseInt(input2.value) - parseInt(input1.value) + 1) +
"集: " + hour + "时" + minute + "分" + parseInt(second) + "秒"
);
d1.appendChild(t1);
} else {
var d1 = document.createElement('div');
d1.style.cssText = "margin-top:15px";
d1.setAttribute("id", "divChild");
d.appendChild(d1);
var t1 = document.createTextNode("输入与实际集数不符");
d1.appendChild(t1);
}
}
function over() {
btn.style.backgroundColor = "#E4E4E4";
}
function out() {
btn.style.backgroundColor = "#F4F4F4";
}
function closePanel() {
var panel = document.getElementById('statPanel');
if (panel) {
panel.remove();
}
}
function makeDraggable(element) {
var isDragging = false;
var offsetX = 0, offsetY = 0;
element.addEventListener('mousedown', function (e) {
isDragging = true;
offsetX = e.clientX - element.offsetLeft;
offsetY = e.clientY - element.offsetTop;
element.style.cursor = 'move';
});
document.addEventListener('mousemove', function (e) {
if (isDragging) {
element.style.left = e.clientX - offsetX + 'px';
element.style.top = e.clientY - offsetY + 'px';
}
});
document.addEventListener('mouseup', function () {
isDragging = false;
element.style.cursor = 'default';
});
}
var body = document.body;
var d = document.createElement("div");
d.style.cssText = "padding-top:15px;width:145px;height:165px;background-color:#F4F4F4;position:absolute;right:20px;top:218px;border:1px solid #00A1D6;color:#00A1D6;z-index:999;text-align:center;font-size:14px";
d.setAttribute("id", "statPanel");
body.appendChild(d);
var d2 = document.createElement("div");
d.appendChild(d2);
var t2 = document.createTextNode("第");
d2.appendChild(t2);
var input1 = document.createElement('input');
input1.setAttribute("type", "number");
input1.style.cssText = "border: 1px solid deepskyblue;width:40px";
d2.appendChild(input1);
var t3 = document.createTextNode("集到");
d2.appendChild(t3);
var input2 = document.createElement('input');
input2.setAttribute("type", "number");
input2.style.cssText = "border: 1px solid deepskyblue;width:40px";
d2.appendChild(input2);
var t4 = document.createTextNode("集");
d2.appendChild(t4);
var btn = document.createElement('input');
btn.setAttribute("type", "button");
btn.setAttribute("value", "计算");
btn.style.cssText = "width:50px;margin-top:15px;border: 1px solid #00A1D6;cursor:pointer";
d.appendChild(btn);
btn.onclick = f1;
btn.onmouseover = over;
btn.onmouseout = out;
var t5 = document.createTextNode("倍速:");
d2.appendChild(t5);
var input3 = document.createElement('input');
input3.setAttribute("type", "number");
input3.style.cssText = "border: 1px solid deepskyblue;width:50px;margin-top:15px;margin-right:10px";
input3.value = 1;
d2.appendChild(input3);
var t6 = document.createTextNode("倍");
d2.appendChild(t6);
var closeBtn = document.createElement('input');
closeBtn.setAttribute("type", "button");
closeBtn.setAttribute("value", "关闭");
closeBtn.style.cssText = "width:50px;margin-top:10px;border: 1px solid red;cursor:pointer;color:red";
closeBtn.onclick = closePanel;
d.appendChild(closeBtn);
makeDraggable(d);
})();
现在可以恢复正常工作了,并且可以被拖拽了
根据元素选择器发现视频分集的时长里面,对应的类名发生的变化,修复代码即可
下面是有注释的版本,可以参考学习
javascript: (function () {
// 检查当前页面是否是 B站视频页面
var hostname = window.location.hostname;
var pathname = window.location.pathname;
if (hostname !== "www.bilibili.com" || !pathname.startsWith("/video/BV")) {
alert("该代码仅在 B站视频页面 (https://www.bilibili.com/video/BV...) 上运行");
return;
}
// 初始化时间统计变量
var hour = 0; // 累计的小时数
var minute = 0; // 累计的分钟数
var second = 0; // 累计的秒数
var durations = document.getElementsByClassName('duration'); // 获取视频时长的元素
var page = durations.length; // 视频总集数
// 定义计算时间的函数
function f1() {
hour = 0;
minute = 0;
second = 0;
var min = 0; // 临时变量,用于累积当前循环中的分钟
var sec = 0; // 临时变量,用于累积当前循环中的秒数
// 如果统计结果已存在,移除旧的结果显示
if (document.getElementById('divChild')) {
document.getElementById('divChild').remove();
}
// 验证用户输入范围是否正确
if (
parseInt(input1.value) >= 1 &&
parseInt(input1.value) <= page &&
parseInt(input2.value) <= page &&
parseInt(input1.value) <= parseInt(input2.value)
) {
// 遍历用户选择的集数范围
for (var i = parseInt(input1.value) - 1; i < parseInt(input2.value); i++) {
var time = durations[i].innerHTML.trim(); // 获取视频时长文本
var t = time.split(':').map(Number); // 将时长解析为数组
// 根据时长格式(hh:mm:ss 或 mm:ss)进行解析
if (t.length == 3) {
var h = t[0];
var m = t[1];
var s = t[2];
} else {
var h = 0;
var m = t[0];
var s = t[1];
}
hour += h; // 累积小时
minute += m; // 累积分钟
sec += s; // 累积秒数
}
// 将秒数进位为分钟,并计算剩余秒数
minute += Math.floor(sec / 60);
second = sec % 60;
// 将分钟进位为小时,并计算剩余分钟数
hour += Math.floor(minute / 60);
minute = minute % 60;
// 如果选择了倍速播放,调整总时长
if (input3.value != 1) {
var total = hour * 3600 + minute * 60 + second; // 总秒数
total = total / input3.value; // 按倍速调整
hour = Math.floor(total / 3600);
minute = Math.floor((total % 3600) / 60);
second = Math.floor(total % 60);
}
// 创建统计结果显示的元素
var d1 = document.createElement('div');
d1.style.cssText = "margin-top:15px";
d1.setAttribute("id", "divChild");
d.appendChild(d1);
var t1 = document.createTextNode(
"全" + (parseInt(input2.value) - parseInt(input1.value) + 1) +
"集: " + hour + "时" + minute + "分" + parseInt(second) + "秒"
);
d1.appendChild(t1);
} else {
// 如果输入无效,提示用户
var d1 = document.createElement('div');
d1.style.cssText = "margin-top:15px";
d1.setAttribute("id", "divChild");
d.appendChild(d1);
var t1 = document.createTextNode("输入与实际集数不符");
d1.appendChild(t1);
}
}
// 鼠标悬停时改变按钮颜色
function over() {
btn.style.backgroundColor = "#E4E4E4";
}
// 鼠标移出时恢复按钮颜色
function out() {
btn.style.backgroundColor = "#F4F4F4";
}
// 关闭统计面板的函数
function closePanel() {
var panel = document.getElementById('statPanel');
if (panel) {
panel.remove();
}
}
// 使统计面板可拖拽的函数
function makeDraggable(element) {
var isDragging = false;
var offsetX = 0, offsetY = 0;
element.addEventListener('mousedown', function (e) {
isDragging = true;
offsetX = e.clientX - element.offsetLeft;
offsetY = e.clientY - element.offsetTop;
element.style.cursor = 'move';
});
document.addEventListener('mousemove', function (e) {
if (isDragging) {
element.style.left = e.clientX - offsetX + 'px';
element.style.top = e.clientY - offsetY + 'px';
}
});
document.addEventListener('mouseup', function () {
isDragging = false;
element.style.cursor = 'default';
});
}
// 创建主统计面板
var body = document.body;
var d = document.createElement("div");
d.style.cssText = "padding-top:15px;width:145px;height:165px;background-color:#F4F4F4;position:absolute;right:20px;top:218px;border:1px solid #00A1D6;color:#00A1D6;z-index:999;text-align:center;font-size:14px";
d.setAttribute("id", "statPanel");
body.appendChild(d);
// 创建输入区域
var d2 = document.createElement("div");
d.appendChild(d2);
var t2 = document.createTextNode("第");
d2.appendChild(t2);
var input1 = document.createElement('input');
input1.setAttribute("type", "number");
input1.style.cssText = "border: 1px solid deepskyblue;width:40px";
d2.appendChild(input1);
var t3 = document.createTextNode("集到");
d2.appendChild(t3);
var input2 = document.createElement('input');
input2.setAttribute("type", "number");
input2.style.cssText = "border: 1px solid deepskyblue;width:40px";
d2.appendChild(input2);
var t4 = document.createTextNode("集");
d2.appendChild(t4);
// 创建计算按钮
var btn = document.createElement('input');
btn.setAttribute("type", "button");
btn.setAttribute("value", "计算");
btn.style.cssText = "width:50px;margin-top:15px;border: 1px solid #00A1D6;cursor:pointer";
d.appendChild(btn);
btn.onclick = f1;
btn.onmouseover = over;
btn.onmouseout = out;
var t5 = document.createTextNode("倍速:");
d2.appendChild(t5);
var input3 = document.createElement('input');
input3.setAttribute("type", "number");
input3.style.cssText = "border: 1px solid deepskyblue;width:50px;margin-top:15px;margin-right:10px";
input3.value = 1;
d2.appendChild(input3);
var t6 = document.createTextNode("倍");
d2.appendChild(t6);
// 创建关闭按钮
var closeBtn = document.createElement('input');
closeBtn.setAttribute("type", "button");
closeBtn.setAttribute("value", "关闭");
closeBtn.style.cssText = "width:50px;margin-top:10px;border: 1px solid red;cursor:pointer;color:red";
closeBtn.onclick = closePanel;
d.appendChild(closeBtn);
// 启用拖拽功能
makeDraggable(d);
})();