Greasy Fork

Greasy Fork is available in English.

bilibili关灯

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

当前为 2021-06-29 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         bilibili关灯
// @namespace    hhh2000
// @version      0.7.4
// @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-start
// @grant        none
// ==/UserScript==

'use strict';
hhh_lightoff_main = {
    init() {
        var //config
            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: {
                        lightOffWhenPlaying: { text: '播放时自动关灯', status: OFF },
                        lightOnWhenPause: { text: '暂停时自动开灯', status: OFF },
                        autoPlay: { text: '开启自动播放', status: OFF, fn: '', tips: '' },
                        repeat: { text: '开启洗脑循环', status: OFF, tips: '' },
                        lightOff: { text: '自动关灯', status: OFF, tips: '' },
                        volumeControlWhenNonFullScreen: { text: '开启非全屏音量调节', status: ON, tips: '' },
                        danmuOpacityControl: { text: '开启弹幕透明度控制', status: ON, tips: '' },  //ctrl+滚轮
                        removeVideoTopMask: { text: '去掉顶部mask', status: ON, tips: '' }
                    },
                    btn: '设置'
                }
            };

        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 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(parent, selector_str, text){
            $(".bilibili-player-volumeHint").css('display', 'none');  //隐藏所有提示,避免重叠
            $(selector_str+'>.bilibili-player-volumeHint-text').text(text);  //百分比显示
            //$(selector_str+'>.bilibili-player-volumeHint-text').css({'position': 'relative', 'left': '-10px'});
            //$(selector_str).width(100);
            var Hint = $(selector_str);  //显示及渐隐效果(抄bilibili^^)
            clearTimeout(parent.showHintTimer),
                Hint.stop().css("opacity", 1).show(),
                parent.showHintTimer = window.setTimeout((function() {
                Hint.animate({
                    opacity: 0
                }, 300, (function() {
                    $(this).hide()
                }
                ))
            }
            ), 1e3)
        }
        //非全屏滚轮音量调节 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 (player.isFullScreen() === true) {  //全屏退出
                    $(".bilibili-player-volumeHint").css('display', 'none');  //隐藏所有提示,避免重叠
                    return;
                }
                if(e.ctrlKey || e.altKey || e.shiftKey) return;
                //屏幕百分比参数
                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 }
                //非暂停 && 鼠标在屏幕指定位置时处理
                var w = $(this).width();
                var e_in_Hint = w !== $(e.target).width();  //处理鼠标在提示上的情况
                var inLimit = e_in_Hint || (e.originalEvent.offsetX > w*screenLeft && e.originalEvent.offsetX < w*screenRight);
                if(player.getState() !== 'PAUSED' && inLimit) {
                    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);
                    }
                    showHint(this, '#hhh_volumeHint', Math.round(player.volume()*100)+'%');
                }
            });
        }
        /*
         * 调节透明度
         * 利用系统mousedown事件
         * '正数': right,  '负数': left,  -100 ~ +100
         */
        function adjust_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"});

            $('.bilibili-player-video-danmaku-setting').mouseleave();  //激活设置,记忆进度条位置
            return tip_selector.innerHTML.slice(0,-1);
        }
        /*
         * 控制进度条
         * .bilibili-player-setting-opacity 透明度
         * .bilibili-player-setting-area 显示区域
         * .bilibili-player-setting-speedplus 弹幕速度 等
         * 利用系统mousedown事件
         * 0 ~ 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';

            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 clientX = selector_rect[0].left + calc_bar_len(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"});

            $('.bilibili-player-video-danmaku-setting').mouseleave();  //激活设置,记忆进度条位置
        }
        //滚轮调节弹幕透明度(ctrl)
        function wheel_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 = adjust_progress('div.bilibili-player-setting-opacity', 5);
                    } else if(wheelDelta <= -120) {  //向下滚动,减少透明度
                        opacity = adjust_progress('div.bilibili-player-setting-opacity', -5);
                    }
                    if(opacity >= 0) showHint(document, '#hhh_opacityHint', '透 '+opacity+'%');
                }
            });
        }
        //主程序
        function run(){
            waitForNode(() => document.querySelector('.bilibili-player-video-danmaku-switch .bui-switch-dot'),
                        (node) => {

                //保存设置信息
                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() });

                //键盘关灯等
                var opacity;
                var parent = document;
                $(document).off('keydown.hhh_lightoff');
                $(document).on('keydown.hhh_lightoff',function(e){
                    if(e.keyCode === 'A'.charCodeAt()){  //开关灯
                        lightoff_btn();
                        player.getPlayerState().lightOn === true ? showHint(parent, '#hhh_wordsHint', '开灯') : showHint(parent, '#hhh_wordsHint', '关灯');
                    } else if(e.keyCode === 'W'.charCodeAt()) {  //网页全屏
                        $('.bilibili-player-video-web-fullscreen').click();
                    } else if(e.keyCode === 'Q'.charCodeAt()) {  //宽屏模式
                        player.isFullScreen() ? $('.bilibili-player-video-web-fullscreen').click() : $('.bilibili-player-video-btn-widescreen').click();
                    } else if(e.keyCode === 'D'.charCodeAt()) {  //开关弹幕
                        $('.bilibili-player-video-danmaku-switch>.bui-switch-input:last').click();
                        player.getPlayerState().danmaku.show === true ? showHint(parent, '#hhh_wordsHint', '开弹幕') : showHint(parent, '#hhh_wordsHint', '关弹幕');
                    } else if(e.keyCode === 'T'.charCodeAt()) {  //开关顶部弹幕
                        $('.bilibili-player-block-filter-type[data-name=ctlbar_danmuku_top_close]').length === 0 ? showHint(parent, '#hhh_wordsHint', '关闭顶部弹幕') : showHint(parent, '#hhh_wordsHint', '打开顶部弹幕');
                        $('.bilibili-player-block-filter-type[ftype=top]').click();
                    } else if(e.keyCode === 'B'.charCodeAt()) {  //开关底部弹幕
                        $('.bilibili-player-block-filter-type[data-name=ctlbar_danmuku_bottom_close]').length === 0 ? showHint(parent, '#hhh_wordsHint', '关闭底部弹幕') : showHint(parent, '#hhh_wordsHint', '打开底部弹幕');
                        $('.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()) {  //-弹幕透明度
                        window.setTimeout((function() {  //长按时保持DOM更新
                            opacity = adjust_progress('div.bilibili-player-setting-opacity', -10);
                            if(opacity >= 0) showHint(parent, '#hhh_opacityHint', '透 '+opacity+'%');
                        }),0);
                    } else if(e.keyCode === 'C'.charCodeAt()) {  //+弹幕透明度
                        window.setTimeout((function() {
                            opacity = adjust_progress('div.bilibili-player-setting-opacity', 10);
                            if(opacity >= 0) showHint(parent, '#hhh_opacityHint', '透 '+opacity+'%');
                        }),0);
                    } else if(e.keyCode === '1'.charCodeAt()) {  //1/4屏
                        set_progress('.bilibili-player-setting-area', 0);
                        showHint(parent, '#hhh_wordsHint', '1/4屏');
                    } else if(e.keyCode === '2'.charCodeAt()) {  //半屏
                        set_progress('.bilibili-player-setting-area', 25);
                        showHint(parent, '#hhh_wordsHint', '半屏');
                    } else if(e.keyCode === '3'.charCodeAt()) {  //3/4屏
                        opacity = set_progress('.bilibili-player-setting-area', 50);
                        showHint(parent, '#hhh_wordsHint', '3/4屏');
                    } else if(e.keyCode === '4'.charCodeAt()) {  //不重叠
                        opacity = set_progress('.bilibili-player-setting-area', 75);
                        showHint(parent, '#hhh_wordsHint', '不重叠');
                    } else if(e.keyCode === '5'.charCodeAt()) {  //不限
                        opacity = set_progress('.bilibili-player-setting-area', 100);
                        showHint(parent, '#hhh_wordsHint', '不限');
                    } 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');
                });

                //非全屏滚轮音量调节
                //两个参数指定屏幕范围(按百分比)
                if(config.getCheckboxSetting('volumeControlWhenNonFullScreen') === ON) wheel_volumeHint(0.30, 0.70);

                //添加wordsHint opacityHint DOM(抄bilibili^^)
                var div_wordsHint = '<div id=hhh_wordsHint class="bilibili-player-volumeHint" style="opacity: 0; display: none; width: auto; margin-left: 0px; padding-left:15px; padding-right:15px; transform: translate(-50%);">\n'+
                    '   <span class="bilibili-player-volumeHint-text" style="width: auto; padding-left: c10px;">57%</span>\n'+
                    '</div>';
                if($('#hhh_wordsHint').length === 0) $('.bilibili-player-video-wrap').append(div_wordsHint);
                var div_opacityHint = '<div id=hhh_opacityHint class="bilibili-player-volumeHint" style="opacity: 0; display: none;">\n'+
                    '   <span class="bilibili-player-volumeHint-text" style="padding-right: 6px">57%</span>\n'+
                    '</div>';
                if($('#hhh_opacityHint').length === 0) $('.bilibili-player-video-wrap').append(div_opacityHint);

                //滚轮调节弹幕透明度(ctrl)
                if(config.getCheckboxSetting('danmuOpacityControl') === ON) wheel_opacity();

                //因为遮挡弹幕,去掉全屏时鼠标悬停时产生的顶端mask
                if(config.getCheckboxSetting('removeVideoTopMask') === ON) $('.bilibili-player-video-top-mask').removeClass();

                //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());

                //自动运行
                if(config.getCheckboxSetting('autoPlay') === ON && $('.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(config.getCheckboxSetting('repeat') === ON) $(".bilibili-player-video-btn-setting-left-repeat>.bui-switch-input").click();  //开启洗脑循环
                if(config.getCheckboxSetting('lightOff') === ON) lightoff_btn();  //自动关灯

                //解决自动播放时,自动关灯不响应的问题**
                //config.getCheckboxSetting('lightOffWhenPlaying') && $('.bilibili-player-video-btn-setting-left-autoplay>.bui-switch-input')[0].checked && !is_lightoff() && lightoff_btn();

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

            run();
        }
        init();
    }
}

window.onload = hhh_lightoff_main.init();