Greasy Fork

Greasy Fork is available in English.

bilibili关灯

bilibili关灯(把被新版B站藏起来的关灯按钮揪出来,在关闭弹幕按钮左边,还可以用快捷键,默认'A')

目前为 2021-06-17 提交的版本。查看 最新版本

// ==UserScript==
// @name         bilibili关灯
// @namespace    hhh2000
// @version      0.61
// @description  bilibili关灯(把被新版B站藏起来的关灯按钮揪出来,在关闭弹幕按钮左边,还可以用快捷键,默认'A')
// @author       hhh2000
// @include      *://*.bilibili.com/video/*
// @include      *://*.bilibili.tv/video/*
// @include      *://*.bilibili.com/bangumi/*
// @include      *://*.bilibili.tv/bangumi/*
// @require      https://cdn.staticfile.org/jquery/1.12.4/jquery.min.js
// @run-at       document-end
// @grant        none
// ==/UserScript==

function abc(e) {console.log(e)};

function waitForNode(nodeSelector, callback) {
    var node = nodeSelector();
    if (node) {
        callback(node);
    } else {
        setTimeout(function() { waitForNode(nodeSelector, callback); }, 100);
    }
}

function waitForTrue(ifTrue, callback) {
    if (ifTrue()) {
        callback();
    } else {
        setTimeout(function() { waitForTrue(ifTrue, callback); }, 100);
    }
}

function isFullScreen() {
    return $('#bilibiliPlayer').hasClass('mode-fullscreen');
}

function is_lightoff() { return $('#heimu').css('display') === 'block'; }
function lightoff() { $('.bilibili-player-video-btn-setting-right-others-content-lightoff input').click(); }

//关灯按钮样式
function lightoff_btn_css() {
    var body_brgb = 'rgb(160, 130, 110)';
    var dot_crgb = 'rgb(230, 200, 180)';
    var dot_brgb = 'rgb(50, 50, 50)';
    var dark_rgb = 'rgb(77, 77, 77)';
    if ($('#hhh_lightoff>.bui-switch-input')[0].checked === false) {  //关灯
        $('#hhh_lightoff .bui-switch-body:first').css('background-color', dark_rgb);
        $('#hhh_lightoff .bui-switch-body:first>.bui-switch-dot').css('color', dark_rgb);
    }
    else {
        $('#hhh_lightoff .bui-switch-body:first').css('background-color', body_brgb);
        $('#hhh_lightoff .bui-switch-body:first>.bui-switch-dot').css({'color': dot_crgb, 'background-color': dot_brgb});
    }
}

//关灯按钮
function lightoff_btn() {
    lightoff();
    if(is_lightoff() === $('#hhh_lightoff>.bui-switch-input')[0].checked) {  //checked==true开灯 false关灯
        $('#hhh_lightoff>.bui-switch-input')[0].checked = !$('#hhh_lightoff>.bui-switch-input')[0].checked;
    }
    lightoff_btn_css();
}

//显示提示
function showHint(upper_this, selector_str, text){
    $(".bilibili-player-volumeHint").css('display', 'none');  //隐藏提示
    $(selector_str+'>.bilibili-player-volumeHint-text').text(text);  //百分比显示
    var Hint = $(selector_str);  //显示及渐隐效果(抄bilibili^^)
    clearTimeout(upper_this.showHintTimer),
        Hint.stop().css("opacity", 1).show(),
        upper_this.showHintTimer = window.setTimeout((function() {
        Hint.animate({
            opacity: 0
        }, 300, (function() {
            $(this).hide()
        }
        ))
    }
    ), 1e3)
}

//非全屏滚轮音量调节 0~1, 0~1
function wheel_volumeHint(screenLeft, screenRight){
    //div(抄bilibili^^)
    var volumeHint = '<div id=hhh_volumeHint class="bilibili-player-volumeHint" style="opacity: 0; display: none;">\n'+
        '   <span class="bilibili-player-volumeHint-icon video-state-volume-max">\n'+
        '       <i class="bilibili-player-iconfont bilibili-player-iconfont-volume icon-24soundsmall"></i>\n'+
        '       <i class="bilibili-player-iconfont bilibili-player-iconfont-volume-max icon-24soundlarge"></i>\n'+
        '       <i class="bilibili-player-iconfont bilibili-player-iconfont-volume-min icon-24soundoff"></i>\n'+
        '   </span>\n'+
        '   <span class="bilibili-player-volumeHint-text">57%</span>\n'+
        '</div>';
    if($('#hhh_volumeHint').length === 0) $('.bilibili-player-video-wrap').append(volumeHint);

    //add wheelevent
    $('.bilibili-player-video-wrap').off('mousewheel.hhh_volumeHint');
    $('.bilibili-player-video-wrap').on('mousewheel.hhh_volumeHint', function(e){
        if(e.ctrlKey || e.altKey || e.shiftKey) return;
        var e_in_Hint = $(this).width() !== $(e.target).width();  //处理鼠标在提示上的情况
        var w = $(this).width();
        screenLeft = screenLeft<0?undefined:screenLeft>1?undefined:screenLeft;
        screenRight = screenRight<0?undefined:screenRight>1?undefined:screenRight;
        if(screenLeft === undefined || screenRight === undefined) {
            screenLeft = 0.3;
            screenRight = 0.7;
        }
        //非全屏及鼠标在屏幕指定位置时处理
        if(player.isFullScreen() === false && (e_in_Hint || (e.originalEvent.offsetX > w*screenLeft && e.originalEvent.offsetX < w*screenRight))) {
            e.preventDefault();  //阻止页面滚动
            var wheelDelta = e.originalEvent.wheelDelta;
            var volume = player.volume();
            if(wheelDelta >= 120) {  //向上滚动,减少音量
                player.volume(volume+0.03);
            } else if(wheelDelta <= -120) {  //向下滚动,增大音量
                player.volume(volume-0.03);
            }
            //console.log(this); var ve=e;
            showHint(this, '#hhh_volumeHint', Math.round(player.volume()*100)+'%');
        }
    });
}

//控制进度条
//.bilibili-player-setting-opacity 透明度
//.bilibili-player-setting-area 显示区域
//.bilibili-player-setting-speedplus 弹幕速度 等等
//利用系统mousedown事件
//'正数': right,  '负数': left,  -100 ~ +100
function set_progress(selector_str, percent){
    var selector = document.querySelector(selector_str);
    var e1 = new MouseEvent('mousedown'); var e2 = new MouseEvent('mouseup');
    var danmaku_setting_wrap = '.bilibili-player-video-danmaku-setting-wrap';
    var tip_selector = document.querySelector(selector_str+' .bui-thumb-tooltip');

    function calc_bar_len(percent){
        var p = percent - 10;
        p = p<0? 0: p>90? 90: p;
        return p<=40? p*2.5: (p-40)*2 + 40*2.5;
    }

    $(danmaku_setting_wrap).css({"display":"block"});

    var selector_rect = selector.getClientRects();
    var curr_percent = Number(tip_selector.innerHTML.slice(0,-1));
    var clientX = selector_rect[0].left + calc_bar_len(curr_percent + percent);
    e1.initMouseEvent('mousedown',1,1,window,1,0,0,clientX,0,0,0,0,0,0,null);
    e2.initMouseEvent('mouseup'  ,1,1,window,1,0,0,clientX,0,0,0,0,0,0,null);
    selector.dispatchEvent(e1); selector.dispatchEvent(e2);

    $(danmaku_setting_wrap).css({"display":"none"});
    return tip_selector.innerHTML.slice(0,-1);
}

//滚轮调节弹幕透明度(ctrl)
function wheel_opacity_wheel(){
    //div(抄bilibili^^)
    var div_opacity = '<div id=hhh_opacity class="bilibili-player-volumeHint" style="opacity: 0; display: none;">\n'+
        '   <span class="bilibili-player-volumeHint-text">57%</span>\n'+
        '</div>';
    if($('#hhh_opacity').length === 0) $('.bilibili-player-video-wrap').append(div_opacity);

    //add wheelevent
    $('.bilibili-player-video-wrap').off('mousewheel.hhh_opacity');
    $('.bilibili-player-video-wrap').on('mousewheel.hhh_opacity', function(e){
        if(e.ctrlKey === true) {
            e.preventDefault();  //阻止页面滚动
            e.stopPropagation();  //阻止冒泡
            var wheelDelta = e.originalEvent.wheelDelta;
            var opacity = -1;
            if(wheelDelta >= 120) {  //向上滚动,增大透明度
                opacity = set_progress('div.bilibili-player-setting-opacity', 5);
            } else if(wheelDelta <= -120) {  //向下滚动,减少透明度
                opacity = set_progress('div.bilibili-player-setting-opacity', -5);
            }
            if(opacity >= 0) showHint(this, '#hhh_opacity', '透 '+opacity+'%');
        }
    });
}

//主程序
function run(){
    waitForNode(() => document.querySelector('.bilibili-player-video-danmaku-switch .bui-switch-dot'),
                (node) => {

        var h5Player = $('#bilibiliPlayer .bilibili-player-video>video');

        //TEST
        //state
        var ON = true,
            OFF = false,
            config = {
                sets: {},
                getCheckboxSetting(key) {
                    return this.sets[key]['status'];
                },
                saveCheckboxSetting() {
                    for(var o in this){
                        if(o.indexOf('b_') === 0){
                            var op = this[o]['options'];
                            for(var k in op){
                                this.sets[k] = op[k];
                            }
                        }
                    }
                },
                b_playerCheckbox: {
                    options: {
                        hideSenderBar: { text: '隐藏弹幕栏', status: OFF, fn: 'hideOrShowSenderBar', tips: '发弹幕快捷键可显示' },
                        widescreenScroll2Top: { text: '宽屏时回到顶部', status: OFF, ban:['widescreenSetOnTop'], fn: 'setWidescreenPos' },
                        widescreenSetOnTop: { text: '宽屏时播放器置顶部', status: OFF, ban:['widescreenScroll2Top'], fn: 'setWidescreenPos' },
                        lightOffWhenPlaying: { text: '播放时自动关灯', status: ON, },
                        lightOnWhenPause: { text: '暂停时自动开灯', status: ON, },
                        ultraWidescreen: { text: '超宽屏', status: OFF, ban:['customUltraWidescreenHeight'], fn: 'ultraWidescreen', tips: '宽屏模式宽度和窗口一样'},
                        customUltraWidescreenHeight: { text: '自定义超宽屏高度', status: OFF, ban:['ultraWidescreen'], fn: 'customUltraWidescreenHeight', tips: '最大高度和窗口一样'},
                        customPlayerHeight: { text: '自定义播放器高度', status: OFF, fn: 'customPlayerHeight', tips: '最大高度和窗口一样' },
                        bottomTitle: { text: '标题位于播放器下方', status: OFF, tips: '刷新生效' },
                        danmukuBoxAfterMultiPage: { text: '新版弹幕列表在视频选集下方', status: OFF, tips: '刷新生效' }
                    },
                    btn: '设置'
                }
            }
        config.saveCheckboxSetting();

        //防止重复加载
        if ($('.bilibili-player-video-danmaku-switch .bui-switch-dot').length !== 1) return;

        //插入关灯按钮
        $("div.bilibili-player-video-danmaku-switch:first").clone().prependTo("div.bilibili-player-video-danmaku-root:first");
        $("div.bilibili-player-video-danmaku-switch:first")[0].id = 'hhh_lightoff';
        $('#hhh_lightoff .bui-switch-dot>span').remove();
        $('#hhh_lightoff .bui-switch-dot')[0].innerHTML = '灯';

        //点击关灯
        $('#hhh_lightoff>.bui-switch-input:first').click(function(){
            lightoff_btn();
            //console.log(this.checked);
            //$('.bilibili-player-video-btn-setting-right-others-content-lightoff>input').click();
            //lightoff_btn_css();
        });

        //键盘关灯等
        var opacity = -1;
        var x = 0;
        $(document).off('keydown.hhh_lightoff');
        $(document).on('keydown.hhh_lightoff',function(e){
            if(e.keyCode === 'A'.charCodeAt()){  //开关灯
                lightoff_btn();
                //实际点击按钮和调用点击事件bui-switch-input')[0].checked值不同,需要下面这句
                //$('.bilibili-player-video-danmaku-switch>.bui-switch-input')[0].checked = !$('.bilibili-player-video-danmaku-switch>.bui-switch-input')[0].checked;
                //$('.bilibili-player-video-btn-setting-right-others-content-lightoff>input').click();
                //lightoff_btn_css();
            } else if(e.keyCode === 'W'.charCodeAt()) {  //网页全屏
                $('.bilibili-player-video-web-fullscreen').click();
            } else if(e.keyCode === 'Q'.charCodeAt()) {  //宽屏模式
                isFullScreen() ? $('.bilibili-player-video-btn-fullscreen').click() : $('.bilibili-player-video-btn-widescreen').click();
            } else if(e.keyCode === 'D'.charCodeAt()) {  //开关弹幕
                $('.bilibili-player-video-danmaku-switch>.bui-switch-input:last').click();
            } else if(e.keyCode === 'T'.charCodeAt()) {  //开关顶端弹幕
                $('.bilibili-player-block-filter-type[ftype=top]').click();
            } else if(e.keyCode === 'B'.charCodeAt()) {  //开关底端弹幕
                $('.bilibili-player-block-filter-type[ftype=bottom]').click();
            } else if(e.keyCode === 'R'.charCodeAt()) {  //开关洗脑循环
                $(".bilibili-player-video-btn-setting-left-repeat>.bui-switch-input").click();
            } else if(e.keyCode === 'Z'.charCodeAt()) {  //-弹幕透明度
                opacity = set_progress('div.bilibili-player-setting-opacity', -10);
                if(opacity >= 0) showHint(this, '#hhh_opacity', '透 '+opacity+'%');
            } else if(e.keyCode === 'C'.charCodeAt()) {  //+弹幕透明度
                //var e1 = new WheelEvent('mousewheel', {deltaX:120,deltaY:120,deltaZ:120,ctrlKey:true});
                //$('.bilibili-player-video-wrap')[0].dispatchEvent(e1)
                opacity = set_progress('div.bilibili-player-setting-opacity', 10);
                if(opacity >= 0) showHint(this, '#hhh_opacity', '透 '+opacity+'%');
            } else if(e.keyCode === 38 || e.keyCode === 40) {  //up+down arrow //系统音量提示显示时隐藏自定义音量提示
                 $(".bilibili-player-volumeHint").css('display', 'none');
            }
        });

        //初始化关灯按钮
        lightoff_btn_css();

        //一些CLASS命名
        var danmaku_setting    = '.bilibili-player-video-danmaku-setting';
        var video_setting      = '.bilibili-player-video-btn.bilibili-player-video-btn-setting';
        var video_setting_wrap = '.bilibili-player-video-btn-setting-wrap';

        //激活系统弹幕设置,以此使用网页全屏等
        $(danmaku_setting).mouseenter().mouseleave();

        //激活系统关灯设置,以此使用关灯
        //去掉mouseout(),否则如果太快执行mouseout()无法激活关灯class,应该是mouseenter()未执行完就被mouseout打断了
        $(video_setting).mouseenter();

        //避免显示激活页面
        waitForNode(() => document.querySelector(video_setting_wrap),
                    (node) => {
            $(node).css({"visibility":"hidden"});  //visible
        })

        //解决因为激活关灯class,导致全屏时滚轮无法调节音量的问题
        waitForTrue(()=>$(video_setting_wrap).css('display') === 'block',
                    () => {
            $(video_setting_wrap).css('display', 'none').css('visibility', 'visible');
        });

        //非全屏滚轮音量调节
        wheel_volumeHint(0.35, 0.65);

        //滚轮调节弹幕透明度(ctrl)
         wheel_opacity_wheel();

        //addEventListener
        player.addEventListener('video_media_playing', () => config.getCheckboxSetting('lightOffWhenPlaying') === ON && !is_lightoff() && lightoff_btn());
        player.addEventListener('video_media_pause', () => config.getCheckboxSetting('lightOnWhenPause') === ON && is_lightoff() && lightoff_btn());

        //自动运行
        var STATAS = 'ON';    // ON | ALLOFF
        if('ON'===STATAS && $('.bilibili-player-video-btn-setting-left-autoplay>.bui-switch-input')[0].checked === false)  //开启自动播放
            $(".bilibili-player-video-btn-setting-left-autoplay>.bui-switch-input").click();
        if('ON'===STATAS) $(".bilibili-player-video-btn-setting-left-repeat>.bui-switch-input").click();  //开启洗脑循环
        if('OFF'===STATAS) lightoff_btn();  //自动关灯

    });
}

function init() {
    //内部加载视频窗口
    waitForNode(() => document.querySelector('video'),
        (node) => {
        var oV = document.getElementsByTagName("video")[0];
        oV.addEventListener('DOMNodeInserted', () => {
            run();
        });
    });

    run();
}

window.onload = init();