// ==UserScript==
// @name bilibili关灯
// @namespace hhh2000
// @version 0.62
// @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==
'use strict';
hhh_lightoff_main = {
init() {
var h5Player = $('#bilibiliPlayer .bilibili-player-video>video'),
//state
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: {
autoPlay: { text: '开启自动播放', status: OFF, fn: '', tips: '' },
lightOffWhenPlaying: { text: '播放时自动关灯', status: OFF },
lightOnWhenPause: { text: '暂停时自动开灯', status: OFF },
repeat: { text: '开启洗脑循环', status: OFF, tips: '' },
lightOff: { text: '自动关灯', status: OFF, tips: '' },
volumeControlWhenNonPaused: { text: '非全屏非暂停音量调节', status: OFF, 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(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(volumeCtrlNonPaused, 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 }
//非全屏 && (鼠标在屏幕指定位置时处理 || 非暂停时)
var pausedCtrl = volumeCtrlNonPaused && !h5Player[0].paused;
var inLimit = !volumeCtrlNonPaused && (e_in_Hint || (e.originalEvent.offsetX > w*screenLeft && e.originalEvent.offsetX < w*screenRight));
if(player.isFullScreen() === false && (pausedCtrl || 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)+'%');
}
});
}
/*
* 控制进度条
* .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) => {
//保存设置信息
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;
$(document).off('keydown.hhh_lightoff');
$(document).on('keydown.hhh_lightoff',function(e){
if(e.keyCode === 'A'.charCodeAt()){ //开关灯
lightoff_btn();
} 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();
} 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()) { //+弹幕透明度
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');
});
//非全屏滚轮音量调节,两种方式——用第一个参数控制
//1、第一个参数为真,表示非暂停时调节音量,暂停时默认行为
//2、第一个参数为假,表示鼠标位于屏幕指定范围时调节音量,不受暂停与否控制(后两个参数指定屏幕范围(按百分比))
wheel_volumeHint(config.getCheckboxSetting('volumeControlWhenNonPaused'), 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());
//自动运行
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(); //自动关灯
});
}
//初始化
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();