Bilibili Auto Turnoff Barrage

B站视频自动关闭弹幕:双击【t】键开/关切换

Version vom 17.01.2017. Aktuellste Version

// ==UserScript==
// @name       Bilibili Auto Turnoff Barrage
// @namespace  https://greasyfork.org/zh-CN/users/6065-hatn
// @version    0.2.7
// @description  B站视频自动关闭弹幕:双击【t】键开/关切换
// @icon           http://www.gravatar.com/avatar/10670da5cbd7779dcb70c28594abbe56?r=PG&s=92&default=identicon
// @include		*bilibili.com/video/av*
// @include		*bilibili.com/anime/*
// @require		http://cdn.staticfile.org/jquery/2.1.1-rc2/jquery.min.js
// @copyright	2016, hatn
// @author		hatn
// @run-at     	document-end
// @grant0       GM_xmlhttpRequest
// @grant0       GM_getValue
// @grant0       GM_setValue
// @grant0       GM_deleteValue
// ==/UserScript==

/**
*
* 功能:用于哔哩哔哩站(B站) 视频自动关闭弹幕
*
* 使用说明:
* 1、双击【t】: 开/关弹幕
* 2、双击【f】: 全屏切换
* 3、双击【p】: 播放/暂停
* 4、双击【Esc】: 全屏&播放
*
*/

/* #########  参数设置 S ######### */
var config = {
	auto_danmuku: 1, // 自动关闭弹幕 [1]开启(默认) [0]关闭
	auto_fullscreen: 0, // 自动全屏 [1]网页全屏 [0]关闭(默认)
    auto_playvedio: 0, // 自动播放 [1]开启 [0]关闭(默认)
    keyboard_flag: 1, // 监听单/双击键盘事件 [1]单双击(默认) [2]双击 [3]单击 [0]关闭
    css_flag: 1, // 额外的css样式 [1]开启 [0]关闭(默认)
};
/* #########  参数设置 E ######### */

var danmukuObj = {
	/* 参数 */
	cfg: {}, // 参数集
	defaultCfg: {
		auto_danmuku: 1,
        auto_fullscreen: 0,
        auto_playvedio: 0,
        keyboard_flag: 1,
        css_flag: 1,
	},
    /* 按键参数 */
    keyData: {
        timenow: 0, // 上一按键时间
        preKey: '', // 记忆前一按键
        keepTime: 400, // 双击间隔
        keyBtn: { // 双/单击按键对应动作
            '0': {}, // global
            // 双击操作
            '70': {'type': 'fullscreen', 'selector': '.bilibili-player-iconfont-fullscreen.icon-24fullscreen:eq(0)'},
            '80': {
                'type': 'playvedio',
                'selector': 'div.bilibili-player-video-btn-start:eq(0)',
                'player_box': '.player-wrapper',
                'pause_btn': 'div.bilibili-player-video-btn-start.video-state-pause',
                'function': function(keyData, s) {
                    if ($(keyData.pause_btn, s.dom_type).length > 0) return true;
                    $('html, body').animate({scrollTop: $(keyData.player_box).offset().top + 22}, 600);
                }
            },
            '84': {
                'type': 'danmuku',
                'selector': 'div.bilibili-player-video-control div.bilibili-player-video-btn.bilibili-player-video-btn-danmaku',
                'hide_danmu_set': '.bilibili-player-danmaku-setting-lite-panel',
                'flag_off': 'div.bilibili-player-video-control div.bilibili-player-video-btn.bilibili-player-video-btn-danmaku.video-state-danmaku-off',
                'function': function(keyData, s) {
                    $(keyData.hide_danmu_set, s.dom_type).hide(); // 模拟点击 + 隐藏弹幕设置面板
                },
            },
            // 单击操作
            '_27': {
                'type': 'fullandplay',
                'full_status': '#bilibiliPlayer.mode-fullscreen',
                'function': function(keyData, s) {
                    if ($(keyData.full_status, s.dom_type).length > 0) return false;
                    s.keyAction(70);
                    if ($(s.keyData.keyBtn[80].pause_btn, s.dom_type).length > 0) setTimeout(function() {s.keyAction(80);}, 450);
                },
            },
        }
    },
    dom_type: document, // 使用 document/iframe
    iframe_arr: { // body体集合
        bangumi: "iframe.player.bilibiliHtml5Player",
    },
	/* 初始化 */
	init: function(config) {
		var s = this;
		s.setParam(config);
		s.band();
        s.addCss();
        s.autoAction();
		console.log('log: Bilibili Auto Turnoff Barrage, Run...');
	},
	/* 启动器 */
	launcher: function(config) {
		var s = this;
        var times = 100;
        var ii = 0;
		var preTimer = setInterval(function () {
            ++ii;
            var selector = s.keyData.keyBtn['84'].selector; //'div.bilibili-player-video-btn.bilibili-player-video-btn-danmaku';
			if ($(selector).length > 0 || checkIframe(selector, s.iframe_arr)) {
				window.clearInterval(preTimer);
                console.log('log: Try ' + ii + ' times!');
				setTimeout(function() {
                    s.init(config); // 延迟3秒执行
                }, 3000);
				return true;
			}
			if (--times < 0) {
                window.clearInterval(preTimer) + console.log('err: time out!');
			}
		}, 600);
        /* 检查各项iframe */
        function checkIframe(selector, iframe_arr) {
            var $type;
            for (var i in iframe_arr) {
                $type = $(iframe_arr[i]);
                if ($type.length > 0 && $(selector, $type.contents()).length > 0) {
                    s.dom_type = $type.contents();
                    return true;
                }
            }
            return false;
        }
	},
	/* 参数读取 */
	setParam: function(config) {
		var s = this;
		config = typeof config == 'object' ? config : {};
        $.extend(s.cfg, s.defaultCfg, config);
		//s.dataMgr('get');
		//s.cfg = {};
		//s.dataMgr('set');
	},
    /* 全局css */
    addCss: function() {
        var s = this;
        if (s.cfg.css_flag == 0) return false;
        var insertStr = '<style id="other-style">#bilibiliPlayer.mode-fullscreen .bilibili-player-video-sendbar[style="opacity: 1;"]{opacity:0.6 !important; bottom: 60px !important;}#bilibiliPlayer.mode-fullscreen .bilibili-player-video-control[style="opacity: 1;"]{opacity:0.6 !important;-moz-transform:scale(1,2);-webkit-transform:scale(1,2);bottom: 16px !important;}</style>';
		$(insertStr).appendTo($('body'));
        if (s.dom_type != document) $(insertStr).appendTo($('body', s.dom_type));
    },
	/* 事件绑定 */
	band: function() {
		var s = this;
		s.cfg.keyboard_flag > 0 && $(window).on('keyup', function(event) {
            var $focus = $(":focus");
            if ($focus.length > 0 && $.inArray($focus[0].nodeName, ['INPUT', 'TEXTAREA']) != -1) return false;
			var keyCode = event.keyCode;
            var double = doubleClick(keyCode);
            var one_click = $.inArray(s.cfg.keyboard_flag, [1, 3]) != -1 ? true: false;
            var double_click = $.inArray(s.cfg.keyboard_flag, [1, 2]) != -1 ? true: false;
            if (double == false && one_click == true) { // 非双击
                keyCode = '_' + keyCode;
                if (typeof s.keyData.keyBtn[keyCode] == 'undefined') return false;
                s.keyAction(keyCode);
            } else if (double == true && typeof s.keyData.keyBtn[keyCode] != 'undefined' && double_click == true) {
                s.keyAction(keyCode);
            }
		});

        /* 双击判定 */
        function doubleClick(keyCode) {
            var timenow = (new Date()).getTime();
            if (s.keyData.timenow == 0) {
                s.keyData.timenow = timenow;
                s.keyData.preKey = keyCode;
                return false;
            } else {
                var intval = timenow - s.keyData.timenow;
                if (intval < s.keyData.keepTime && s.keyData.preKey == keyCode) {
                    s.keyData.timenow = 0;
                    return true;
                }
                s.keyData.preKey = keyCode;
                s.keyData.timenow = timenow;
            }
            return false;
        }
	},
    /* 开关切换 */
    autoAction: function() {
        var s = this;
        if (s.cfg.auto_danmuku == 1) s.keyAction(84);
        if (s.cfg.auto_playvedio == 1) s.keyAction(80);
        if (s.cfg.auto_fullscreen >= 1) s.keyAction(70);
        return true;
    },
    /* 按键操作 */
    keyAction: function(_keyCode) {
        var s = this;
        var keyCode = _keyCode || false;
        if (keyCode == false || typeof s.keyData.keyBtn[keyCode] == 'undefined') return false;
        var keyData = s.keyData.keyBtn[keyCode];
        var selector = keyData.selector || false;
        var subsidiary_func = keyData.function || false;
        if (selector != false) $(selector, s.dom_type).click(); // 点击操作
        if (subsidiary_func != false) subsidiary_func(keyData, s); // 附属操作
        console.log('log: ' + s.keyData.keyBtn[keyCode].type + ' Action.');
    },
	/* 数据操作 */
	dataMgr: function(act) {
		var s = this;
		var action = act == 'set' ? 'set' : 'get';
		if (action == 'get') {
			var cfgStr = GM_getValue('config');
			if (typeof cfgStr == 'undefined' || cfgStr == '') {
				s.cfg = s.defaultCfg;
				return false;
			}
            var cfg_obj = JSON.parse(cfgStr);
			$.extend(s.cfg, s.defaultCfg, cfg_obj); // 合并
		} else {
			var cfgStr = JSON.stringify(s.cfg);
			GM_setValue('config', cfgStr);
		}
	}
};

danmukuObj.launcher(config);