// ==UserScript== // @name bilibili关灯及快捷操作 // @namespace hhh2000 // @version 0.9.6.4 // @description bilibili关灯及快捷操作(把被新版B站藏起来的关灯按钮揪出来,在关闭弹幕按钮左边,还可以用快捷键,默认'A')、非全屏滚轮音量控制、弹幕控制快捷操作等 // @author hhh2000 // @include http*://www.bilibili.com/* // @include http*://www.bilibili.com/video/av* // @include http*://www.bilibili.com/video/BV* // @include http*://www.bilibili.com/watchlater/* // @include http*://www.bilibili.com/medialist/play/* // @include http*://www.bilibili.com/bangumi/play/ep* // @include http*://www.bilibili.com/bangumi/play/ss* // @include http*://bangumi.bilibili.com/anime/*/play* // @include http*://bangumi.bilibili.com/movie/* // @include http*://www.bilibili.com/blackboard/* // @include http*://t.bilibili.com/* // @include http*://space.bilibili.com/* // @include http*://www.bilibili.com/video/online.html* // @include http*://www.bilibili.com/account/history // @include http*://api.bilibili.com/* // @require https://cdn.staticfile.org/jquery/1.12.4/jquery.min.js /* globals jQuery, $, waitForkeyElements */ /* eslint-disable no-multi-spaces, dot-notation */ // @run-at document-end // @grant GM_setValue // @grant GM_getValue // @grant GM_listValues // @grant none // @downloadURL none // ==/UserScript== 'use strict'; var hhh_lightoff_main = { init() { var // ver, fps, h5Player, curr_focus, is_in_biliplayer, is_show_hint, $tip, move_frames; //const [BILI_2_X_V2, BILI_3_X, ALL] = ['bili_2.x', 'bili_3.x', 'all']; const [BILI_2_X_V2, BILI_2_X_V3, BILI_2_X, BILI_3_X, ALL] = ['bili_2.x.v2', 'bili_2.x.v3', 'bili_2.x', 'bili_3.x', 'all']; var //切换番剧和一般视频class bb = {}, bb_type = '', bb_config = { bb_class_data: { //其实这样不方便调试 //'player':{BILI_2_X_V2:'.player', [BILI_3_X]:'.bpx-player'}, //main //$('meta[property="og:image"]').attr('content') 'coverImg':{[ALL]:'meta[property="og:image"]'}, //封面 'playTipWrap':{[BILI_2_X] :'.bilibili-player-dm-tip-wrap', [BILI_3_X]:'.bpx-player-video-perch'}, //paly/pause 'fullScreen':{[BILI_2_X] :'.bilibili-player-video-btn-fullscreen', [BILI_3_X]:'.squirtle-video-fullscreen.squirtle-video-item'}, //全屏 'webFullScreen':{[BILI_2_X]:'.bilibili-player-video-web-fullscreen', [BILI_3_X]:'.squirtle-video-pagefullscreen.squirtle-video-item'}, //网页全屏 'wideScreen':{[BILI_2_X] :'.bilibili-player-video-btn-widescreen', [BILI_3_X]:'.squirtle-video-widescreen.squirtle-video-item'}, //宽屏 //一健三联 'like' :{[BILI_2_X_V2]:'.ops .like' , [BILI_2_X_V3]:'.toolbar-left .like' , [BILI_3_X]:'.like-info'}, //点赞 'likeon' :{[BILI_2_X_V2]:'.ops .like.on', [BILI_2_X_V3]:'.toolbar-left .like.on', [BILI_3_X]:'.like-info.active'}, //已点赞 'coin' :{[BILI_2_X_V2]:'.ops .coin' , [BILI_2_X_V3]:'.toolbar-left .coin' , [BILI_3_X]:'.coin-info'}, //硬币 'collect':{[BILI_2_X_V2]:'.ops .collect', [BILI_2_X_V3]:'.toolbar-left .collect', [BILI_3_X]:''}, //收藏 //弹幕 'danmukuTopClose':{[BILI_2_X]:'.bilibili-player-block-filter-type[data-name=ctlbar_danmuku_top_close]', [BILI_3_X]:'.bpx-player-block-filter-type.bpx-player-block-typeTop.bpx-player-active'}, //顶部弹幕 'danmukuTop' :{[BILI_2_X]:'.bilibili-player-block-filter-type[ftype=top]', [BILI_3_X]:'.bpx-player-block-filter-type.bpx-player-block-typeTop'}, //顶部弹幕 'danmukuBottomClose':{[BILI_2_X]:'.bilibili-player-block-filter-type[data-name=ctlbar_danmuku_bottom_close]', [BILI_3_X]:'.bpx-player-block-filter-type.bpx-player-block-typeBottom.bpx-player-active'}, //底部弹幕 'danmukuBottom' :{[BILI_2_X]:'.bilibili-player-block-filter-type[ftype=bottom]', [BILI_3_X]:'.bpx-player-block-filter-type.bpx-player-block-typeBottom'}, //底部弹幕 'progressVal' :{[ALL]:'.bui-progress-val'}, //弹幕透明度读数 'progressWrap' :{[ALL]:'.bui-progress-wrap'}, //弹幕透明度进度条 'settingOpacity':{[BILI_2_X]:'.bilibili-player-setting-opacity', [BILI_3_X]:'.bpx-player-dm-setting-ui-opacity'}, //弹幕透明度 'settingFontsize':{[BILI_2_X]:'.bilibili-player-setting-fontsize', [BILI_3_X]:'.bpx-player-dm-setting-ui-fontsize'}, //弹幕字号 'settingArea' :{[BILI_2_X]:'.bilibili-player-setting-area', [BILI_3_X]:'.bpx-player-dm-setting-ui-area'}, //显示区域 'settingFs' :{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-left-fs input', [BILI_3_X]:'.bpx-player-dm-setting-left-fs input'}, //弹幕随屏幕缩放 //音量 'volumeHint' :{[BILI_2_X]:'.bilibili-player-volumeHint', [BILI_3_X]:'.bpx-player-volume-hint'}, //音量显示 'volumeHintText':{[BILI_2_X]:'.bilibili-player-volumeHint-text', [BILI_3_X]:'.bpx-player-volume-hint-text'}, //音量显示百分比读数 'volumeHintIcon':{[BILI_2_X]:'.bilibili-player-volumeHint-icon', [BILI_3_X]:'.bpx-player-volume-hint-icon'}, //音量显示图标 'volumebarWrp' :{[BILI_2_X]:'.bilibili-player-video-volumebar-wrp', [BILI_3_X]:'.squirtle-volume-bar-wrap'}, //音量条 'volumeNum' :{[BILI_2_X]:'.bilibili-player-video-volume-num', [BILI_3_X]:'.squirtle-volume-num'}, //音量读数 //视频速度 'videoSpeedActive':{[BILI_2_X]:'.bilibili-player-video-btn-speed-menu-list.bilibili-player-active', [BILI_3_X]:'.squirtle-speed-select-list .squirtle-select-item.active'}, //视频速度 'videoSpeed':{[BILI_2_X]:'.bilibili-player-video-btn-speed-menu-list', [BILI_3_X]:'.squirtle-speed-select-list .squirtle-select-item'}, //视频速度 'videoSpeedName':{[BILI_2_X]:'.bilibili-player-video-btn-speed-name', [BILI_3_X]:'.squirtle-select-result.squirtle-speed-select-result'}, //视频速度 //弹幕设置等 'switchBody':{[ALL]:'.bui-switch-body'}, //系统关灯css设置 'switchDot':{[ALL]:'.bui-switch-dot'}, //系统弹幕设置按钮wrap进度条拖动点 'switchInput':{[BILI_2_X_V3]:'.bui-danmaku-switch-input', [ALL]:'.bui-switch-input'}, //弹幕设置switch按钮 'switchLabel':{[BILI_2_X_V3]:'.bui-danmaku-switch-label', [ALL]:'.bui-switch-label'}, //弹幕设置switchLabel 'danmaku':{[BILI_2_X]:'.bilibili-player-video-danmaku', [BILI_3_X]:'.bpx-player-row-dm-wrap'}, //弹幕 'danmakuRoot':{[BILI_2_X]:'.bilibili-player-video-danmaku-root', [BILI_3_X]:'.bpx-player-dm-root'}, //系统弹幕设置条 'danmakuSwitch':{[BILI_2_X]:'.bilibili-player-video-danmaku-switch', [BILI_3_X]:'.bpx-player-dm-switch'}, //关闭弹幕按钮 'dm':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting', [BILI_3_X]:'.bpx-player-dm-setting'}, //系统弹幕设置按钮 'dmWrap':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-wrap', [BILI_3_X]:'.bpx-player-dm-setting-wrap'}, //系统弹幕设置wrap 'dmBox':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-box', [BILI_3_X]:'.bpx-player-dm-setting-box'}, //系统弹幕设置box 'dmLeft':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-left', [BILI_3_X]:'.bpx-player-dm-setting-left'}, 'dmLeftMore':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-left-more', [BILI_3_X]:'.bpx-player-dm-setting-left-more'}, 'dmLeftMoreText':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-left-more-text', [BILI_3_X]:'.bpx-player-dm-setting-left-more-text'}, 'dmLeftBlock':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-left-block', [BILI_3_X]:'.bpx-player-dm-setting-left-block'}, 'dmLeftBlockTitle':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-left-block-title', [BILI_3_X]:'.bpx-player-dm-setting-left-block-title'}, 'dmLeftFlagTitle':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-left-flag-title', [BILI_3_X]:'.bpx-player-dm-setting-left-flag-title'}, 'dmRightMore':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-right-more', [BILI_3_X]:'.bpx-player-dm-setting-right-more'}, 'dmRightMoreText':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-right-more-text', [BILI_3_X]:'.bpx-player-dm-setting-right-more-text'}, 'dmRightSeparator':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-right-separator', [BILI_3_X]:'.bpx-player-dm-setting-right-separator'}, 'dmRightReset':{[BILI_2_X]:'.bilibili-player-video-danmaku-setting-right-reset', [BILI_3_X]:'.bpx-player-dm-setting-right-reset'}, 'videoWrap':{[BILI_2_X]:'.bilibili-player-video-wrap', [BILI_3_X]:'.bpx-player-video-area'}, //播放wrap 'videoContextMenu':{[BILI_2_X]:'.bilibili-player-video-wrap', [BILI_3_X]:'.bpx-player-video-perch'}, //播放contextmenu 'video':{[BILI_2_X]:'.bilibili-player-video', [BILI_3_X]:'.bpx-player-video-wrap'}, //播放 'videoTopMask':{[BILI_2_X]:'.bilibili-player-video-top-mask', [BILI_3_X]:'.bpx-player-top-mask'}, //全屏时鼠标悬停时产生的顶端mask //系统设置等 'playArea':{[ALL]:'.bilibili-player-area'}, //哔哩哔哩播放器 'playVideo':{[BILI_2_X]:'.bilibili-player-video-btn'}, //系统设置 'playVideoControlWrap':{[BILI_2_X]:'.bilibili-player-video-control-wrap', [BILI_3_X]:'.bpx-player-control-wrap'}, //系统控制面板 'playSetting':{[BILI_2_X]:'.bilibili-player-video-btn-setting'}, //系统播放设置 'playSettingWrap':{[BILI_2_X]:'.bilibili-player-video-btn-setting-wrap'}, //系统播放设置wrap 'playSettingAutoplay':{[BILI_2_X]:'.bilibili-player-video-btn-setting-left-autoplay input', [BILI_3_X]: '.squirtle-setting-autoplay'}, //自动播放 'playSettingRepeatInput':{[BILI_2_X]:'.bilibili-player-video-btn-setting-left-repeat input', [BILI_3_X]:'.squirtle-setting-loop'}, //洗脑循环按钮 'playSettingLightoff':{[BILI_2_X]:'.bilibili-player-video-btn-setting-right-others-content-lightoff input', [BILI_3_X]:'.squirtle-single-setting-other-choice.squirtle-lightoff'}, //关灯按钮 'bpxStateLightOff':{[BILI_3_X]:'.bpx-state-light-off'}, //关灯bpx 'playJumpElectric':{[BILI_2_X]:'.bilibili-player-electric-panel-jump'}, //2.69.4版本B站取消充电鸣谢,2.72又加回来了 //右键菜单 'playerContextMenu':{[BILI_2_X]:'.bilibili-player-context-menu-container.black.bilibili-player-context-menu-origin', [BILI_3_X]:'.bpx-player-contextmenu.bpx-player-black'}, //右键菜单 'hotkeyPanel':{[BILI_2_X]:'.bilibili-player-hotkey-panel-container', [BILI_3_X]:'.bpx-player-hotkey-panel'}, //快捷键说明面板 'hotkeyPanelClose':{[BILI_2_X]:'.bilibili-player-hotkey-panel-close', [BILI_3_X]:'.bpx-player-hotkey-panel-close'}, //快捷键说明面板关闭按钮 'videoInfo':{[BILI_2_X]:'.bilibili-player-video-info', [BILI_3_X]:'.bpx-player-info'}, //视频统计信息 'videoInfoClose':{[BILI_2_X]:'.bilibili-player-video-info-close', [BILI_3_X]:'.bpx-player-info-close'}, //视频统计信息关闭按钮 'videoInfoContainer':{[BILI_2_X]:'.bilibili-player-video-info-container', [BILI_3_X]:'.bpx-player-info-container'}, //视频统计信息 'videoInfoShow':{[BILI_2_X]:'.bilibili-player-video-info-container active', [BILI_3_X]:'.bpx-player-info-container'}, //视频统计信息面板显示 'DOMNodeInsertedVideoInfoShow':{[BILI_2_X]:'.bilibili-player-video-info-container active', [BILI_3_X]:'.info-line'}, // }, set_bb(_bb_type) { bb_type = _bb_type; for(var k in this.bb_class_data){ var class_str = this.bb_class_data[k][bb_type] || this.bb_class_data[k][[BILI_2_X]] || this.bb_class_data[k][[ALL]]; bb[k] = class_str; } } }; const [ON, OFF] = [true, false]; var //config keycode = { 'Enter': 13, 'Ctrl': 17, 'Esc': 27, 'left': 37, 'right': 39, 'up': 38, 'down': 40, 'space': 32, '/': 191, }, config = { //一些主要开关设置 sets: {}, getCheckboxSettingStatus(key) { return this.sets[key]['status']; }, getCheckboxSettingFn(key) { return this.sets[key]['fn']; }, getCheckboxSettingArgs(key) { return this.sets[key]['args']; }, setCheckboxSettingStatus(key, status) { this.sets[key]['status'] = status; }, setCheckboxSettingTips(key, tips) { this.sets[key]['tips'] = tips; }, saveCheckboxSetting() { for(var o in this){ if(o.indexOf('b_') === 0){ this.sets = JSON.parse(JSON.stringify(this[o]['options'])); } } }, b_playerCheckbox: { options: { autoPlay: { text: '自动播放', status: OFF, tips: '' }, lightOff: { text: '自动关灯', status: OFF, tips: '' }, autoFullScreen: { text: '自动全屏', status: OFF, tips: '' }, autoWebFullScreen: { text: '自动网页全屏', status: OFF, tips: '' }, videoRepeat: { text: '自动洗脑循环', status: OFF, tips: '' }, lightOffWhenPlaying: { text: '播放时自动关灯', status: OFF, fn: 'lightOffWhenPlaying' }, lightOnWhenPause: { text: '暂停时自动开灯', status: OFF, fn: 'lightOnWhenPause' }, rememberVideoRepeat: { text: '记忆洗脑循环', status: ON, tips: '优先级低于【自动洗脑循环】', show: OFF }, //优先级低于videoRepeat dblclickFullScreen: { text: '双击或中键全屏', status: ON, tips: '', fn: 'dblclickFullScreen' }, volumeControlWhenNonFullScreen: { text: '非全屏滚轮音量调节', status: ON, tips: '', fn: 'wheel_volumeHint', args:{screenLeft: 0.3, screenRight: 0.7, delta: 1} }, volumeControlWhenPause: { text: '非全屏暂停时滚轮音量调节', status: ON, tips: '' }, danmuOpacityControl: { text: '滚轮弹幕透明度控制', status: ON, tips: 'Ctrl + 滚轮', fn: 'wheel_opacity', args:{delta: 5} }, //ctrl+滚轮 keyVideoSpeed: { text: '键盘调节视频速度', status: ON, tips: 'Ctrl + ↑↓' }, removeVideoTopMask: { text: '去掉顶部mask', status: ON, tips: '', fn: 'removeVideoTopMask' }, jumpElectric: { text: '跳过充电鸣谢', status: ON, fn: 'jumpElectric' }, //2.69.4版本B站取消充电鸣谢,2.72又加回来了 reloadDanmuku: { text: '快进快退恢复重载弹幕效果', status: OFF }, //快进快退恢复重载弹幕效果 //removeMostViewedListener: { text: '删除动态首页UP主动态提示', status: ON }, //不显示有明显变化的提示,关灯、关弹幕等,因为对有些人来说这些操作变化明显可见,提示反而多余且遮挡屏幕 hotKeyHint: { text: '快捷键屏幕提示', status: OFF, tips: '不显示有明显变化的提示,关灯、关弹幕等' }, openHotKey: { text: '开启自定义快捷键', status: ON, tips: '', 'fn': 'set_hotkey' }, }, btn: '设置' }, //快捷键 QDs: {}, //未使用 getQD(key) { return this.QDs[key]; }, //未使用 saveQD() { for (let [key, { value, text }] of Object.entries(this.hotKeyMenu)) { this.QDs[key] = {value: value, keyCode: value.charCodeAt(), text: text}; } }, //未使用 hotKeyMenu: { //只是右键菜单的数据,如需改动快捷键改run函数 'volumeControl': { value: '滚轮', text: '音量调节', }, 'lightOff': { value: 'A', text: '关灯/开灯', }, 'webFullscreen': { value: 'W', text: '网页全屏', }, 'widescreen': { value: 'Q', text: '宽屏模式', }, 'danmu': { value: 'D', text: '弹幕/关闭弹幕', }, 'danmuTopBottom': { value: 'T/B', text: '顶部/底部弹幕', }, 'videoRepeat': { value: 'R', text: '洗脑循环', }, 'addsubDanmuOpacity': { value: 'Z/C', text: '减增弹幕透明度10%', }, 'addsubDanmuFontsize': { value: 'V/N', text: '减增弹幕字号10%', }, 'danmuArea': { value: '1、2、3、4、5', text: '弹幕显示区域 1/4屏~不限', }, // 'quarterArea': { value: '1', text: '1/4屏', }, // 'halfArea': { value: '2', text: '半屏', }, // 'threeQuarterArea': { value: '3', text: '3/4屏', }, // 'nonOverArea': { value: '4', text: '不重叠', }, // 'fullArea': { value: '5', text: '不限', }, 'wheelDanmuOpacity': { value: 'Ctrl + 滚轮', text: '增减弹幕透明度5%', }, 'fastForwardBackward30s': { value: 'Ctrl + ←/→', text: '快进/快退30s', }, '1/FPS': { value: 'Shift + ←/→', text: '逐帧操作', }, 'keyVideoSpeed': { value: 'Ctrl + ↑/↓', text: '调节视频播放速度', }, 'dblclickFullScreen': { value: '双击/中键/功能键', text: '全屏', }, 'ctrl_enterFullScreen': { value: 'Ctrl+Enter', text: '全屏', }, 'danmuZoomWithScreen': { value: 'S', text: '弹幕是否随屏幕缩放', }, 'like': { value: 'Y、U、I、O', text: '点赞、投币、收藏、长按一键三连', }, 'loop': { value: 'Ctrl + 左键 / L', text: '设定段落循环 / 设定后切换', }, }, }; const assert = function(condition, message) { if (!condition) throw Error('Assert failed: ' + (message || 'Assertion failed')); } function log(e) {console.log(e)} function dir(e) {console.dir(e)} function set_value(key, value){ localStorage.setItem(key, value) } function get_value(key, default_value){ return localStorage.getItem(key) || default_value } function waitForNode(nodeSelector, callback, times) { //log('----n---'); if(times < 0) return; var node = nodeSelector(); if (node) { callback(node); } else { times-=1; setTimeout(function() { waitForNode(nodeSelector, callback, times); }, 50); } } function waitForTrue(ifTrue, callback) { //log('----t---'); if (ifTrue()) { callback(); } else { setTimeout(function() { waitForTrue(ifTrue, callback); }, 50); } } function is_fullscreen() { //if(bb_type.indexOf(BILI_2_X) !== -1){ return bili_player.isFullScreen() } if(bb_type.indexOf(BILI_2_X) !== -1){ return $('#bilibiliPlayer').hasClass('mode-webfullscreen') || $('#bilibiliPlayer').hasClass('mode-fullscreen') } else if(bb_type === BILI_3_X){ return $('.bpx-player-container').attr('data-screen') === 'web' || $('.bpx-player-container').attr('data-screen') === 'full' } //normal wide web full } function fullscreen() { $(bb['fullScreen']).click() } function web_fullscreen() { $(bb['webFullScreen']).click() } function wide_screen() { $(bb['wideScreen']).click() } function is_lightoff() { //if (bb_type.indexOf(BILI_2_X) !== -1) { return !bili_player.getPlayerState().lightOn } if (bb_type.indexOf(BILI_2_X) !== -1) { return $('#bilibiliPlayer').hasClass('mode-light-off') } else if(bb_type === BILI_3_X) { return $(bb['playSettingLightoff']).hasClass('active') } } function is_danmaku_show(){ return $(bb['danmakuSwitch']+' '+bb['switchInput']+':last')[0].checked; } function lightoff() { $(bb['playSettingLightoff']).click() } function add_tip($tip, $node, args){ $node.mouseover(function(){ var e = this; var op = {}; let t = setTimeout(function() { $tip.appendTo(e); let $this = $(e); let $new_tip = $('.player-tooltips.tip.top-center.animation').css({top:0,left:0}); true === !!$this.data('tip') ? $.extend(true, op, $this.data('tip')) : $.extend(true, op, args); $new_tip.find('.tooltip').text(op['text']); let tip_new_top = $this.offset().top - $new_tip.offset().top - $new_tip.height(); //console.log('top:'+$this.offset().top+' tiptop: '+$new_tip.offset().top +' height: '+ $new_tip.height()); //console.log('left:'+$this.offset().left+' tipleft: '+$new_tip.offset().left +' width: '+ $this.width()+' tipwidth: '+ $new_tip.width()); //console.log('top:'+$this.css('top')+'left:'+$this.css('left')) let tip_new_left = $this.offset().left - $new_tip.offset().left + ($this.width() - $new_tip.width())/2; //console.log(tip_new_top+' '+tip_new_left); tip_new_left = tip_new_left <= 0 ? 0 : tip_new_left; let diff_full_top = is_fullscreen() ? (op['diff_full_top'] || 0) : 0; //全屏时位置不同 $new_tip.css({'top':tip_new_top + op['top'] + diff_full_top, 'left':tip_new_left + op['left']}).addClass('active'); }, op['millisec']); $(this).data('timeout', t); }). mouseout(function(e){ clearTimeout($(this).data('timeout')); $('.player-tooltips.tip.top-center.animation').removeClass('active'); $('.player-tooltips.tip.top-center.animation').remove(); }) } //关灯按钮样式 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 '+bb['switchInput'])[0].checked === false) { //关灯 $('#hhh_lightoff '+bb['switchBody']+':first').css('background-color', dark_rgb); $('#hhh_lightoff '+bb['switchBody']+':first>'+bb['switchDot']).css('color', dark_rgb); $(`#hhh_lightoff ${bb['switchLabel']}`).removeClass('checked'); } else { $('#hhh_lightoff '+bb['switchBody']+':first').css('background-color', body_brgb); $('#hhh_lightoff '+bb['switchBody']+':first>'+bb['switchDot']).css({'color': dot_crgb, 'background-color': dot_brgb}); $(`#hhh_lightoff ${bb['switchLabel']}`).addClass('checked'); } } //关灯按钮 function lightoff_btn() { lightoff(); let $light_input = $('#hhh_lightoff '+bb['switchInput']); if(is_lightoff() === $light_input[0].checked) { //checked==true开灯 false关灯 $light_input[0].checked = !$light_input[0].checked; } lightoff_btn_css(); let light_tip_text = $light_input[0].checked === true? '关灯': '开灯'; $('#hhh_lightoff .tooltip').text(light_tip_text); if(bb_type.indexOf(BILI_2_X) !== -1) $('#hhh_lightoff').data('tip')['text'] = light_tip_text; } //关灯按钮初始化 function lightoff_init() { //插入关灯按钮 $(`${bb['danmakuSwitch']}:first`).clone().prependTo(`${bb['danmakuRoot']}:first`)[0].id = 'hhh_lightoff'; $('#hhh_lightoff '+bb['switchInput'])[0].checked = true; if(bb_type !== BILI_2_X_V3) $(`#hhh_lightoff ${bb['switchDot']}`)[0].innerHTML = '灯'; else{ //开灯 $('#hhh_lightoff').find('.bui-danmaku-switch-on svg').replaceWith(` ` ); //关灯 $('#hhh_lightoff').find('.bui-danmaku-switch-off svg').replaceWith(` ` ); } //css lightoff_btn_css(); //add tips waitForTrue(()=> ($tip !== undefined && $('#hhh_lightoff').length === 1), () => { if(bb_type === BILI_3_X) $('.squirtle-controller-wrap').css({"display":"flex"}); $(bb['dmWrap']).css({"display":"block"}); if(bb_type === BILI_2_X_V2) $('#hhh_lightoff').data('tip', {'text': '关灯', 'millisec':1, 'top':2, 'left':0, 'diff_full_top':-20}); else if(bb_type === BILI_2_X_V3) $('#hhh_lightoff').data('tip', {'text': '关灯', 'millisec':1, 'top':-4, 'left':0, 'diff_full_top':-14}); add_tip($tip, $('#hhh_lightoff'), {}); $(bb['dmWrap']).css({"display":"none"}); if(bb_type === BILI_3_X) $('.squirtle-controller-wrap').css({"display":"none"}); }) } //模拟B站音量调节 //2.X版本可以直接调用系统函数window.player.volume(),但不能直接使用H5Player.volume //3.X版本去掉了window.player.volume(),但H5Player.volume功能发生变动,基本等价于window.player.volume() function volume(v, is_show_hint=true){ function volume_bar(v){ //未使用 if(v === undefined) return; v = v<0? 0: v>1? 1: v; $('.bilibili-player-video-volume-num').text(Math.round(v*100)); $('.bilibili-player-video-volumebar-wrp .bui-bar.bui-bar-normal')[0].style.transform = `scaleY(${v})`; $('.bilibili-player-video-volumebar-wrp .bui-thumb')[0].style.transform = `translateY(${-48*v}px)`; v === 0? $('.bilibili-player-video-btn.bilibili-player-video-btn-volume').addClass('video-state-volume-min'): $('.bilibili-player-video-btn.bilibili-player-video-btn-volume').removeClass('video-state-volume-min') } function volume_hint_bar(v){ if(v === undefined) return; assert(typeof v === "number", '| volume err: v is not number') //debug //v = v<0? 0: v>1? 1: v; v = +Math.max(Math.min(v,1),0).toFixed(3); var $volumeHintIcon = $(`#hhh_volumeHint ${bb['volumeHintIcon']}`); var volumeHintIconClassName = bb['volumeHintIcon'].substr(1); if(bb_type.indexOf(BILI_2_X) !== -1){ if(v <= 0) $volumeHintIcon.attr('class', `${volumeHintIconClassName} video-state-volume-min`); else if(v >= 1) $volumeHintIcon.attr('class', `${volumeHintIconClassName} video-state-volume-max`); else $volumeHintIcon.attr('class', volumeHintIconClassName); } else{ if(v <= 0){ $volumeHintIcon.find('.bpx-common-svg-icon:last').css('display','block'); $volumeHintIcon.find('.bpx-common-svg-icon:first').css('display','none'); } else{ $volumeHintIcon.find('.bpx-common-svg-icon:last').css('display','none'); $volumeHintIcon.find('.bpx-common-svg-icon:first').css('display','block'); } } if(v <= 0) showHint(this, '#hhh_volumeHint', '静音'); else showHint(this, '#hhh_volumeHint', Math.round(v*100)+'%'); } h5Player = ($(`${bb['video']} video`)[0] || $(`${bb['video']} bwp-video`)[0]); // bug:调节清晰度会影响 h5Player 和window.player,需要重新赋值 assert(typeof h5Player.volume === "number", '| volume err: h5Player.volume is not number') //debug if(v === undefined) { /*log('v: '+h5Player.volume);*/ return +h5Player.volume;} v = +Math.max(Math.min(v,1),0).toFixed(3); assert(typeof v === "number", '| volume err: v is not number') //debug //log('volume: '+v+' '+h5Player); //v = v<0.01? 0: v>1? 1: v; //0.01防止误差 bb_type.indexOf(BILI_2_X) !== -1? window.player.volume(v): h5Player.volume = v; //h5Player.volume = v; if(is_show_hint === true) volume_hint_bar(+h5Player.volume); return +h5Player.volume; } //显示提示 function showHint(parent, selector_str, text){ $(bb['volumeHint']).css({"visibility":"visible"}) $(bb['volumeHint']).css('display', 'none'); //隐藏所有提示,避免提示重叠 $(`${selector_str}>${bb['volumeHintText']}`).text(text); //百分比显示 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 (b站默认滚轮操作某些情况会失效,一并处理全屏情况) //两个参数指定屏幕范围(按百分比),第三个参数表示滚动一下增加的音量百分比,参数四表示暂停时是否调节 function wheel_volumeHint(isWheelVolume=ON, screenLeft=0.3, screenRight=0.7, delta=1, isPauseVolume=ON){ $(bb['videoWrap']).off('mousewheel.hhh_volumeHint'); if(!isWheelVolume) return; $(bb['videoWrap']).on('mousewheel.hhh_volumeHint', function(e){ if(e.ctrlKey || e.altKey || e.shiftKey) return; //缺省屏幕百分比参数,默认0.3~0.7 screenLeft = (screenLeft<0 || screenLeft>1)? 0.3: screenLeft; screenRight = (screenRight<0 || screenRight>1)? 0.7: screenRight; //缺省音量百分比,默认1 delta = (delta<1 || delta>100)? 1: delta; //非暂停(可选) && 鼠标在屏幕指定位置时处理 var pauseState = isPauseVolume || h5Player.paused === false; var Rect = $(bb['videoWrap'])[0].getBoundingClientRect(); var offsetX = e.originalEvent.x - Rect.x; var inLimit = offsetX > Rect.width*screenLeft && offsetX < Rect.width*screenRight; if(is_fullscreen() || (pauseState && inLimit)) { //阻止页面滚动 && 阻止冒泡 e.preventDefault(); e.stopPropagation(); var wheelDelta = e.originalEvent.wheelDelta; var v = volume(); if(wheelDelta >= 120) { //向上滚动,减少音量 volume(+(v+(delta/100)).toFixed(3)); //+ string to number } else if(wheelDelta <= -120) { //向下滚动,增大音量 volume(+(v-(delta/100)).toFixed(3)); } } }); } /* * 控制进度条 * .bilibili-player-setting-opacity 透明度 * .bilibili-player-setting-area 显示区域 * .bilibili-player-setting-speedplus 弹幕速度 等 * 利用系统mousedown事件 * 0 ~ 100 */ function set_progress(selector_str, percent, limit_left, limit_right){ function calc_bar_offset2(percent, bar_width, limit_left, limit_right){ //某种插值算法,未使用 let p = +percent; p = plimit_right? limit_right: p; //log(p+' - '+bar_width+' - '+(limit_right-limit_left)); let limits = limit_right - limit_left; let quo = Math.floor((p-limit_left)*bar_width/limits); let rem = (p-limit_left)*bar_width%limits; //log(quo+'****'+rem); return (bb_type === BILI_3_X)? Math.round((p-limit_left)/limits*bar_width): (rem>=(limits/2)? quo+1: quo); //百分比对应进度条位置 } function calc_bar_offset(percent, bar_width, limit_left, limit_right){ let p = Math.max(Math.min(+percent, limit_right), limit_left); //log(p+' - '+bar_width+' - '+(limit_right-limit_left)); let limits = limit_right - limit_left; let bar_offset = (p-limit_left) / limits * bar_width; return Math.round(bar_offset); //百分比对应进度条位置 } let selector = document.querySelector(selector_str); let e1 = new MouseEvent('mousedown'), e2 = new MouseEvent('mouseup'); if(bb_type === BILI_3_X) $('.squirtle-controller-wrap').css({"display":"flex"}); $(bb['dmWrap']).css({"display":"block"}); let selector_rect = selector.getClientRects(); //log(selector.getBoundingClientRect()[0]+' - '+selector_rect[0]); let bar_offset = calc_bar_offset(percent, $(`${selector_str} ${bb['progressWrap']}`).innerWidth(), limit_left, limit_right); //log('wrapWIdth: '+ calc_bar_len(percent, $(`${selector_str} ${bb['progressWrap']}`).innerWidth(), limit_left, limit_right)); for(let i=0;i<10;i++){ let dest_per = Math.max(Math.min(+percent, limit_right), limit_left); let clientX = selector_rect[0].left + bar_offset; 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); let curr_per = +$(`${selector_str} ${bb['progressVal']}`).text().slice(0,-1); //log(curr_per+' - '+dest_per); if(curr_per !== dest_per){ curr_per < dest_per ? ++bar_offset : --bar_offset; //log(bar_offset); }else{ break; } } $(bb['dmWrap']).css({"display":"none"}); if(bb_type === BILI_3_X) $('.squirtle-controller-wrap').css({"display":"none"}); //激活设置,记忆进度条位置 if(bb_type === BILI_3_X){ $(bb['dm'])[0].dispatchEvent( new MouseEvent('mouseleave') ); //3.X }else{ $(bb['dm'])[0].dispatchEvent( new MouseEvent('mouseout') ); //2.X } return $(`${selector_str} ${bb['progressVal']}`).text(); } /* * 调节弹幕设置进度条 * 利用系统mousedown事件 * '正数': right, '负数': left, -100 ~ +100 */ function adjust_progress(selector_str, inc_percent, limit_left, limit_right){ var curr_percent = Number($(`${selector_str} ${bb['progressVal']}`).text().slice(0,-1)); return set_progress(selector_str, curr_percent + inc_percent, limit_left, limit_right); } //滚轮调节弹幕透明度(ctrl),参数表示滚动一下增加的透明度百分比 function wheel_opacity(status, delta=5){ $(bb['videoWrap']).off('mousewheel.hhh_opacity'); if(status === OFF) return; $(bb['videoWrap']).on('mousewheel.hhh_opacity', function(e){ if(e.ctrlKey === true) { //阻止页面滚动 && 阻止冒泡 e.preventDefault(); e.stopPropagation(); //缺省透明度百分比,默认5 delta = (delta<1 || delta>100)? 5: delta; var wheelDelta = e.originalEvent.wheelDelta; var opacity; if(wheelDelta >= 120) { //向上滚动,增大透明度 opacity = adjust_progress(bb['settingOpacity'], delta, 10, 100); } else if(wheelDelta <= -120) { //向下滚动,减少透明度 opacity = adjust_progress(bb['settingOpacity'], -delta, 10, 100); } if(opacity !== undefined) showHint(document, '#hhh_opacityHint', '透 '+opacity); } }); } /* / \ | | \ / clip-path: polygon(40% 0%, 25% 30%, 25% 70%, 40% 100%, 0% 100%, 0% 0%,60% 0%, 75% 30%, 75% 70%, 60% 100%, 100% 100%, 100% 0%);
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
11111111111111111111111
$('.bilibili-player-context-menu-container.active li:last').mouseenter(function(){ let hotkey_class = '.bilibili-player-hotkey-panel-container'.substr(1); $('#hhh_hotkey_panel').clone(true,true).replaceAll($(`.${hotkey_class}:last`)).attr({'id': '', 'class': hotkey_class, 'style': ''}); let $hotkey = $('.bilibili-player-hotkey-panel-container').addClass('active').css('z-index', $('.bilibili-player-video-control-wrap').css('z-index')); }).mouseleave(function(){ $('.bilibili-player-hotkey-panel-container').removeClass('active').css('display', 'none'); }) BV to AV // 作者:mcfx // 链接:https://www.zhihu.com/question/381784377/answer/1099438784 // 来源:知乎 // 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 function bv2av() { const bv = document.getElementById('bv').value; document.getElementById('av').value = dec(bv); } function av2bv() { const av = +document.getElementById('av').value; document.getElementById('bv').value = enc(av); } const table = 'fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF' const tr = {} for (let i = 0; i < 58; i++) tr[table[i]] = i const s = [11, 10, 3, 8, 4, 6] const xor = 177451812 const add = 8728348608 function dec(x) { let r = 0 for (let i = 0; i < 6; i++) { r += tr[x[s[i]]] * 58 ** i } return (r - add) ^ xor } function enc(x) { x = (x ^ xor) + add r = 'BV1 4 1 7 '.split('') for (let i = 0; i < 6; i++) { r[s[i]] = table[parseInt(x / 58 ** i) % 58] } return r.join('') } // console.log(dec('BV17x411w7KC')) // console.log(dec('BV1Q541167Qg')) // console.log(dec('BV1mK4y1C7Bz')) // console.log(enc(170001)) // console.log(enc(455017605)) // console.log(enc(882584971)) // console.log('----------------------------'); // console.log(1, enc(1)) // console.log(93761707, dec(enc(93761707))) // console.log('BV1xE411x7Mn', enc(dec('BV1xE411x7Mn'))) // console.log(add === 100618342136696320, add); */ //自定义快捷键说明页面 function add_custom_hotkey(hotkey_panel_class, hotkey, is_append) { var $hotkey_panel = $(`.${hotkey_panel_class}`); var $hotkey_item = $hotkey_panel.find(`.${hotkey_panel_class}-item:first`); var key_name = bb_type.indexOf(BILI_2_X) !== -1 ? 'key' : 'name'; if(is_append === false) $hotkey_panel.empty(); for (let [key, { value, text }] of Object.entries(hotkey)) { $hotkey_item.clone().appendTo($hotkey_panel); let $hotkey_key = $hotkey_panel.find(`.${hotkey_panel_class}-${key_name}:last`); $hotkey_key.text(value); $hotkey_key.next().text(text); } } //添加右键菜单自定义快捷键说明2.X function add_custom_hotkey_menu_2_X(custom_hotkey) { //主class名,去掉"." let hotkey_panel_class = 'bilibili-player-hotkey-panel', is_init = false; //设置右键 & 快捷键菜单 (function add_menu(){ $('#bilibiliPlayer')[0].addEventListener('DOMSubtreeModified', function(e) { //typeof e.target.className === 'string' && e.target.className !== '' && log(e.target.className); let $target = $(e.target); if($target.hasClass('context-line context-menu-function hover') && $('.bilibili-player-hotkey-panel').length === 1){ if(is_init === false){ //log('-------添加快捷键菜单--------'); is_init = true; let $last_item = $('.bilibili-player-hotkey-panel').find('.bilibili-player-hotkey-panel-item:last'); $last_item.attr('id', 'hhh_last_system_hotkey_panel_item'); add_custom_hotkey(hotkey_panel_class, custom_hotkey, true); }else if($target[0].id !== '__sizzle__'){ //过滤掉第一个懒加载 let $last_system_itme = $('#hhh_last_system_hotkey_panel_item'); //log($target.find('a').text()); if($target.find('a').text() === '快捷键说明'){ //log('--------显示快捷键说明-------'); $last_system_itme.prevAll().css('display','block'); $last_system_itme.css('display','block'); $last_system_itme.nextAll().css('display','none'); }else if($target.find('a').text() === '快捷键说明(bilibili关灯)'){ //log('--------显示快捷键说明(bilibili关灯)-------'); $last_system_itme.prevAll().css('display','none'); $last_system_itme.css('display','none'); $last_system_itme.nextAll().css('display','block'); } let wheelEvent = new WheelEvent('mousewheel', { deltaY: -10000, deltaMode: 0 }); //打开时回到最上 $('.bilibili-player-hotkey-panel-wrap')[0].dispatchEvent(wheelEvent); $('.bilibili-player-hotkey-panel-wrap').find('.bscroll-vertical-scrollbar')[0].style.cssText+=";background:#f1f1f1!important"; //默认滚动条对比度不明显,浅化背景颜色,增强对比度 } } else if($target.hasClass('bilibili-player-context-menu-container black bilibili-player-context-menu-origin') && $target[0].id === '') { //还有一个id = __sizzle__ this.removeEventListener('DOMSubtreeModified', arguments.callee); //log('--------添加右键菜单-------'); let $li_sys_hotkey = $target.find('a:contains("快捷键说明"):first').parent(); //返回li,XXX: 此时contains("快捷键说明")多于一个 let $a_hhh_hotkey = $target.find('a:contains("快捷键说明(bilibili关灯)")'); var $li_hhh_hotkey = ($a_hhh_hotkey.length && $a_hhh_hotkey.parent()) || $li_sys_hotkey.clone(false, false).insertAfter($li_sys_hotkey).css('display', '').find('a').text('快捷键说明(bilibili关灯)'); //插入自定义快捷键 add_menu(); } }); })(); } //添加右键菜单自定义快捷键说明3.X function add_custom_hotkey_menu_3_X(custom_hotkey) { //主class名,去掉"." let hotkey_panel_class = 'bpx-player-hotkey-panel-content'; //监听右键菜单,生成自定义快捷键说明页面,只执行一次 (function set_custom_hotkey(){ $('.bpx-player-container')[0].addEventListener('DOMNodeInserted', function(e) { //typeof e.target.className === 'string' && e.target.className !== '' && log(e.target.className); let $target = $(e.target); if($target.hasClass('bpx-player-hotkey-panel')){ //log('-------添加快捷键菜单--------'); let $last_item = $target.find('.bpx-player-hotkey-panel-content-item:last'); $last_item.attr('id', 'hhh_last_system_hotkey_panel_item'); add_custom_hotkey(hotkey_panel_class, custom_hotkey, true); } }); })(); //右键菜单弹出时添加项 (function add_menu(){ $('.bpx-player-container')[0].addEventListener('DOMSubtreeModified', function(e) { //typeof e.target.className === 'string' && e.target.className !== '' && log(e.target.className); let $target = $(e.target); if($target.hasClass('bpx-player-contextmenu bpx-player-black') && $target[0].childNodes.length !== 0) { this.removeEventListener('DOMSubtreeModified', arguments.callee); //log('--------添加右键菜单-------'); let $li_sys_hotkey = $target.find('li:contains("快捷键说明"):first'); var $li_hhh_hotkey = $li_sys_hotkey.clone(false, false).insertAfter($li_sys_hotkey).text('快捷键说明(bilibili关灯)'); //插入自定义快捷键 let $last_system_itme = $('#hhh_last_system_hotkey_panel_item'); //log('--------显示快捷键说明-------'); $li_sys_hotkey.mousedown(function(){ $last_system_itme.prevAll().css('display','block'); $last_system_itme.css('display','block'); $last_system_itme.nextAll().css('display','none'); }); //log('--------显示快捷键说明(bilibili关灯)-------'); $li_hhh_hotkey.mousedown(function(){ $last_system_itme.prevAll().css('display','none'); $last_system_itme.css('display','none'); $last_system_itme.nextAll().css('display','block'); }); let wheelEvent = new WheelEvent('mousewheel', { deltaY: -10000, deltaMode: 0 }); //打开时回到最上 $('.bpx-player-hotkey-panel-area')[0].dispatchEvent(wheelEvent); add_menu(); } }); })(); //模拟右键菜单消息,激活菜单 let evt = new MouseEvent('contextmenu', { clientX:-9999, clientY:-9999 }); $(bb['videoWrap'])[0].dispatchEvent(evt); //模拟点击菜单,激活热键菜单DOM evt = new MouseEvent('mousedown',{ bubbles:true }); $(`.bpx-player-contextmenu.bpx-player-black li:contains("快捷键说明")`)[0].dispatchEvent(evt); //关闭热键菜单 $('.bpx-player-hotkey-panel-close').click(); } /* //自定义快捷键说明页面 function set_custom_hotkey2($hotkey, sub_class, hotkey, is_append) { var $hotkey_panel = bb_type.indexOf(BILI_2_X) !== -1 ? $hotkey.find(`.${sub_class}:first`) : $hotkey.find(`.${sub_class}:first`); var $hotkey_item = $hotkey.find(`.${sub_class}-item:first`); var key_name = bb_type.indexOf(BILI_2_X) !== -1 ? 'key' : 'name'; if(is_append === false) $hotkey_panel.empty(); for (let [key, { value, text }] of Object.entries(hotkey)) { $hotkey_item.clone().appendTo($hotkey_panel); let $hotkey_key = $hotkey_panel.find(`.${sub_class}-${key_name}:last`); $hotkey_key.text(value);; $hotkey_key.next().text(text).width(180); // 3.X 默认宽度窄了 } } //添加右键菜单自定义快捷键说明3.X2 function add_custom_hotkey_menu_3_X2(custom_hotkey) { //主class名,去掉"." var player_hotkey_panel_class = 'bpx-player-hotkey-panel'; //监听右键菜单,生成自定义快捷键说明页面,只执行一次 (function add_custom_hotkey(){ //$(bb['videoWrap'])[0].addEventListener('DOMNodeInserted', function(e) { $('.bpx-player-container')[0].addEventListener('DOMNodeInserted', function(e) { let $target = $(e.target); if($target.hasClass(player_hotkey_panel_class)) { this.removeEventListener('DOMNodeInserted', arguments.callee); //var $hotkey = $target.css('display', 'none'); var $hotkey = $target; $hotkey.clone(true,true).insertBefore($hotkey).attr({'class': '','id': 'sys_hotkey_panel'}).css('display', 'none') .find(`.${player_hotkey_panel_class}-area`).css('max-height', '600px'); //bilibili自己的BUG,由于max-height限制,显示不全 $hotkey.clone(true,true).insertBefore($hotkey).attr({'class': '','id': 'hhh_hotkey_panel'}).css('display', 'none') .find(`.${player_hotkey_panel_class}-area`).css('max-height', '600px'); $('#sys_hotkey_panel .bpx-player-hotkey-panel-close').click(function(){ $(this).parent().parent().css('display', 'none') }); //jquery问题,clone失败,自定义关闭按钮事件 $('#hhh_hotkey_panel .bpx-player-hotkey-panel-close').click(function(){ $(this).parent().parent().css('display', 'none') }); //jquery问题,clone失败,自定义关闭按钮事件 //自定义快捷键说明页面 set_custom_hotkey2($('#hhh_hotkey_panel'), `${player_hotkey_panel_class}-content`, custom_hotkey, false); } }); })(); //右键菜单弹出时添加项 (function add_menu(){ $('#bilibili-player')[0].addEventListener('DOMSubtreeModified', function(e) { let $target = $(e.target); if($target.hasClass('bpx-player-contextmenu bpx-player-black') && $target[0].id === '') { //还有一个id = __sizzle__ this.removeEventListener('DOMSubtreeModified', arguments.callee); if($target.find('li:contains("快捷键说明"):first').length === 1) { var $li_sys_hotkey = $target.find('li:contains("快捷键说明"):first'); //XXX: 此时contains("快捷键说明")多于一个 var $li_hhh_hotkey = $li_sys_hotkey.clone(false, false).insertAfter($li_sys_hotkey).css('display', '').text('快捷键说明(bilibili关灯)'); $li_sys_hotkey.mousedown(function(){ $('#sys_hotkey_panel').clone(true,true).replaceAll($(`.${player_hotkey_panel_class}:last`)).attr({'id': '', 'class': player_hotkey_panel_class, 'style': ''}); }); $li_hhh_hotkey.mousedown(function(){ $('#hhh_hotkey_panel').clone(true,true).replaceAll($(`.${player_hotkey_panel_class}:last`)).attr({'id': '', 'class': player_hotkey_panel_class, 'style': ''}); }); } add_menu(); } }); })(); //模拟右键菜单消息,激活菜单 let evt = new MouseEvent('contextmenu', { clientX:-9999, clientY:-9999 }); $(bb['videoWrap'])[0].dispatchEvent(evt); //模拟点击菜单,激活热键菜单DOM evt = new MouseEvent('mousedown',{ bubbles:true }); $(`.bpx-player-contextmenu.bpx-player-black li:contains("快捷键说明")`)[0].dispatchEvent(evt); //关闭热键菜单 $('.bpx-player-hotkey-panel-close').click(); } */ //添加右键菜单自定义快捷键说明 function add_custom_hotkey_menu(hotKeyMenu) { if(bb_type.indexOf(BILI_2_X) !== -1) add_custom_hotkey_menu_2_X(hotKeyMenu); else add_custom_hotkey_menu_3_X(hotKeyMenu); } //取得版本号-未使用 //function get_ver() { // if(bb_type.indexOf(BILI_2_X) !== -1) ver = bili_player.getVersion().version; // else ver = $('.bpx-common-opacity-60').text().split('-')[0]; //} //取得视频FPS(Frames Per Second)和版本 function get_video_fps_ver() { $(bb['videoWrap'])[0].addEventListener('DOMNodeInserted', function(e) { //插入info面板时截取fps值 if($(e.target).hasClass(bb['DOMNodeInsertedVideoInfoShow'].substr(1))) { this.removeEventListener('DOMNodeInserted', arguments.callee); let $video_info_close = $(bb['videoInfoClose']); $video_info_close.click(); //模拟关闭统计信息面板,2.X版本一次即可关掉 $video_info_close.click(); //3.X版本执行两次才能关掉面板,保险起见3次 $video_info_close.click(); //估计是点击事件开始太快,系统未能处理,也可能3.X测试版自己的问题 //text中取得fps值 var get_title_text = function(title) { return $(bb['videoInfoContainer']).find(`.info-title:contains("${title}")`).next().text(); } fps = Number(get_title_text('Resolution').match(/\d+\.\d+/)) || Number(get_title_text('FPS')) || 30; } }) //模拟右键菜单消息,激活菜单DOM let evt = new MouseEvent('contextmenu', { clientX:-9999, clientY:-9999 }); $(bb['videoContextMenu'])[0].dispatchEvent(evt); //模拟点击菜单,激活热键菜单DOM,版本号 if(bb_type.indexOf(BILI_2_X) !== -1){ let evt = new MouseEvent('click',{ bubbles:true }); $(`${bb['playerContextMenu']} a:contains("视频统计信息")`)[0].dispatchEvent(evt); ver = $(`${bb['playerContextMenu']} a:contains("更新历史")`).text().split(' ')[1].split('-')[0]; } else if(bb_type === BILI_3_X) { let evt = new MouseEvent('mousedown',{ bubbles:true }); $(`${bb['playerContextMenu']} li:contains("视频统计信息")`)[0].dispatchEvent(evt); ver = $(`${bb['playerContextMenu']} li:contains("更新历史")`).text().match(/\S+/g)[1].split('-')[0]; } } //笨办法,激活系统音量设置,复制volumeHint DOM function pick_volume_hint(){ var original_volume = h5Player.volume; //监视提取提示DOM $(bb['videoWrap'])[0].addEventListener('DOMNodeInserted', function(e) { if($(e.target).hasClass(bb['volumeHint'].substr(1))) { this.removeEventListener('DOMNodeInserted', arguments.callee); volume(original_volume); //模拟鼠标拖动无法按1%精确控制音量,系统自身限制或者说bug //添加 volumeHint wordsHint opacityHint DOM $(bb['volumeHint']).clone().appendTo(bb['videoWrap']).attr('id','hhh_volumeHint'); $('#hhh_volumeHint').clone().appendTo(bb['videoWrap']).attr('id','hhh_wordsHint').css({'opacity': 0, 'display': 'none'}).find(bb['volumeHintIcon']).remove(); $('#hhh_wordsHint').clone().appendTo(bb['videoWrap']).attr('id','hhh_opacityHint'); if(bb_type.indexOf(BILI_2_X) !== -1){ $('#hhh_wordsHint').css({'width':'auto','margin-left':'0px','padding-left':'8px','padding-right':'15px','transform':'translate(-50%)'}) .find(bb['volumeHintText']).css({'width': 'auto', 'padding-left': '10px'}); $('#hhh_opacityHint').find(bb['volumeHintText']).css({'padding-right': '6px'}); } else{ $('#hhh_wordsHint, #hhh_opacityHint').find(bb['volumeHintText']).css({'padding': '0 10px'}); } //隐藏提示 $(bb['volumeHint']).css({"visibility":"hidden"}); } }); //激活系统音量设置,复制volumeHint DOM let evt = new KeyboardEvent('keydown', { keyCode:keycode['up'] }); window.dispatchEvent(evt); } //快进时显示醒目进度条 function dynamicProgress(dynamicHeight, staticHeight){ if(bb_type.indexOf(BILI_2_X) !== -1) { if (1||$('.bilibili-player-area').hasClass('progress-shadow-show') === true) { $('.bilibili-player-video-progress-shadow .bui-track-video-progress').css('cssText', `height:${dynamicHeight}px !important`); clearTimeout(document.showVideoProgress); document.showVideoProgress = window.setTimeout((function() { $('.bilibili-player-video-progress-shadow .bui-track-video-progress').css('cssText', `height:${staticHeight}px !important`); }), 2000); } } else { if(1||$('.bpx-player-container').hasClass('bpx-state-no-cursor') === true) { $('.squirtle-progress-buffer').css({'height': `${dynamicHeight/2}px`}); $('.squirtle-progress-timeline').css({'height': `${dynamicHeight/2}px`}); $('.squirtle-progress-totalline').css({'height': `${dynamicHeight/2}px`}); clearTimeout(document.showVideoProgress); document.showVideoProgress = window.setTimeout((function() { $('.squirtle-progress-buffer').css({'height': `${staticHeight}px`}); $('.squirtle-progress-timeline').css({'height': `${staticHeight}px`}); $('.squirtle-progress-totalline').css({'height': `${staticHeight}px`}); }), 2000); } } } //修复选择历史弹幕时弹幕填装信息丢失问题 function fix_danmaku_info() { if(bb_type.indexOf(BILI_2_X) !== -1) { //log($('.danmaku-box').length); $('.danmaku-box')[0].addEventListener('DOMSubtreeModified', function(e) { if($(e.target).hasClass('player-auxiliary-danmaku-list bpui-component bpui-undefined bpui-selectable') && $('.bilibili-player-video-info').hasClass('bilibili-player-hide-dm')) { $('.bilibili-player-video-info').removeClass('bilibili-player-hide-dm'); //得到弹幕数 let danmaku_number = $('.player-auxiliary-danmaku-contaner .player-auxiliary-danmaku-list').height()/$('.danmaku-info-row:first').height(); $('.bilibili-player-video-info-danmaku-number').text(danmaku_number); } }); } else { $('.bpx-player-video-info')[0].addEventListener('DOMSubtreeModified', function(e) { if($(e.target).hasClass('bpx-player-video-info-dm') && $('.bpx-player-video-info').hasClass('bpx-player-hide-dm')) { $('.bpx-player-video-info').removeClass('bpx-player-hide-dm'); } }); } } //初始化自定义设置 节点 事件 tips //setting - wrap - box | wrap - move - item function init_setting(run_default_setting_flag){ var $DSet = $(bb['dm']); var $wrap = $DSet.find('.bui-panel-wrap'); var $move = $DSet.find('.bui-panel-move'); var $item_0 = $DSet.find('.bui-panel-item:eq(0)'); var $item_1 = $DSet.find('.bui-panel-item:eq(1)'); var $item_2; var old_width = $item_0.width() + $item_1.width(); var item_0_height = $item_0.height() + 36; var item_2_width = $item_0.width() + 20; var item_2_height = 452+22*2; // if($DSet.length!=1 || $wrap.length!=1 || $move.length!=1) log('init_setting失败'); if($item_0.length!=1 || $item_1.length!=1) log('init_setting失败2'); /*----------------------------------- * 初始化 *----------------------------------*/ //初始化【$item_0】高度 $item_0.css('height', item_0_height); $item_0[0].hhh_new_height = item_0_height; //初始化【$move】宽度 $DSet.find('.bui-panel-move').css('width', old_width + item_2_width); /*----------------------------------- * 复制所需节点 *----------------------------------*/ //复制【item_0】【高级设置】To【自定义设置】 $(bb['dmLeftMore']).clone().appendTo(bb['dmLeft']).attr('id', 'hhh_more') .css('top', '20px') .find(bb['dmLeftMoreText']).text('自定义设置'); //复制【item_1】 To 【item_2】 $item_2 = $item_1.clone().appendTo($move).attr('id', 'hhh_item') .css({'width':item_2_width, 'height':item_2_height}) .removeClass('bui-panel-item-active') .find('div *').remove().end(); //复制【分割线】模板 var $separator = $item_1.find(`${bb['dmRightSeparator']}:first`).clone(); //复制【$title $hotkey父节点】模板 var $title_div = $item_0.find(bb['dmLeftBlock']).clone().attr('id', 'hhh_title_div') //.css({'display': 'flex', 'flex-direction': 'column'}) .empty().css({'margin-top': 6, 'margin-bottom': 2, 'height': 32+0}); //复制【title】模板 var $title = $item_0.find(bb['dmLeftBlockTitle']).clone().css({'color': '#12b3e8'}) .css({'display': 'inline-flex', 'line-height': '32px'}) .text('bilibili关灯自定义设置'); //复制【快捷键说明】模板 var $hotkey = $item_1.find(bb['dmRightMore']).clone().attr('id', 'hhh_item_2_hotkey') .css({'display': 'inline-flex', 'float': 'right'}) .find('span:first').remove().end() .find(bb['dmRightMoreText']).text('快捷键说明(点击切换)').end(); // var $div = $('
'); var $middle_div = $div.clone().css({'display':'flex', 'justify-content':'space-between'}); //复制【封面】模板 var $cover = $item_1.find(bb['dmRightMore']).clone().attr('id', 'hhh_item_2_cover') //.css({'display': 'inline-flex', 'float': 'right', 'flex-direction': 'row-reverse'}) //.css({'float': 'right'}) .find('span:first').remove().end() .find(bb['dmRightMoreText']).text('显示封面(点击切换)').end(); //复制【input-checkbox父节点】模板 var $input_div = $item_0.find(bb['dmLeftBlock']).clone().attr('id', 'hhh_input_div') .empty().css({'margin-top': 4, 'margin-bottom': 2}) //.css('background', 'blue') //.css('width', 200) ; //复制【更多其他】模板 var $more_div = $item_0.find(bb['dmLeftBlock']).clone().attr('id', 'hhh_input_div2') .empty().css({'margin-top': 4, 'margin-bottom': 2}) //.css('background', 'red') //.css('width', 100).css('height', 100) ; //复制【input-checkbox】模板 var $input = $item_0.find(bb['dmLeftFlagTitle']).clone().css({'display': 'flex', 'margin-top': '6px'}) //inline-flex .find('input').removeAttr('aria-label').prop('checked', false).end() .find('.bui-checkbox-name').text('bilibili关灯').end(); //复制【恢复默认设置】模板 var $reset = $item_1.find(bb['dmRightReset']).clone().css({'margin-top': 6, 'margin-bottom': 6}); //复制【返回】模板 var $reback = $item_1.find(bb['dmRightMore']).clone().attr('id', 'hhh_item_2_more') .css({'margin-top': 2}) .find(bb['dmRightMoreText']) .text('返回').end(); /*----------------------------------- * 添加节点 *----------------------------------*/ let $item_2_div = $item_2.children(':first'); /*----------------------------------- * 上部div *----------------------------------*/ //添加title hotkey $title_div.appendTo($item_2_div); $title.clone().appendTo($title_div); $hotkey.clone().appendTo($($title_div)); //添加分割线 $separator.clone().appendTo($item_2_div); /*----------------------------------- * 中部div *----------------------------------*/ $middle_div.appendTo($item_2_div); $input_div.appendTo($middle_div); $more_div.appendTo($middle_div); //添加 & 初始化【checkbox】 for (let [key, { text, status, args, show }] of Object.entries(config.sets)) { if(show === OFF) continue; $input.clone().appendTo($input_div).attr('id', key) .find('input').prop('checked', status).end() .find('.bui-checkbox-name').text(text); if(key === 'volumeControlWhenNonFullScreen') config.setCheckboxSettingTips('volumeControlWhenNonFullScreen', `在屏幕中间${Math.round((args.screenRight-args.screenLeft)*100)}%范围内调节,步幅${args.delta}%`); } //添加恢复默认设置 $reset.clone().appendTo($input_div); //添加封面 $cover.appendTo($more_div); /*----------------------------------- * 下部div *----------------------------------*/ //添加分割线 $separator.clone().appendTo($item_2_div); //添加返回 $reback.clone().appendTo($item_2_div); /*----------------------------------- * 添加事件等 *----------------------------------*/ //重设置【设置按钮】 // $DSet.mouseenter(function(){ // $wrap.css('height', $DSet.find('.bui-panel-item-active').css('height')); // }) //重设置【item_0 - 自定义设置】 $('#hhh_more').click(function(){ $wrap.css({'height': $item_2.css('height'), 'width': $item_2.css('width')}); $move.css('transform', `translateX(-${old_width}px)`); $DSet.find('.bui-panel-item-active').removeClass('bui-panel-item-active'); $item_2.addClass('bui-panel-item-active'); }) //重设置【item_1 - 更多弹幕设置】 $item_1.find(bb['dmRightMore']).click(function(){ $item_0.css('height', item_0_height); //会改变item_0长度 $wrap.css({'height': $item_0.css('height'), 'width': $item_0.css('width')}); }) //重设置【item_2 - 返回】 $item_2.find('#hhh_item_2_more').click(function(){ $wrap.css({'height': $item_0.css('height'), 'width': $item_0.css('width')}); $move.css('transform', 'translateX(0px)'); $DSet.find('.bui-panel-item-active').removeClass('bui-panel-item-active'); $item_0.addClass('bui-panel-item-active'); }) //重设置【item_2 - 封面】 $item_2.find('#hhh_item_2_cover').click(function(){ if($('#hhh_img').length === 1){ let $hhh_img = $('#hhh_img'); //let width = $(bb['video']).width()*0.9; //$('#hhh_img').css('width', width); $hhh_img.css('display') === 'none'? $hhh_img.css('display', 'flex'): $hhh_img.css('display', 'none'); } else { let $img = $(``); let $d = $div.clone().attr('id', 'hhh_img') .css({position: 'absolute', top:'50%', left:'50%', transform: 'translate(-50%,-50%)'}) .css({'z-index':`${$(bb['playTipWrap']).css('z-index')}`}) .css({'display':'flex'}) //.css('width',width) .css({'align-items':'center','justify-content':'center'}) .appendTo($(bb['videoWrap'])); $img.css({width:'100%', height:'auto'}).appendTo($d); //重设置【item_2 - 封面 - IMG】 $('#hhh_img').click(function(){ $(this).css('display','none'); window.open($(bb['coverImg']).attr('content').replace('http:','https:')); }) //let width = $(bb['video']).width()*0.9; //log(width); //if($img.width() > width) $('#hhh_img').css('width', 0); //log($('#hhh_img').width()); //log($img.width()); } }) //重设置【item_2 - 快捷键说明】 let set_hotkey_panel_close = false; $item_2.find('#hhh_item_2_hotkey').click(function(){ let is_active = bb_type.indexOf(BILI_2_X) !== -1 ? $(bb['hotkeyPanel']).hasClass('active') : $(bb['hotkeyPanel']).css('display') !== 'none'; //2.X和3.X不一样?我来让你一样! if(is_active === false){ let evt = new MouseEvent('contextmenu', { clientX:-9999, clientY:-9999 }); $(bb['videoWrap'])[0].dispatchEvent(evt); evt = bb_type.indexOf(BILI_2_X) !== -1? new MouseEvent('click', { bubbles:true }): new MouseEvent('mousedown', { bubbles:true }); let node = bb_type.indexOf(BILI_2_X) !== -1? 'a': 'li'; $(bb['playerContextMenu']).find(`${node}:contains("快捷键说明(bilibili关灯)")`)[0].dispatchEvent(evt); //$(bb['playerContextMenu']).find(`li:contains("快捷键说明(bilibili关灯)")`).mousedown(); let $hotkey = $(bb['hotkeyPanel']); //let $hotkey = $(bb['hotkeyPanel']).css('z-index', $(bb['playVideoControlWrap']).css('z-index')-1); //同步显示 // let wrap_left = $(bb['dmWrap']).position().left; // let box_left = $(bb['dmBox']).position().left; // $(bb['dmWrap']).css('left', wrap_left + $item_0.width()); // $(bb['dmBox']).css('left', box_left - $item_0.width()); // $(bb['dmWrap']).css('height', $hotkey.innerHeight()); // $(bb['dmWrap']).css('width', $hotkey.innerWidth()-50); // $(bb['dmBox']).css('width', item_2_width); //$(bb['dmWrap']).css('background', 'blue').css('opacity', 0.8); //test //同步隐藏 // waitForTrue(()=> ($(bb['hotkeyPanel']).hasClass('active') === false && $(bb['hotkeyPanel']).css('display') === 'none') || $(bb['dmWrap']).css('display') === 'none', () => { // //$(bb['hotkeyPanel']).removeClass('active').css('display', 'none'); // $(bb['hotkeyPanelClose']).click(); // }); let new_left = $item_2.offset().left + $item_2.width(); let new_top = $hotkey.offset().top + ($item_2.offset().top + $item_2.height()) - ($hotkey.offset().top + $hotkey.innerHeight()); $hotkey.offset({left:new_left, top:new_top}); //$hotkey.offset({left:new_left, top:new_top}).find(bb['hotkeyPanelClose']).css('display', 'none'); if(set_hotkey_panel_close === false){ // set_hotkey_panel_close = true; $(bb['hotkeyPanelClose']).click(function(){ $(bb['hotkeyPanel']).css({left: '50%', top:'50%'}); }) } }else{ $(bb['hotkeyPanel']).css({left: '50%', top:'50%'}); $(bb['hotkeyPanelClose']).click(); // $(bb['dmWrap'])[0].style.cssText = ''; // $(bb['dmBox'])[0].style.cssText = ''; // $(bb['dmWrap']).css('display', 'block'); } }) /* //重设置【item_2 - 快捷键说明】 $item_2.find('#hhh_item_2_hotkey').dblclick(function(){ let is_active = bb_type.indexOf(BILI_2_X) !== -1 ? $(bb['hotkeyPanel']).hasClass('active') : $(bb['hotkeyPanel']).css('display') !== 'none'; //2.X和3.X不一样?我来让你一样! if(is_active === false){ let hotkey_class = bb['hotkeyPanel'].substr(1); $('#hhh_hotkey_panel').clone(true,true).replaceAll($(`.${hotkey_class}:last`)).attr({'id': '', 'class': hotkey_class, 'style': ''}); let $hotkey = $(bb['hotkeyPanel']).addClass('active').css('z-index', $(bb['playVideoControlWrap']).css('z-index')-1); //同步显示 let wrap_left = $(bb['dmWrap']).position().left; let box_left = $(bb['dmBox']).position().left; $(bb['dmWrap']).css('left', wrap_left + $item_0.width()); $(bb['dmBox']).css('left', box_left - $item_0.width()); $(bb['dmWrap']).css('height', $hotkey.innerHeight()); $(bb['dmWrap']).css('width', $hotkey.innerWidth()-100); $(bb['dmBox']).css('width', item_2_width); //$(bb['dmWrap']).css('background', 'blue').css('opacity', 0.8); //test //同步隐藏 waitForTrue(()=> ($(bb['hotkeyPanel']).hasClass('active') === false && $(bb['hotkeyPanel']).css('display') === 'none') || $(bb['dmWrap']).css('display') === 'none', () => { $(bb['hotkeyPanel']).removeClass('active').css('display', 'none'); }); let new_left = $item_2.offset().left + $item_2.width(); let new_top = $hotkey.offset().top + ($item_2.offset().top + $item_2.height()) - ($hotkey.offset().top + $hotkey.innerHeight()); $hotkey.offset({left:new_left, top:new_top}).find(bb['hotkeyPanelClose']).css('display', 'none'); }else{ $(bb['hotkeyPanel']).removeClass('active').css('display', 'none'); $(bb['dmWrap'])[0].style.cssText = ''; $(bb['dmBox'])[0].style.cssText = ''; $(bb['dmWrap']).css('display', 'block'); } }) */ //set key function key_setting(key, status, fn, args){ if(key === 'volumeControlWhenNonFullScreen'){ let pause_status = config.getCheckboxSettingStatus('volumeControlWhenPause'); eval(`${fn}(${status}, ${args.screenLeft}, ${args.screenRight}, ${args.delta}, ${pause_status})`); } else if(key === 'volumeControlWhenPause'){ let non_full_status = config.getCheckboxSettingStatus('volumeControlWhenNonFullScreen'); let fn = config.getCheckboxSettingFn('volumeControlWhenNonFullScreen'); let args = config.getCheckboxSettingArgs('volumeControlWhenNonFullScreen'); eval(`${fn}(${non_full_status}, ${args.screenLeft}, ${args.screenRight}, ${args.delta}, ${status})`); } else if(key === 'danmuOpacityControl'){ eval(`${fn}(${status}, ${args.delta})`); } else if(key === 'hotKeyHint'){ is_show_hint = config.getCheckboxSettingStatus(key); } else if(!!fn){ // openHotKey | removeVideoTopMask 等 eval(`${fn}(${status})`); //Function(`${fn}(${status})`)(); } } //重设置【item_2 - 恢复默认设置】 $item_2.find(bb['dmRightReset']).click(function(){ for (let [key, { text, status, tips, fn, args }] of Object.entries(config.b_playerCheckbox.options)) { if(get_value(key) === status) continue; $(`#${key}`).find('input').prop('checked', status); set_value(key, status); config.setCheckboxSettingStatus(key, status); key_setting(key, status, fn, args); } }) //设置【checkbox】选择 $item_2.find('#hhh_input_div').click(function(e){ if(e.target.type === 'checkbox'){ let key = bb_type.indexOf(BILI_2_X) !== -1 ? e.target.parentNode.id : e.target.parentNode.parentNode.id; let status = e.target.checked; set_value(key, status); config.setCheckboxSettingStatus(key, status); let fn = config.getCheckboxSettingFn(key); let args = config.getCheckboxSettingArgs(key); key_setting(key, status, fn, args); } }) //重设置【item_2 - 恢复默认设置】 $DSet.on('mouseenter', function(){ if ($(bb['dmWrap']).css('display') !== 'none') return; $item_0.css('height', $item_0[0].hhh_new_height); $wrap.css({'height': $item_0.css('height'), 'width': $item_0.css('width')}); $move.css('transform', 'translateX(0px)'); $DSet.find('.bui-panel-item-active').removeClass('bui-panel-item-active'); $item_0.addClass('bui-panel-item-active'); $(bb['dmWrap'])[0].style.cssText = ''; $(bb['dmBox'])[0].style.cssText = ''; }) //set tips waitForTrue(()=> ($tip !== undefined && $(`#${Object.keys(config.sets)[0]}`).length === 1), () => { if(bb_type === BILI_3_X) $('.squirtle-controller-wrap').css({"display":"flex"}); $(bb['dmWrap']).css({"display":"block"}); for (let [key, { text, status, tips }] of Object.entries(config.sets)) { let $key = $(`#${key}`); $key.width($key.find('label').width()); //调整宽度 !!tips && add_tip($tip, $key, {'text':tips, 'millisec':200, 'top':9, 'left':0}); } $(bb['dmWrap']).css({"display":"none"}); if(bb_type === BILI_3_X) $('.squirtle-controller-wrap').css({"display":"none"}); }) //执行所有默认设置 if(run_default_setting_flag === 'run_default_setting') $item_2.find(bb['dmRightReset']).click(); } //自定义快捷键设置 //ON - 启用热键,OFF - 关闭热键 function set_hotkey(open){ if (open !== ON){ $(document).off('keyup.hhh_lightoff'); $(document).off('keydown.hhh_lightoff'); }else{ var parent = document; var like_shake = false; var prev_time = 0; is_show_hint = config.getCheckboxSettingStatus('hotKeyHint'); //up $(document).off('keyup.hhh_lightoff'); $(document).on('keyup.hhh_lightoff',function(e){ if(!!e.target.type && e.target.type.toLowerCase().search(/text|textarea/) !== -1) return; if(e.target.className === 'ql-editor') return; if(e.keyCode === 'Y'.charCodeAt() || e.keyCode === 'O'.charCodeAt()) { //点赞;长按一键三连 $(bb['like'])[0].dispatchEvent(new MouseEvent('mouseup')); if(e.keyCode === 'Y'.charCodeAt() && like_shake === false) { let like_text = $(bb['like']).text().match(/.+/)[0]; let like_num = like_text.match(/\d+$/)? (+like_text.match(/\d+$/)[0])+1: like_text; if($(bb['likeon']).length === 1) showHint(parent, '#hhh_wordsHint', '取消点赞'); else showHint(parent, '#hhh_wordsHint', `点赞成功 ${like_num}`); $(bb['like']).click(); } like_shake = false; } }); //down $(document).off('keydown.hhh_lightoff'); $(document).on('keydown.hhh_lightoff',function(e){ //log(!!e.target.type === true); //log($(e.target.className)); //跳过输入框 if(!!e.target.type && e.target.type.toLowerCase().search(/text|textarea/) !== -1) return; if(e.target.className === 'ql-editor') return; //以下使用功能键 if(e.shiftKey && (e.keyCode === keycode['left'] || e.keyCode === keycode['right'])) { //逐帧 shift+ left/right h5Player.pause(); for(let move_frames = 1.01; move_frames>0.2;){ let move_frames_time = move_frames/fps; h5Player.currentTime = e.keyCode === keycode['left']? +(h5Player.currentTime - move_frames_time).toFixed(3): +(h5Player.currentTime + move_frames_time).toFixed(3); if(prev_time === h5Player.currentTime){ //如果未走帧 move_frames /= 2; //log('2.1: '+h5Player.currentTime+' - '+prev_time+' - '+move_frames_time+' - '+move_frames); continue; } else{ //log('2.2: '+h5Player.currentTime+' - '+prev_time+' - '+move_frames_time+' - '+move_frames); let total_frame = +(h5Player.duration*fps).toFixed(); let current_frame = +(h5Player.currentTime*fps).toFixed(); showHint(parent, '#hhh_wordsHint', `${current_frame}/${total_frame}`); prev_time = h5Player.currentTime; break; } } e.stopPropagation(); } else if(e.ctrlKey && (e.keyCode === keycode['left'] || e.keyCode === keycode['right'])) { //+ -30s ctrl+ left/right $(bb['danmakuSwitch']).last().find('input').click().click(); h5Player.currentTime = e.keyCode === keycode['left']? h5Player.currentTime - 30: h5Player.currentTime + 30; h5Player.play(); dynamicProgress(16, 2); } else if(e.ctrlKey && (e.keyCode === keycode['up'] || e.keyCode === keycode['down'])) { //ctrl + -播放速度 if(config.getCheckboxSettingStatus('keyVideoSpeed') === OFF) return; window.setTimeout((function() { //长按时保持DOM更新 e.keyCode === keycode['up']? video_select_speed(1): video_select_speed(-1); }),10); } else if(e.ctrlKey && e.keyCode === keycode['Enter']) { //全屏 fullscreen(); } //以下不使用功能键 if(e.ctrlKey || e.altKey || e.shiftKey) return; if(e.keyCode === 'A'.charCodeAt()){ //开关灯 is_show_hint && (is_lightoff() ? showHint(parent, '#hhh_wordsHint', '开灯') : showHint(parent, '#hhh_wordsHint', '关灯')); lightoff_btn(); } else if(e.keyCode === 'W'.charCodeAt()) { //网页全屏 Bb站改成点赞了 web_fullscreen(); e.stopPropagation(); } else if(e.keyCode === 'Q'.charCodeAt()) { //宽屏模式 B站改成投币了 is_fullscreen() ? web_fullscreen() : wide_screen(); e.stopPropagation(); } else if(e.keyCode === 'D'.charCodeAt()) { //开关弹幕 bilibili增加了关弹幕的快捷键,也是D $(bb['danmakuSwitch']).last().find('input').click(); is_show_hint && (is_danmaku_show() === true ? showHint(parent, '#hhh_wordsHint', '开弹幕') : showHint(parent, '#hhh_wordsHint', '关弹幕')); e.stopPropagation(); } else if(e.keyCode === 'T'.charCodeAt()) { //开关顶部弹幕 $(bb['danmukuTopClose']).length === 0 ? showHint(parent, '#hhh_wordsHint', '关闭顶部弹幕') : showHint(parent, '#hhh_wordsHint', '打开顶部弹幕'); $(bb['danmukuTop']).click(); } else if(e.keyCode === 'B'.charCodeAt()) { //开关底部弹幕 $(bb['danmukuBottomClose']).length === 0 ? showHint(parent, '#hhh_wordsHint', '关闭底部弹幕') : showHint(parent, '#hhh_wordsHint', '打开底部弹幕'); $(bb['danmukuBottom']).click(); } else if(e.keyCode === 'S'.charCodeAt()) { //弹幕随屏幕缩放 $(bb['settingFs'])[0].checked === false ? showHint(parent, '#hhh_wordsHint', '弹幕随屏幕缩放') : showHint(parent, '#hhh_wordsHint', '弹幕不随屏幕缩放'); $(bb['settingFs']).click(); } else if(e.keyCode === 'R'.charCodeAt()) { //开关洗脑循环 B站改成一键三连了 $(bb['playSettingRepeatInput'])[0].checked ? showHint(parent, '#hhh_wordsHint', '关洗脑循环') : showHint(parent, '#hhh_wordsHint', '开洗脑循环'); $(bb['playSettingRepeatInput']).click(); e.stopPropagation(); } else if(e.keyCode === 'Z'.charCodeAt() || e.keyCode === 'C'.charCodeAt()) { //+ -弹幕透明度 let inc_percent = e.keyCode === 'Z'.charCodeAt()? -10: 10; window.setTimeout((function() { //长按时保持DOM更新 let opacity = adjust_progress(bb['settingOpacity'], inc_percent, 10, 100); showHint(parent, '#hhh_opacityHint', '透 ' + opacity); }),10); } else if(e.keyCode === 'V'.charCodeAt() || e.keyCode === 'N'.charCodeAt()) { //+ -弹幕字号 let inc_percent = e.keyCode === 'V'.charCodeAt()? -10: 10; window.setTimeout((function() { //长按时保持DOM更新 let opacity = adjust_progress(bb['settingFontsize'], inc_percent, 50, 170); showHint(parent, '#hhh_opacityHint', '字 ' + opacity); }),10); } else if(e.keyCode >= '1'.charCodeAt() && e.keyCode <= '5'.charCodeAt()) { //弹幕显示区域 var area_text = {0:'1/4屏',25:'半屏',50:'3/4屏',75:'不重叠',100:'不限'}; var percent = (e.keyCode - '1'.charCodeAt()) * 25; //((0~4)*25)% set_progress(bb['settingArea'], percent, 0, 100); showHint(parent, '#hhh_wordsHint', area_text[percent]); } else if(e.keyCode === keycode['left'] || e.keyCode === keycode['right']){ //快进时显示醒目进度条 && 段落循环 //log( $('#hhh_loop_wrap')[0].hhh_loop_playback_click ); if(0&&$('#hhh_loop_wrap')[0].hhh_loop_playback_click === true){ //log('快进时显示醒目进度条 && 段落循环'); return false; }else{ if(config.getCheckboxSettingStatus('reloadDanmuku') === ON) { //恢复重载弹幕效果 e.stopPropagation(); h5Player.currentTime = e.keyCode === keycode['left']? h5Player.currentTime - 5: h5Player.currentTime + 5; h5Player.play(); setTimeout(function(){ $(bb['danmakuSwitch']).last().find('input').click(); $(bb['danmakuSwitch']).last().find('input').click(); },0); } dynamicProgress(16, 2); } } else if(e.keyCode === keycode['up'] || e.keyCode === keycode['down']) { //音量控制,替换系统默认 //$(bb['volumeHint']).css({"visibility":"visible"}) //隐藏所有提示,避免提示重叠 //$(bb['volumeHint']).css('display', 'none'); let diff = e.keyCode === keycode['up']? 0.05: -0.05; window.setTimeout((function() { //长按时保持DOM更新 volume(volume()+diff); }),10); return false; } else if(e.keyCode === keycode['space']) { //空格键2.X版本不合理,改成和3.X版本一样,3.X版也O了 if(!is_fullscreen()){ if(is_in_biliplayer === false) e.stopPropagation() } } else if(e.keyCode === keycode['Esc']){ //优先取消右键菜单等 if($(bb['hotkeyPanel']).length === 1 && ($(bb['hotkeyPanel']).hasClass('active') === true || $(bb['hotkeyPanel']).css('display') !== 'none')){ //$(bb['hotkeyPanel']).removeClass('active').css('display', 'none'); $(bb['hotkeyPanel']).find(bb['hotkeyPanelClose']).click(); //慢 return false; } if($(bb['playerContextMenu']).hasClass('active') === true || $(bb['playerContextMenu']).hasClass('bpx-player-active') === true ){ let evt = new MouseEvent('contextmenu', { clientX:-9999, clientY:-9999 }); $(bb['videoWrap'])[0].dispatchEvent(evt); return false; } if($('#hhh_img').length >= 1 && $('#hhh_img').css('display') !== 'none'){ $('#hhh_img').css('display', 'none'); return false; } //对应 系统快捷键 Q、R、W、E } else if(e.keyCode === 'Y'.charCodeAt() || e.keyCode === 'O'.charCodeAt()) { //长按一键三连 $(bb['like'])[0].dispatchEvent( new MouseEvent('mousedown') ); if(like_shake === false) like_shake = !!$('.van-icon-videodetails_like.shake').length; } else if(e.keyCode === 'U'.charCodeAt()) { //投币 $(bb['coin']).click(); } else if(e.keyCode === 'I'.charCodeAt()) { //收藏 $(bb['collect']).click(); //TEST } else if(e.keyCode === 'X'.charCodeAt() || e.keyCode === keycode['/']) { //TEST 显示、隐藏video-control if($(bb['playArea']).hasClass('video-control-show') === true) $(bb['playVideoControlWrap']).mouseout(); else $(bb['playVideoControlWrap']).mousemove(); } else if(e.keyCode === 'V'.charCodeAt()) { //TEST //if(bb_type===BILI_3_X) $('.bpx-player-dm-setting-wrap').css('display','block'); $('.bilibili-player-video-danmaku-setting-wrap').mouseover(); //$('.bilibili-player-area.video-state-blackside').attr('class', 'bilibili-player-area video-state-blackside video-state-pause video-control-show'); }else{ //console.dir(e.keyCode); } }); } } //因为遮挡弹幕,去掉全屏时鼠标悬停时产生的顶端mask function removeVideoTopMask(is_remove){ let top_mask_class = bb['videoTopMask'].substr(1); if(is_remove === ON) $(bb['videoTopMask']).attr('id', top_mask_class).removeClass(); else $(`#${top_mask_class}`).addClass(top_mask_class); } //播放关灯,暂停开灯,跳过充电 function lightOffWhenPlaying(status){ $(h5Player).off('play.hhh'); if(status === OFF) return; $(h5Player).on('play.hhh', ()=> !is_lightoff() && lightoff_btn()); } function lightOnWhenPause(status){ $(h5Player).off('pause.hhh'); if(status === OFF) return; $(h5Player).on('pause.hhh', ()=> is_lightoff() && lightoff_btn()); } function jumpElectric(status){ $(h5Player).off('ended.hhh'); if(status === OFF) return; $(h5Player).on('ended.hhh', ()=> $(bb['playJumpElectric']).click()); } //双击或中键全屏 function dblclickFullScreen(status){ $(bb['videoWrap']).off('mousedown.hhh'); if(status === OFF) return; $(bb['videoWrap']).on('mousedown.hhh', function(e){ if(e.button === 1 || e.button === 4 || e.button === 3) { // 1中键 if(e.button === 1) web_fullscreen(); else fullscreen(); e.preventDefault(); e.stopPropagation(); } }); //$(bb['playTipWrap']).dblclick(function(){ fullscreen() }); //2.66自带双击全屏 } //调节视频倍速 function video_select_speed(level) { let data_x = ['0.5x', '0.75x', '1.0x', '1.25x', '1.5x', '2.0x']; let curr_x = $(bb['videoSpeedActive']).text(); let x = data_x[data_x.indexOf(curr_x) + level]; log(curr_x+' - '+x+' - '+data_x.indexOf(curr_x)); if(x !== undefined) $(`${bb["videoSpeed"]}:contains("${x}")`).click(); showHint(parent, '#hhh_wordsHint', x); } //扩展播放倍速范围 function extend_video_speed(){ let $speedul = $(bb['videoSpeedActive']).parent(); let $li_0_1x = $speedul.find('li:first').clone(true, true).text('0.1x'); $speedul.append($li_0_1x); let $li_1_7_5x = $speedul.find('li:first').clone(true, true).text('1.75x'); $speedul.find('li:contains(2.0x)').after($li_1_7_5x); let $li_3x = $speedul.find('li:first').clone(true, true).text('3.0x'); let $li_3_5x = $speedul.find('li:first').clone(true, true).text('3.5x'); let $li_4x = $speedul.find('li:first').clone(true, true).text('4.0x'); let $li_4_5x = $speedul.find('li:first').clone(true, true).text('4.5x'); let $li_5x = $speedul.find('li:first').clone(true, true).text('5.0x'); $speedul.prepend($li_3x); $speedul.prepend($li_3_5x); $speedul.prepend($li_4x); $speedul.prepend($li_4_5x); $speedul.prepend($li_5x); $speedul.find('li').each(function(e){ let $this = $(this); $this.attr('data-value', `${$this.text().split('x')[0]}`); }) $speedul.on('click', function(e){ let $li = $(e.target); let speed = $li.attr('data-value'); if(speed !== undefined){ h5Player.playbackRate = speed; setTimeout(function(){ let speed_active = bb_type === BILI_3_X? 'active': 'bilibili-player-active'; $(bb['videoSpeedActive']).removeClass(speed_active); $li.addClass(speed_active); $(bb['videoSpeedName']).text($li.text()); },0) } }) } //主程序 function run(){ //防止重复加载 if ($('#hhh_lightoff').length === 1) { log('重复加载'); return } //bpx test function bpx_test(){ log('-------------------'); log('ver: '+ver); log('fps: '+fps); log('------h5Player-----'); dir(h5Player); log('currentTime : '+h5Player.currentTime); log('duration : '+h5Player.duration); log('playbackRate : '+h5Player.playbackRate); log('volume : '+h5Player.volume); log('paused : '+h5Player.paused); log('pause() : '+'h5Player.pause()'); log('videoHeight : '+h5Player.videoHeight); log('videoWidth : '+h5Player.videoWidth); log('-------------------'); } /*----------------------------------- *初始化等 *----------------------------------*/ //保存设置信息 && 快捷键信息 config.saveCheckboxSetting(); for (let [key, { text, status }] of Object.entries(config.sets)) { if(get_value(key) === undefined) set_value(key, status); else config.sets[key]['status'] = JSON.parse(get_value(key)); } //取得h5 video & window.player h5Player = ($(`${bb['video']} video`)[0] || $(`${bb['video']} bwp-video`)[0]); //bili_player = window.player; //初始化关灯按钮 lightoff_init(); //激活系统弹幕设置,以此调用系统网页全屏等 $(bb['dm']).mouseenter().mouseleave(); //保存tip $('.bilibili-player-video-danmaku-setting-left-ps').mouseover(); waitForTrue(()=> $('.player-tooltips.tip.top-center.animation').length === 1, () => { $tip = $('.player-tooltips.tip.top-center.animation').clone().removeClass('active'); $tip.find('.tooltip').css('background-color', 'rgba(0,0,0,0.9)'); $('.bilibili-player-video-danmaku-setting-left-ps').mouseout(); }); //激活系统播放设置,以此调用系统关灯等 //去掉mouseleave(),否则如果太快执行mouseleave()无法激活关灯class,应该是mouseenter()未执行完就被mouseleave打断了 $(`${bb['playVideo']}${bb['playSetting']}`).mouseenter(); //避免显示设置页面 waitForNode(() => document.querySelector(bb['playSettingWrap']), (node) => {; $(node).css({"visibility":"hidden"}); //visible }) //解决因为激活关灯class,导致全屏时滚轮操作(系统自带)无法调节音量的问题 waitForTrue(()=> $(bb['playSettingWrap']).css('display') === 'block', () => { $(bb['playSettingWrap']).css('display', 'none').css('visibility', 'visible'); }); //取得视频fps get_video_fps_ver(); //取得版本号 //get_ver(); //激活系统提示添加音量等自定义提示DOM pick_volume_hint(); //添加自定义快捷键说明到右键菜单 add_custom_hotkey_menu(config.hotKeyMenu); //初始化自定义设置 init_setting(); /*----------------------------------- *事件等 *----------------------------------*/ //点击关灯 $(`#hhh_lightoff ${bb['switchInput']}:first`).click(function(){ lightoff_btn() }); //判断当前鼠标点击焦点 $(document).mouseup(function(e){ if(e.originalEvent === undefined) return; let path = e.originalEvent.path; curr_focus = path[0]; is_in_biliplayer = false; $(path).each(function(){ if(this.id === 'bilibili-player') { is_in_biliplayer = true; return; } }) //隐藏封面 2.x && 3.x if(is_in_biliplayer == false || e.target.className === 'bilibili-player-dm-tip-wrap' || e.target.tagName.toLowerCase() === 'video'){ $('#hhh_img').css('display', 'none'); } }) //扩展播放倍速范围 extend_video_speed(); //修复选择历史弹幕时弹幕填装信息丢失问题 fix_danmaku_info(); //自动运行 if(config.getCheckboxSettingStatus('autoPlay') === ON && $(bb['playSettingAutoplay'])[0].checked === false) $(bb['playSettingAutoplay']).click();//开启自动播放 if(config.getCheckboxSettingStatus('lightOff') === ON) lightoff_btn(); //自动关灯 if(config.getCheckboxSettingStatus('autoFullScreen') === ON) fullscreen(); //自动全屏 if(config.getCheckboxSettingStatus('autoWebFullScreen') === ON) web_fullscreen(); //自动网页全屏 if(config.getCheckboxSettingStatus('videoRepeat') === ON) $(bb['playSettingRepeatInput']).click(); //开启洗脑循环 //双击或中键全屏 dblclickFullScreen(config.getCheckboxSettingStatus('dblclickFullScreen')); //非全屏滚轮音量调节 //两个参数指定屏幕范围(按百分比),第三个参数表示滚动一下增加的音量百分比,参数四表示暂停时是否调节 let args = config.getCheckboxSettingArgs('volumeControlWhenNonFullScreen'); wheel_volumeHint(config.getCheckboxSettingStatus('volumeControlWhenNonFullScreen'), args.screenLeft,args.screenRight,args.delta, config.getCheckboxSettingStatus('volumeControlWhenPause')); //滚轮调节弹幕透明度(ctrl),参数表示滚动一下增加的透明度百分比,默认5 wheel_opacity(config.getCheckboxSettingStatus('danmuOpacityControl'), 5); //因为遮挡弹幕,去掉全屏时鼠标悬停时产生的顶端mask removeVideoTopMask(config.getCheckboxSettingStatus('removeVideoTopMask')); //播放关灯,暂停开灯,跳过充电鸣谢 lightOffWhenPlaying(config.getCheckboxSettingStatus('lightOffWhenPlaying')); lightOnWhenPause(config.getCheckboxSettingStatus('lightOnWhenPause')); jumpElectric(config.getCheckboxSettingStatus('jumpElectric')); //记忆洗脑循环 if(config.getCheckboxSettingStatus('rememberVideoRepeat') === ON && config.getCheckboxSettingStatus('videoRepeat') !== ON) { if(JSON.parse(get_value('hhh-rememberVideoRepeat', $(bb['playSettingRepeatInput'])[0].checked)) === true) $(bb['playSettingRepeatInput']).click(); //localStorage只能保存字符串 $(bb['playSettingRepeatInput']).click(function() { set_value('hhh-rememberVideoRepeat', $(bb['playSettingRepeatInput'])[0].checked); }); }; /*----------------------------------- *键盘控制 *----------------------------------*/ set_hotkey(config.getCheckboxSettingStatus('openHotKey')); /*设置界面 //viewBox="10 8.5 10 12" $('.bilibili-player-video-danmaku-setting').clone(false,false).insertBefore($('#hhh_lightoff')).attr('id', 'hhh_setting') $('#hhh_setting>span>svg')[0].attributes[1].value = '10 8.5 10 12' $('#hhh_setting>span>svg>path:first').remove() */ //段落循环 //loop_playback(); //TEST bpx_test(); log(bb) // log($('.bilibili-player-video-danmaku-switch .bui-switch-input').length); // log($('.bilibili-player-video-danmaku-switch .bui-switch-input')[0].checked); // log($('.bilibili-player-video-danmaku-switch .bui-switch-input')[1].checked); // setTimeout(function(){log($('.bilibili-player-video-danmaku-switch .bui-switch-input')[0].checked); // log($('.bilibili-player-video-danmaku-switch .bui-switch-input')[1].checked);},1000) } //段落循环 function loop_playback(){ if(bb_type.indexOf(BILI_2_X) === -1) return false; var is_begin = true, first = true; function show_loop_time(sign_show){ $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-cut-img').hide(); if(sign_show !== 'sign_show') $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-sign').hide(); $('.bilibili-player-video-progress .bilibili-player-video-progress-detail').show(); $('.bilibili-player-video-progress .bilibili-player-video-progress-detail').css('opacity',1); } function hide_loop_time(){ $('.bilibili-player-video-progress .bilibili-player-video-progress-detail').css({display:''}); $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-cut-img').show(); $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-sign').show(); } //loop显示状态切换 function loop_state_switch(state){ $('#hhh_loop_wrap')[0].hhh_loop_state_switch = state; let $p1 = $('#hhh_loop_1'), $p2 = $('#hhh_loop_2'), $bar = $('#hhh_loop_bar'); if(state === 0){ //no loop $p1.hide(), $p2.hide(), $bar.hide(); }else if(state === 1){ //loop 1 if($p1[0].hhh_seconds) $p1.show(); if($p2[0].hhh_seconds) $p2.show(); if($p1[0].hhh_seconds && $p2[0].hhh_seconds) $bar.show(); }else{ //loop 2 $p1.hide(), $p2.hide(); if($p1[0].hhh_seconds && $p2[0].hhh_seconds) $bar.show(); } } //更新 function loop_update($hhh_loop, o){ //function PrefixZero(num, n) { return (Array(n).join(0) + num).slice(-n) } //time = PrefixZero(Math.floor(time/60),2) + ':' + PrefixZero(time%60,2); var left = 0, seconds = 0, rect = $('.bilibili-player-video-progress')[0].getBoundingClientRect(); if(o.left !== undefined){ left = o.left - rect.x; if(left < 0 || left > rect.width) return; //Position To Time seconds = Math.round(left/$('.bilibili-player-video-progress').width()*h5Player.duration); }else if(o.seconds !== undefined){ //Time To Position left = o.seconds/h5Player.duration*$('.bilibili-player-video-progress').width(); if(left < 0 || left > rect.width) return; seconds = o.seconds; }else{ log('参数错误',o); return;} //updata x $hhh_loop.css({left:left}); $('.bilibili-player-video-progress .bilibili-player-video-progress-detail').css({left:left}); //updata time $hhh_loop[0].hhh_seconds = seconds; function sec2str(t){ var d = Math.floor(t/86400), h = (''+Math.floor(t/3600) % 24).slice(-2), m = ('0'+Math.floor(t/60)%60).slice(-2), s = ('0' + t % 60).slice(-2); return (d>0?d+'d ':'')+(h5Player.duration>=3600?h+':':'')+m+':'+s; } let time = sec2str(seconds); $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-time').text(time); //updata bar let t1 = $('#hhh_loop_1')[0].hhh_seconds; let t2 = $('#hhh_loop_2')[0].hhh_seconds; if(t1 && t2){ t1 = $('#hhh_loop_1').css('left').slice(0,-2); t2 = $('#hhh_loop_2').css('left').slice(0,-2); let begin = Math.min(t1,t2); let end = Math.max(t1,t2); $('#hhh_loop_bar').css({display:'block',width:`${end-begin}px`,left:`${begin}px`}); } } //更新位置 function resize_updata(){ let $p1 = $('#hhh_loop_1'); let $p2 = $('#hhh_loop_2'); let $bar = $('#hhh_loop_bar'); if($p1.length !== 1 || $p2.length !== 1 && $bar.length !== 1) return; let t1 = $p1[0].hhh_seconds; let t2 = $p2[0].hhh_seconds; let rect = $('.bilibili-player-video-progress')[0].getBoundingClientRect(); let newleft = t1/h5Player.duration*rect.width; $p1.css('left', newleft); newleft = t2/h5Player.duration*rect.width; $p2.css('left', newleft); //log($p1.css('left'),$p2.css('left')); //log('------'+newleft); t1 = $p1.css('left').slice(0,-2); t2 = $p2.css('left').slice(0,-2); let begin = Math.min(t1,t2); let end = Math.max(t1,t2); $bar.css({left:begin, width:end-begin}); } //css $('#hhh_head_style').remove(); //test if($('#hhh_head_style').length<1){ $('head:first').append(``); } //loop wrap let progheight = $('.bilibili-player-video-progress .bui-track').parent().css('height'); //let progalignitem = $('.bilibili-player-video-progress .bui-track').parent().css('align-items'); let progclass = $('.bilibili-player-video-progress .bui-track').parent().attr('class'); $('.bilibili-player-video-progress .bui-track').wrap(`
`); $('#hhh_loop_wrap')[0].hhh_loop_state_switch = 1; //$('.bilibili-player-video-progress .bui-track').wrap(`
`); let $bar = $('#hhh_loop_wrap').find('.bui-bar-wrap'); let $schedule = $('#hhh_loop_wrap').find('.bui-schedule-wrap'); $bar = $bar.length === 1? $bar: $schedule.length === 1? $schedule: log('not bui-bar-wrap bui-schedule-wrap'); $bar.children('div:first').clone(true,true).appendTo($bar) .css({transform:'scaleX(0.999999)'}) //配合其他transform,否则height不同,scaleX会改变height,bug? .css({background:'rgba(255,165,0,0.5)',display:'none'}) .attr('id','hhh_loop_bar'); //前后箭头node let detail = `
00:01
`; $('.bilibili-player-video-control-top').append(detail.replace(/hhh_id/, 'hhh_loop_1')); $('.bilibili-player-video-control-top').append(detail.replace(/hhh_id/, 'hhh_loop_2')); //设置起点和终点 $('#hhh_loop_wrap')[0].hhh_loop_playback_click = false; $('#hhh_loop_wrap').mousedown(function(e){ if(e.ctrlKey === true){ return false } }).mouseup(function(e){ if(e.ctrlKey === true){ $('.bilibili-player-video-toast-wrp').css('z-index', 0); loop_state_switch(1); var begin_left = $('.bilibili-player-video-progress .bilibili-player-video-progress-detail').css('left'); let $hhh_loop = is_begin? $('#hhh_loop_1'): $('#hhh_loop_2'); is_begin = !is_begin; loop_update($hhh_loop, {left:e.pageX}); $hhh_loop.css({left:`${begin_left}`}).css('display', 'block'); let time = $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-time').text(); $hhh_loop.find('.bilibili-player-video-progress-detail-time').text(time); this.hhh_loop_playback_click = $hhh_loop[0].id; if(first === true){ first = false; //判断当前鼠标点击焦点 $(document).mouseup(function(e){ if(!e.ctrlKey && $('#hhh_loop_wrap')[0].hhh_loop_playback_click) $('#hhh_loop_wrap')[0].hhh_loop_playback_click = false; }); //time now $('.bilibili-player-video-time-now')[0].addEventListener('DOMNodeInserted', function(e) { if($('#hhh_loop_wrap')[0].hhh_loop_state_switch && $('#hhh_loop_wrap')[0].hhh_loop_state_switch !== 0){ let t1 = $('#hhh_loop_1')[0].hhh_seconds; let t2 = $('#hhh_loop_2')[0].hhh_seconds; let begin = Math.min(t1,t2); let end = Math.max(t1,t2); //log(t1+' - '+t2); if(h5Player.currentTime > end){ //log(t1+' - '+t2); h5Player.currentTime = begin; } } }); //拖动确定范围 $('#hhh_loop_1, #hhh_loop_2').mouseenter(function(e){ $(this).css({'cursor': 'w-resize'}); }).mousedown(function(e){ var $this = $(this); var doc = document; if(e.ctrlKey){ loop_state_switch(0); }else{ loop_update($this, {left:e.pageX}); doc.onmousemove = function(e){ loop_update($this, {left:e.pageX}); let time = $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-time').text(); $this.find('.bilibili-player-video-progress-detail-time').text(time); }; doc.onmouseup = function(e){ //清除事件 doc.onmousemove=null; doc.onmouseup=null; //hide_loop_time(); let time = $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-time').text(); $this.find('.bilibili-player-video-progress-detail-time').text(time); //$this.find('.bilibili-player-video-progress-detail-container').show(); $('#hhh_loop_wrap')[0].hhh_loop_playback_click = $this[0].id; return false; } } }); //监听视频窗口大小变化 var ro = new ResizeObserver( entries => { for (let entry of entries) { //更新loop位置 resize_updata(); } }); // Observe one or multiple elements //squirtle-video-time-now 2.X bilibili-player-video-time-now 3.X ro.observe($('.bilibili-player-video-wrap')[0]); } return false; }else{ this.hhh_loop_playback_click = false; } }); //保存sign原color $('.bilibili-player-video-progress-slider')[0].hhh_sign_color = $('.bilibili-player-video-progress-detail-sign-down').css('border-top-color'); //键盘 down $(document).off('keydown.hhh_progress'); $(document).on('keydown.hhh_progress',function(e){ if(e.keyCode === keycode['Ctrl']) { if($('.bilibili-player-video-progress').hasClass('bilibili-player-show') === true){ $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-sign-down').css('border-top-color', '#FFA500'); $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-sign-up').css('border-bottom-color', '#FFA500'); show_loop_time('sign_show'); } } else if(e.keyCode === keycode['left'] || e.keyCode === keycode['right']){ //段落循环 if($('#hhh_loop_wrap')[0].hhh_loop_playback_click !== false && $('#hhh_loop_1').css('display') !== 'none'){ $('.bilibili-player-area').addClass('video-control-show'); let $hhh_loop = $('#'+$('#hhh_loop_wrap')[0].hhh_loop_playback_click); let old_seconds = $hhh_loop[0].hhh_seconds; let time1 = $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-time').text(); let seconds = e.keyCode === keycode['right']? ++$hhh_loop[0].hhh_seconds: --$hhh_loop[0].hhh_seconds; loop_update($hhh_loop, {seconds:seconds}); let time2 = $('.bilibili-player-video-progress .bilibili-player-video-progress-detail-time').text(); if(time1 !== time2) { $hhh_loop.find('.bilibili-player-video-progress-detail-time').text(time2) }else{ $hhh_loop[0].hhh_seconds = old_seconds; } return false; } }else if(e.keyCode === 'L'.charCodeAt()){ if($('#hhh_loop_1')[0].hhh_seconds !== undefined){ $('.bilibili-player-area').addClass('video-control-show'); $('#hhh_loop_wrap')[0].hhh_loop_state_switch = ++$('#hhh_loop_wrap')[0].hhh_loop_state_switch % 3; loop_state_switch($('#hhh_loop_wrap')[0].hhh_loop_state_switch); } } }); //键盘 up $(document).off('keyup.hhh_progress'); $(document).on('keyup.hhh_progress',function(e){ if(e.keyCode === keycode['Ctrl']) { //if($('.bilibili-player-video-progress').hasClass('bilibili-player-show') === true){ $('.bilibili-player-video-progress-detail-sign-down').css('border-top-color', $('.bilibili-player-video-progress-slider')[0].hhh_sign_color); $('.bilibili-player-video-progress-detail-sign-up').css('border-bottom-color', $('.bilibili-player-video-progress-slider')[0].hhh_sign_color); hide_loop_time(); //} } else if(e.keyCode === keycode['left'] || e.keyCode === keycode['right']){ //段落循环 if($('#hhh_loop_wrap')[0].hhh_loop_playback_click !== false){ //hide_loop_time(); return false; } } }); } //增加当前在线视频预览 function run_preview(){ if($('#hhh_online_list_style').length === 1) return; function hide(parent, selector, show_or_hide){ var o = $(); if($.isArray(selector) === true){ $.each(selector, function(i,v){ o = o.add(v); }) }else{ o = $(selector); } //显示及渐隐效果(抄bilibili^^) clearTimeout(parent.showHintTimer), o.stop().show(), parent.showHintTimer = window.setTimeout((function() { o.animate({ opacity: 0 }, 600, (function() { $(this).hide() })) } ), 0) } function show(parent, selector, show_or_hide){ var o = $(); if($.isArray(selector) === true){ $.each(selector, function(i,v){ o = o.add(v); }) }else{ o = $(selector); } //显示及渐隐效果(抄bilibili^^) clearTimeout(parent.showHintTimer), parent.showHintTimer = window.setTimeout((function() { o.stop().show(), o.animate({ opacity: 1 }, 600, (function() { $(this).show() })) } ), 300) } if($('#hhh_online_list_style').length<1){ $('.online-list').append(``); } var bvs = {}, box_width = 0, bg_img_row = 0, bg_y_block_len = 0, bg_img_totle = 0; $('.online-list>.ebox>a>div').mouseenter(function(e){ this.state = 'enter'; let $lazy_img = $(this); let bvid = $lazy_img.parent().attr('href').match(/BV\w+$/); bvid = bvid && bvid[0]; this.bvid = bvid; if(bvs[bvid] === undefined){ bvs[bvid] = $lazy_img.parent().attr('title'); $.getJSON("https://api.bilibili.com/x/player/videoshot", { bvid: bvid, index: "1" }, function(json){ let bg_img = json.data.image[0]; box_width = $lazy_img.width(); bg_img_totle = json.data.index.length > (json.data.img_x_len*json.data.img_x_len)? (json.data.img_x_len*json.data.img_x_len): json.data.index.length; bg_img_row = bg_img_totle < json.data.img_x_len? bg_img_totle: json.data.img_x_len; bg_y_block_len = json.data.img_y_size/json.data.img_x_size*box_width; bvs[bvid] = {box_width:box_width, bg_img_totle:bg_img_totle, bg_img_row:bg_img_row, bg_y_block_len:bg_y_block_len}; //log(bg_img_row+' - '+bg_img_totle+' - '+bg_y_block_len); //log(bvs[bvid]); $lazy_img.css({'overflow':'hidden', 'position':'relative'}); $lazy_img.append(`
`); if($lazy_img[0].state === 'enter') show($lazy_img[0], [$lazy_img.find('.hhh-preview-bg'), $lazy_img.find('.hhh-preview-wrapper')], 'show'); }); }else{ show($lazy_img[0], [$lazy_img.find('.hhh-preview-bg'), $lazy_img.find('.hhh-preview-wrapper')], 'show'); } }).mouseleave(function(){ this.state = 'leave'; hide(this, [$(this).find('.hhh-preview-bg'), $(this).find('.hhh-preview-wrapper')], 'hide'); }).mousemove(function(e){ //log(this.bvid); let obv = bvs[this.bvid]; let amounts = Math.floor(e.offsetX/(obv.box_width/obv.bg_img_totle)); let x = Math.floor(amounts % obv.bg_img_row) * -obv.box_width; x = Math.min(Math.max(x,-obv.box_width*(obv.bg_img_totle-1)),0); let y = Math.floor(amounts/obv.bg_img_row) * -obv.bg_y_block_len; //log('---'+box_width+' - '+bg_img_totle); //log(e.offsetX+' - '+amounts+' - '+x+' - '+y+' - '+bg_y_block_len+' - '+Math.floor(amounts/bg_img_row)); $(this).find('.hhh-preview-bg').css({'background-position':`${x}px ${y}px`}); let w = Math.round(e.offsetX/obv.box_width*100); $(this).find('.hhh-preview-progress-bar').css({'width':`${w}%`}); }) } //动态首页直接显示隐藏content function run_content(){ if($('[hhh_has_content]').length < $('.bili-dyn-content__orig__major').length){ $('.bili-dyn-content__orig__major').each(function(){ let $major = $(this); let $hhh_has_content = $major.find('[hhh_has_content]'); if($hhh_has_content.length >= 1) return true; //$major.attr('hhh_has_content', true); //显示隐藏标题 let $title = $major.find('.bili-dyn-card-video__title'); if($title.length >= 1){ let font_size = $title.css('font-size'); let line_height = +font_size.match(/\d+/)[0] + 5; //估算 let h = $title.removeClass('bili-dyn-card-video__title').css({'font-size':font_size}).height(); //log(line_height+' - '+h) $title.addClass('bili-dyn-card-video__title'); if(h > line_height*2){ $title.attr('title', $title.text()) } } //显示隐藏content let $content = $major.find('.bili-dyn-card-video__desc'); if($content.length >= 1){ //console.log($content.text().slice(0,10)+ ' : ' +$content.height()); let line_height = $content.css('line-height'); //log($content.height()); let font_size = $content.css('font-size'); let h = $content.removeClass('bili-dyn-card-video__desc').css({'line-height':line_height, 'font-size':font_size}).height(); line_height = line_height.match(/\d+/)[0]; //console.log('---line_h:'+line_height+' h: '+h+' title: '+$major.find('.title').text()); $content.addClass('bili-dyn-card-video__desc'); $content.attr('hhh_has_content', true); if(h > line_height*2){ $major.find('.bili-dyn-card-video').height('auto'); $major.find('.bili-dyn-card-video__body').css('display', 'block'); $major.find('.bili-dyn-card-video__header').height(127); //console.log(line_height*2); $content.css({'padding-top':'8px'}); $content.height(line_height); let $expand = $(`
展开
`).insertAfter($content); //let $expand = $(`
展开
`).insertAfter($content); $expand.add($content).click(function(){ if($expand.text() === '展开'){ //console.log('=='+$content.height()+'==='+$content.css('line-height').match(/\d+/)[0]); $content.css({height:'auto', '-webkit-box-orient':'inline-axis'}); $expand.text('收起'); }else{ $content.height(line_height); $content.css({'-webkit-box-orient':'vertical'}); $expand.text('展开'); } return false }); } } }) } } function run_history(){ $.get("https://api.bilibili.com/x/web-goblin/history/search", { pn:"1", keyword: "12", business: "all" }, function(json){ console.log(json) }); } function run_rcmd_box(){ var rcmd_box_data = [$('.rcmd-box').clone(false,false)]; let $cbtn = $('.change-btn'); let h = $cbtn.outerHeight(); let w = $cbtn.outerWidth(); let is_change_break = null; let curr_rcmd_box_num = 0; //list-box left $('#elevator').css({left:`calc(50% + ${w+3+20}px)`}); //calc(50% + 3px); //refresh $cbtn.click(()=>{ $('.rcmd-box-wrap')[0].addEventListener('DOMSubtreeModified', function(e) { let eve_this = this; if(typeof e.target.className === 'string' && e.target.className === 'rcmd-box'){ clearTimeout(is_change_break); is_change_break = setTimeout(function() { //log("推荐页面刷新完毕"); eve_this.removeEventListener('DOMSubtreeModified', arguments.callee); rcmd_box_data.push($('.rcmd-box').clone(false,false)); curr_rcmd_box_num = rcmd_box_data.length - 1; $('#hhh_cbtn_num').text(`${rcmd_box_data.length}/${rcmd_box_data.length}`); if(rcmd_box_data.length >= 10){ $('#hhh_cbtn_num').css({width:'37px', right:'-41px'}) } //log(rcmd_box_data.length) }, 50); } }) }); let $new_cbtn = $cbtn.clone(false, false).empty(); //num $('.rcmd-box-wrap').append($new_cbtn.clone().attr('id','hhh_cbtn_num') .css({height:'21px', 'line-height':'21px', top:`${h+2}px`}) .css({cursor:'default'}) .css({padding:'0px', background:'#e2e2e2'}).append('1/1')); let $cbtn_num = $('#hhh_cbtn_num'); let cbtn_h = $cbtn_num.outerHeight() + 3; //left $('.rcmd-box-wrap').append($new_cbtn.clone().attr('id','hhh_cbtn_zuo').css({height:'auto', top:`${h+1+cbtn_h}px`}) .css({'border-bottom':'0px', 'border-bottom-left-radius':'0px', 'border-bottom-right-radius':'0px'}) .append('')); let $cbtn_zuo = $('#hhh_cbtn_zuo'); $cbtn_zuo.click(function(){ //激活动画 let $i = $(this).find('i'); $i.addClass('active'); setTimeout(function(){ $i.removeClass('active') },500); //恢复前一个list curr_rcmd_box_num = Math.max(curr_rcmd_box_num-1, 0); $('#hhh_cbtn_num').text(`${curr_rcmd_box_num+1}/${rcmd_box_data.length}`); $('.rcmd-box').find('.video-card-reco').each(function(i){ $(this).empty().append($(rcmd_box_data[curr_rcmd_box_num]).find('.video-card-reco:eq('+i+')>div').clone()); }) }) cbtn_h += $cbtn_zuo.outerHeight()-1; //right $('.rcmd-box-wrap').append($new_cbtn.clone().attr('id','hhh_cbtn_you').css({height:'auto', top:`${h+1+cbtn_h}px`, 'border-top':'0px'}) .css({'border-top':'0px', 'border-top-left-radius':'0px', 'border-top-right-radius':'0px'}) .append('')); let $cbtn_you = $('#hhh_cbtn_you'); $cbtn_you.click(function(){ let $i = $(this).find('i'); $i.addClass('active'); setTimeout(function(){ $i.removeClass('active') },500); //恢复后一个list curr_rcmd_box_num = Math.min(curr_rcmd_box_num+1, rcmd_box_data.length-1); $('#hhh_cbtn_num').text(`${curr_rcmd_box_num+1}/${rcmd_box_data.length}`); $('.rcmd-box').find('.video-card-reco').each(function(i){ $(this).empty().append($(rcmd_box_data[curr_rcmd_box_num]).find('.video-card-reco:eq('+i+')>div').clone()); }) }) } //初始化 function init() { console.clear(); let is_card_load = true; let is_content_load = true; let is_homepage_load = true; let is_history_break = null; let is_rcmd_box_break = null; new MutationObserver((mutations, observer) => { mutations.forEach(mutation => { const target = mutation.target; //typeof target.className === 'string' && target.className !== '' && log(target.className); //log(window.location.href); const stage = mutation.previousSibling && target.getAttribute('stage'); if(stage === '1' && $('.bilibili-player-video-wrap').length === 1){ //2.X if($('#app').hasClass('app-v1')){ log("2.X“V3版”加载完毕"); bb_config.set_bb(BILI_2_X_V3); run(); }else{ log("2.X“V2版”加载完毕"); bb_config.set_bb(BILI_2_X_V2); run(); } } else if(typeof target.className === 'string' && target.className === 'squirtle-fullscreen-wrap squirtle-block-wrap' && $('.bpx-player-video-area').length === 1) { //3.X pbp-tip log("3.X加载完毕"); bb_config.set_bb(BILI_3_X); run(); } else if(typeof target.className === 'string' && target.className==='bili-dyn-list__items' && is_content_load){ is_content_load = false; log("2.X动态首页加载完毕"); run_content(); setTimeout(function() { is_content_load = true }, 200); } else if(typeof target.className === 'string' && target.className === 'avatar' && target.baseURI.indexOf('www.bilibili.com/video/online.html') !== -1){ //log($('#hhh_online_list_style').length); log("当前在线加载完毕"); run_preview(); } else if(typeof target.className === 'string' && target.className==='history-list'){ clearTimeout(is_history_break); is_history_break = setTimeout(function() { log("历史记录加载完毕"); run_history()}, 200); } else if(typeof target.className === 'string' && window.location.href.match(/https?:\/\/www.bilibili.com\/?$/) && is_homepage_load){ log("推荐列表加载完毕"); is_homepage_load = false; run_rcmd_box(); //clearTimeout(is_rcmd_box_break); //is_rcmd_box_break = setTimeout(function() { log("推荐列表加载完毕"); run_rcmd_box()}, 50); // } else if(is_card_load === false && typeof target.className === 'string' && target.className === 'card' && $(target).find('.video-container .content').length){ // is_card_load = true; // log("2.X动态首页加载完毕"); // run_card(); //搞笑,刚写完,2.70.7就有了 // removeMostViewedListener(config.getCheckboxSettingStatus('removeMostViewedListener')); } }); }).observe(document.body, { childList: true, subtree: true, }); } init(); } } hhh_lightoff_main.init();