b站辅助(时长/集数/倍速/单集循环)

辅助使用bilibili(时长/集数/倍速/单集循环)

目前为 2022-03-02 提交的版本。查看 最新版本

// ==UserScript==
// @name         b站辅助(时长/集数/倍速/单集循环)
// @namespace    http://tampermonkey.net/
// @version      1.0.0
// @description  辅助使用bilibili(时长/集数/倍速/单集循环)
// @author       eleky
// @match        https://www.bilibili.com/*
// @require      https://cdn.bootcss.com/jquery/3.5.0/jquery.min.js
// @icon         https://www.bilibili.com/favicon.ico
// @grant        none
// @license MIT
// ==/UserScript==

/*
### 功能
1. 统计视频已看时长、正在观看的这一集的时长、未看时长、总时长,显示到右侧。按“J”键。
2. 统计视频已看集数、正在看的集数、未看集数、总集数,显示到右侧。按“J”键。
3. 视频倍速播放及快捷键,按“,”或“<”速度减0.25,按“。”或“<”速度加0.25。b站自带的倍速调整会失效。
4. 打开视频后默认单集循环。按“J”键。
*/

/*
var jq = document.createElement('script');
jq.src = "https://cdn.bootcss.com/jquery/3.5.0/jquery.min.js";
document.getElementsByTagName('head')[0].appendChild(jq);
*/

let stop;
let speed = 1;

//let speed = 1;
//注册(不可用)按钮监听,
window.onkeydown = function(ev){
    document.getElementsByTagName("video")[0].playbackRate = speed;//倍速关键代码,初始化倍速
    //ev表示onkeydown事件对象,逗号/小于号是188,句号/大于号是190,回车是13,J是74
    if(ev.keyCode===190){
        speed += 0.25;
        //console.log("speed:" + speed);
        show_speed(speed);
        document.getElementsByTagName("video")[0].playbackRate = speed;//倍速关键代码
    }else if(ev.keyCode===188){
        speed -= 0.25;
        //console.log("speed:" + speed);
        show_speed(speed);
        document.getElementsByTagName("video")[0].playbackRate = speed;//倍速关键代码
    }else if(ev.keyCode===74){
        //主函数,统计集数和时长
        main();
        //选中洗脑循环
        select_repeat();
    }
}

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);//只是看起来选中了
}

/*
window.onkeydown = function(ev){
    console.log(ev.keyCode);
}
*/

//显示倍速
function show_speed(speed) {
    //找到显示位置
    let position = document.getElementsByClassName("bilibili-player-video-top")[0];

    //获取标签
    let tag = document.getElementById("mytag");
    let 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 = "X " + speed ;

    //数据添加到面板
    if (isNull){
        position.after(tag);
    }

    //定时消失
    sleep(1000).then(() => {
        $("#mytag").css("display", "none"); 
    })
}


function main() {

    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);
        
        //显示到网页
        show(looked_time_arr, looking_time_arr, undone_time_arr, all_time_arr, looked, number, all_num);
        //console.log("显示到网页:");
    //})
   
}

//单集视频显示时长
function show2() {
    //获取总时长
    let time_box = document.getElementsByClassName('bilibili-player-video-time-total')[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 = "<div>总时长:" + time_num + "</div>" ;

    //数据添加到面板
    if (isNull){
        plain.after(data_tag);
    }
    
}

//获取视频索引列表
function getVideoList() {
    let list_box = document.getElementsByClassName('list-box')[0];
    return list_box.childNodes;
}

//获取到当前观看视频的索引
function getCurrentLookVideoIndex(nodeList) {
    let index = null;
    for (let i = 0; i < nodeList.length; i++) {
        //当前观看的视频
        let current = nodeList[i];
        //延迟之后获取class值

        let class_name = current.className;

        //当前观看
        if (class_name==='watched on' || class_name==='on'){
            //console.log(class_name)  //类名
            index = i;
            //console.log("当前视频索引:"+index)
            break;
        }
        //循环结束时还没有获取到索引(正常不会之前,前面就跳出了)
        if (i === nodeList.length - 1){
            console.log("error")
        }

    }
    return index;
}

//获取到时间时间字符串
function getTimeArray(nodeList,start_index,end_index) {
    let parent_array = [];
    for (let i = start_index; i < end_index; i++) {
        // nodeList[i]代表列表中的每一个li
        let div = nodeList[i].getElementsByClassName("duration");
        //每个视频的时长
        let duration = div[0].innerHTML;
        //console.log(duration);   //格式:'09:29'

        //添加到数组
        let child_array = duration.split(":");
        if (child_array.length<3){
            //数组首部添加0
            child_array.unshift('0');
        }
        parent_array.push(child_array);

    }
    return parent_array;
}

//计算时间/格式化
function format(timeArray) {

    //console.log("视频列表长度:"+timeArray.length);  //如果为0没有数据,就出错了

    let h=0,m=0,s=0;
    for (let i = 0; i < timeArray.length; i++) {
        h += Number(timeArray[i][0]);
        m += Number(timeArray[i][1]);
        s += Number(timeArray[i][2]);
    }

    //将秒转换为分钟
    let temp1 = s/60;
    let m1 = Math.floor(temp1);
    m +=m1;

    //小于一分钟的转换为秒
    let s2 = ('0.'+String(temp1).split('.')[1])*60;

    //分钟转换为小时
    let temp = m/60;
    let h1 = Math.floor(temp);

    //小于一小时的转换为分钟
    let m2 = ('0.'+String(temp).split('.')[1])*60;


    //最终结果
    h +=h1;
    s =Math.floor(s2);
    m =Math.floor(m2);

    //分钟出现NaN,原因是因为没有分钟,全是小时,直接赋值
    if (isNaN(m)){
        m="0";
    }
    //同理
    if (isNaN(s)){
        s="0";
    }

    //console.log("小时:"+h);
    //console.log("分钟:"+m);
    //console.log("秒:"+s);

    return [h,m,s];

}

//在评论上显示
function show(looked_time_arr, looking_time_arr, undone_time_arr, all_time_arr, looked, number, all_num) {
    //找到显示面板
    let plain = document.getElementById("danmukuBox");

    let data_tag = document.getElementById("data_tag");

    let isNull = data_tag===null;

    //没有创建过这个标签就创建
    if (isNull){
        //创建
        data_tag = document.createElement("table");
        //console.log(data_tag)

        //id赋值,用于下次更新查找
        data_tag.setAttribute("id", "data_tag");
        data_tag.setAttribute("class", "multi-page-v1 small-mode");
        data_tag.setAttribute("width", "100%");
        
    }

    //写入html
    data_tag.innerHTML = "<tr><th></th><th>已看</th><th>正在</th><th>未看</th><th>全部</th></tr>" + show_Str();

    //数据添加到面板
    if (isNull){
        plain.after(data_tag);
    }

    $("#data_tag th,#data_tag td").css("width", "20%");
    $("#data_tag th,#data_tag td").css("padding", "5px");
    $("#data_tag th,#data_tag td").css("text-align", "center");

    function show_Str() {
        let looked_time = looked_time_arr.join(':');
        let looking_time =  looking_time_arr.join(':');
        let undone_time =  undone_time_arr.join(':');
        let all_time =  all_time_arr.join(':');
        let  l1 = "<tr><td>集数</td><td>"+ looked + "</td><td>" + 1 + "</td><td>" + number + "</td><td>" + all_num +"</td></tr>";
        let  l2 = "<tr><td>时长</td><td>"+ looked_time + "</td><td>" + looking_time + "</td><td>" + undone_time + "</td><td>" + all_time +"</td></tr>";

        return l1+l2; 
    }
}

//跳过充电鸣谢
function pass() {
    let jumpButton = '.bilibili-player-electric-panel-jump';
    setInterval(() => {
        if($(jumpButton).length > 0) {
            $(jumpButton).trigger('click')
        }
    }, 200)
}

//延时函数
function sleep (time) {
    return new Promise((resolve) => setTimeout(resolve, time));
}

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址