// ==UserScript== // @name b站辅助(时长/集数/倍速/单集循环) // @namespace http://tampermonkey.net/ // @version 1.0.2 // @description 更好地使用bilibili(b站)!统计分集视频和视频合集的时长和集数(已看时长、未看时长、总时长、集数..);增强倍速功能,最高16倍速;单集循环快捷键..。 // @author eleky // @match https://www.bilibili.com/* // @icon https://www.bilibili.com/favicon.ico // @grant none // @license MIT // @downloadURL https://update.greasyfork.icu/scripts/440792/b%E7%AB%99%E8%BE%85%E5%8A%A9%EF%BC%88%E6%97%B6%E9%95%BF%E9%9B%86%E6%95%B0%E5%80%8D%E9%80%9F%E5%8D%95%E9%9B%86%E5%BE%AA%E7%8E%AF%EF%BC%89.user.js // @updateURL https://update.greasyfork.icu/scripts/440792/b%E7%AB%99%E8%BE%85%E5%8A%A9%EF%BC%88%E6%97%B6%E9%95%BF%E9%9B%86%E6%95%B0%E5%80%8D%E9%80%9F%E5%8D%95%E9%9B%86%E5%BE%AA%E7%8E%AF%EF%BC%89.meta.js // ==/UserScript== /* ### 功能 1. 统计视频已看时长、正在观看的这一集的时长、未看时长、总时长,显示到右侧。按“j”或“J”键。 2. 统计视频已看集数、正在看的集数、未看集数、总集数,显示到右侧。按“j”或“J”键。 3. 视频倍速播放及快捷键,按“,”或“<”速度减0.25,按“。”或“<”速度加0.25。b站自带的倍速调整会失效。 4. 设置单集循环,按“k”或“K”键。 */ window.onload = function () { console.log("b站辅助(时长/集数/倍速/单集循环)..."); var jq = document.createElement('script'); jq.setAttribute('type', 'text/javascript'); jq.src = "https://cdn.bootcss.com/jquery/3.5.0/jquery.min.js"; document.getElementsByTagName('head')[0].appendChild(jq); var rate = 1; var stop = 1; var videoSelector = "bwp-video"; // 视频元素选择器 var keyMap = { forward0_25: '.', // 速度增加 0.25x back0_25: ',', // 速度减少 0.25x rate1: '1', // 设为 1x rate3: '3', // 设为 3x stats_key: 'j', stats_key2: 'J', select_repeat: 'k', select_repeat2: 'K', }; var el = document.querySelector(videoSelector) || document.querySelector('video'); window.addEventListener('keydown', (e) => { // console.log("e.key ",e.key); if (e.key === keyMap.rate1) { rate = 1; } else if (e.key === keyMap.rate3) { rate = 3; } else if (e.key === keyMap.forward0_25 && rate < 16) { rate += 0.25; } else if (e.key === keyMap.back0_25 && rate > 0.25) { rate -= 0.25; } else if (e.key === keyMap.stats_key || e.key === keyMap.stats_key2) { stats(); // 统计集数和时长 // showVideoInfo("stats"); return; } else if (e.key === keyMap.select_repeat || e.key === keyMap.select_repeat2) { select_repeat(); // 选中洗脑循环 // showVideoInfo("repeat"); return; } else { return; } setVideoRate(); showVideoInfo("X" + rate); }) // window.onkeydown = function(ev){ // console.log(ev.keyCode); // } function setVideoRate() { if (el) { el.playbackRate = rate; } } function showVideoInfo(info) { //显示倍速 //找到显示位置 var position = document.getElementsByClassName("bpx-player-video-area")[0]; //获取标签 var tag = document.getElementById("mytag"); var isNull = tag === null; //没有创建过这个标签就创建 if (isNull) { //创建显示标签 tag = document.createElement("div"); tag.setAttribute("id", "mytag"); tag.style = '\n' + ' width: 50px;\n' + ' height: 28px;\n' + ' background-color: #666666;\n' + ' position: absolute;\n' + ' top: 50%;\n' + ' left: 50%;\n' + ' transform: translate(-50%, -50%);\n' + ' border-radius: 2px;\n' + ' z-index: 99999999;\n' + ' text-align: center;\n' + ' line-height: 28px;\n' + ' font-size: 14px;\n' + ' color: #fff;\n' + ' '; } $("#mytag").css("display", "block"); //写入html tag.innerHTML = info; //数据添加到面板 if (isNull) { position.after(tag); } //定时消失 sleep(1000).then(() => { $("#mytag").css("display", "none"); }) } // function select_repeat() { // 原写法,没用 // //$(".bilibili-player-iconfont .bilibili-player-iconfont-setting").trigger('mouseover'); // $(".bilibili-player-video-btn-setting").trigger('mouseover'); //使循环播放按钮出现 // $(".bilibili-player-video-btn-setting").trigger('mouseout'); //使循环播放按钮消失 // //let setting = document.querySelector(".bilibili-player-iconfont .bilibili-player-iconfont-setting"); // //setting.click(); // $(".bilibili-player-video-btn-setting-left-repeat .bui-switch-input").trigger('click'); //真实选中洗脑循环 // $(".bilibili-player-video-btn-setting-left-repeat .bui-switch-input").attr('checked', true); //只是看起来选中了 // // var a = document.getElementsByClassName("bpx-player-ctrl-btn bpx-player-ctrl-setting")[0]; // // // 不通过鼠标,自动 mouseover 事件。其他事件也类推。 // // var ev = new Event("mouseover"); // // a.dispatchEvent(ev); // } //获取设置列表 function select_repeat() { var setting_btn = document.getElementsByClassName("bpx-player-ctrl-btn bpx-player-ctrl-setting")[0]; var setting_list = setting_btn.getElementsByClassName("bpx-player-ctrl-setting-box")[0]; var setting_repeat = setting_list.getElementsByTagName("input")[1]; // 此时setting_repeat = // var ev_click = new Event("click");// 这么写没用 // setting_repeat.dispatchEvent(ev_click); setting_repeat.click(); } function stats() { let nodeList; try { //获取视频列表节点 nodeList = getVideoList(); // console.log("已获取视频列表节点"); } catch (e) { console.log("没有视频列表,不是视频选集"); show2(); //单集视频显示时长 clearInterval(stop); return; } //sleep(10000).then(() => { //获取当前观看索引 let index = getCurrentLookVideoIndex(nodeList); // console.log("当前观看索引:" + index); //全部视频个数 let all_num = nodeList.length; // console.log("全部视频个数:" + all_num); //已看视频个数 let looked = index; // console.log("已看视频个数:" + looked); //未看视频个数 let number = all_num - index - 1; // console.log("未看视频个数:" + number); //获取视频全部时间的数组 let allTime = getTimeArray(nodeList, 0, nodeList.length); // console.log("视频全部时间的数组:" + allTime); //所有时间数组,格式 [h,m] let all_time_arr = format(allTime); // console.log("所有时间数组,格式 [h,m,s]:" + all_time_arr); //获取已观看的视频时间数组 let looked_time = getTimeArray(nodeList, 0, index); // console.log("已观看的视频时间数组:" + looked_time); //已看时间数组,格式 [h,m] let looked_time_arr = format(looked_time); // console.log("已看时间数组,格式 [h,m,s]:" + looked_time_arr); //获取正在观看的视频时间数组 let looking_time = getTimeArray(nodeList, index, index + 1); // console.log("正在观看的视频时间数组:" + looking_time); //正在观看时间数组,格式 [h,m] let looking_time_arr = format(looking_time); // console.log("正在观看时间数组,格式 [h,m,s]:" + looking_time_arr); //获取未观看的视频时间数组 let timeArray = getTimeArray(nodeList, index + 1, nodeList.length); // console.log("未观看的视频时间数组:" + timeArray); //未看时间数组,格式 [h,m] let undone_time_arr = format(timeArray); // console.log("未看时间数组,格式 [h,m,s]:" + undone_time_arr); //显示到网页 // console.log("begin 显示到网页"); show(looked_time_arr, looking_time_arr, undone_time_arr, all_time_arr, looked, number, all_num); // console.log("end 显示到网页"); //}) } //单集视频显示时长 function show2() { //获取总时长 let time_box = document.getElementsByClassName('bpx-player-ctrl-time-duration')[0]; let time_num = time_box.innerHTML; //console.log("显示到网页:" + time_num); //找到显示位置 let plain = document.getElementById("danmukuBox"); let data_tag = document.getElementById("data_tag"); let isNull = data_tag === null; //没有创建过这个标签就创建 if (isNull) { //创建 data_tag = document.createElement("div"); //console.log(data_tag) //id赋值,用于下次更新查找 data_tag.setAttribute("id", "data_tag"); data_tag.setAttribute("width", "100%"); } //写入html data_tag.innerHTML = "