Greasy Fork 还支持 简体中文。

斗鱼(douyu)快捷操作

滚轮音量调节;鼠标功能键全屏;快捷键:开关弹幕D、网页全屏W、隐藏有边框Q、↑↓键音量调节等

目前為 2023-06-27 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         斗鱼(douyu)快捷操作
// @namespace    hhh2000
// @version      0.4.1
// @description  滚轮音量调节;鼠标功能键全屏;快捷键:开关弹幕D、网页全屏W、隐藏有边框Q、↑↓键音量调节等
// @author       hhh2000
// @match        http*://www.douyu.com/*
// @require      https://cdn.staticfile.org/jquery/1.12.4/jquery.min.js
// @run-at       document-end
// @grant        none
// @compatible   chrome
/* globals jQuery, $, waitForkeyElements */
/* eslint-disable no-multi-spaces, dot-notation */
/* eslint no-eval:0 */
// ==/UserScript==

'use strict';
(function() {

    function getkeyCode(k) {
        var keyCodes = {
            300: '滚↑轮',
            301: '滚↓轮',
            302: '鼠标左键',
            303: '鼠标右键',
            304: '鼠标中键',
            305: '鼠标左前侧键',
            306: '鼠标左后侧键',
            307: '鼠标右前侧键',
            308: '鼠标右后侧键',
            309: '鼠标中前侧键',
            310: '鼠标中后侧键',

            0: "",
            3: "break",
            8: "Backspace",
            9: "Tab",
            12: "Clear",
            13: "Enter",
            16: "Shift",
            17: "Ctrl",
            18: "Alt",
            19: "PauseBreak",
            20: "CapsLock",
            27: "Escape",
            32: "Space",
            33: "PageUp",
            34: "PageDown",
            35: "End",
            36: "Home",
            37: "←",   //LeftArrow ↑ ↓ ← →
            38: "↑",   //UpArrow
            39: "→",   //RightArrow
            40: "↓",   //DownArrow
            45: "Insert",
            46: "Delete",
            48: "0",
            49: "1",
            50: "2",
            51: "3",
            52: "4",
            53: "5",
            54: "6",
            55: "7",
            56: "8",
            57: "9",
            65: "A",
            66: "B",
            67: "C",
            68: "D",
            69: "E",
            70: "F",
            71: "G",
            72: "H",
            73: "I",
            74: "J",
            75: "K",
            76: "L",
            77: "M",
            78: "N",
            79: "O",
            80: "P",
            81: "Q",
            82: "R",
            83: "S",
            84: "T",
            85: "U",
            86: "V",
            87: "W",
            88: "X",
            89: "Y",
            90: "Z",
            93: "ContextMenu",
            96: "NumPad0",
            97: "NumPad1",
            98: "NumPad2",
            99: "NumPad3",
            100: "NumPad4",
            101: "NumPad5",
            102: "NumPad6",
            103: "NumPad7",
            104: "NumPad8",
            105: "NumPad9",
            106: "NumPad_Multiply",
            107: "NumPad_Add",
            108: "NumPad_Separator",
            109: "NumPad_Subtract",
            110: "NumPad_Decimal",
            111: "NumPad_Divide",
            112: "F1",
            113: "F2",
            114: "F3",
            115: "F4",
            116: "F5",
            117: "F6",
            118: "F7",
            119: "F8",
            120: "F9",
            121: "F10",
            122: "F11",
            123: "F12",
            124: "F13",
            125: "F14",
            126: "F15",
            127: "F16",
            128: "F17",
            129: "F18",
            130: "F19",
            144: "NumLock",
            145: "ScrollLock",
            166: "BrowserBack",
            167: "BrowserForward",
            170: "BrowserSearch",
            172: "BrowserHome",
            173: "AudioVolumeMute",
            174: "AudioVolumeDown",
            175: "AudioVolumeUp",
            176: "MediaTrackNext",
            177: "MediaTrackPrevious",
            178: "MediaStop",
            179: "MediaPlayPause",
            180: "LaunchMail",
            181: "LaunchMediaPlayer",
            183: "LaunchApp2",
            186: ";",
            187: "=",
            188: ",",
            189: "-",
            190: ".",
            191: "/",
            192: "`",
            193: "ABNT_C1",
            194: "ABNT_C2",
            219: "[",
            220: "\\",
            221: "]",
            222: "'",
            223: "OEM_8",
            226: "OEM_102",
            229: "KeyInComposition",
        };
        return keyCodes[k];
    }
    let keycode = {
        'Enter': 13,
        'Ctrl': 17,
        'Esc': 27,
        'left': 37,
        'right': 39,
        'up': 38,
        'down': 40,
        'space': 32,
        'NumPad0': 96,
        'NumPad_Decimal': 110,
    }

    function set_progress(selector, curr_percent, inc_percent, limit_begin, limit_end){

        function calc_bar_offset(percent, bar_length, limit_begin, limit_end){
            let p = Math.max(Math.min(+percent, limit_end), limit_begin);
            let limit = limit_end - limit_begin;
            let bar_offset = (p-limit_begin) * bar_length / limit;
            //log(p, limit, bar_length, 128/100*p, bar_offset)
            return bar_offset;  //百分比对应进度条位置
        }

       // $('.controlbar-f41e38').removeClass('hide-6cf943')

        let e1 = new MouseEvent('mousedown'), e2 = new MouseEvent('mouseup')
        let rect = selector.getBoundingClientRect()

        let padding_top = +$(selector).css('padding-top').match(/\d+/)?.[0]
        let padding_bottom = +$(selector).css('padding-bottom').match(/\d+/)?.[0]
        let bar_offset = calc_bar_offset(curr_percent-inc_percent, (rect.height-padding_top-padding_bottom), limit_begin, limit_end)
        let clientY = rect.bottom - padding_bottom - bar_offset + 1

        let o1 = calc_bar_offset(curr_percent, (rect.height-padding_top-padding_bottom), limit_begin, limit_end)
        let o2 = calc_bar_offset(curr_percent+inc_percent, (rect.height-padding_top-padding_bottom), limit_begin, limit_end)
        let o3 = calc_bar_offset(curr_percent-inc_percent, (rect.height-padding_top-padding_bottom), limit_begin, limit_end)
        // log(`当前音量:${curr_percent}   加音量${curr_percent+inc_percent}   减音量${curr_percent-inc_percent}`)
        // log(`当前距离:${o1}   加距离${o2}   减距离${o3}`)

        let percent = Math.max(Math.min(curr_percent - inc_percent, limit_end), limit_begin)
        let step = (rect.height-padding_top-padding_bottom)/(limit_end - limit_begin)/2
        // 动态调整
        for(let i=0; i<Math.abs(inc_percent*10); ++i){
            //log(`原音量:${curr_percent}/${parseInt($('.tips-3df825').text().match(/\d+/))}`)
            e1.initMouseEvent('mousedown',1,1,window,1,0,0,0,clientY,0,0,0,0,0,null);
            e2.initMouseEvent('mouseup'  ,1,1,window,1,0,0,0,clientY,0,0,0,0,0,null);
            selector.dispatchEvent(e1); selector.dispatchEvent(e2);

            let next_percent = parseInt($('.tips-3df825').text().match(/\d+/))
            //log(`新音量:${percent}/${next_percent}/${$('.tips-3df825').text().match(/\d+/)}`)


            if(percent < next_percent) clientY += step
            else if(percent > next_percent) clientY -= step
            else break

        }
    }

    function adjust_progress(selector, inc_percent, range_bengin, range_end){
        let e1 = new MouseEvent('mouseover'), e2 = new MouseEvent('mouseout')
        e1.initMouseEvent('mouseover',1,1,window,1,0,0,0,0,0,0,0,0,0,null)
        $('.volume-8e2726')?.[0]?.dispatchEvent(e1)
        $('.volume-silent-3eb726')?.[0]?.dispatchEvent(e1)
        //$('.VolumeBar-9010af').css('visibility', 'hidden')

        selector = $('.volume-bar-06542d')[0]
        const curr_percent = parseInt($('.tips-3df825').text().match(/\d+/))
        set_progress(selector, curr_percent, parseInt(inc_percent), 0, 100)

        // $('.VolumeBar-9010af').css('visibility', 'visible')
        let t = $('.volume-bar-06542d').data('hhh_timeout')
        clearTimeout(t)
        t = setTimeout(()=>{
            e2.initMouseEvent('mouseout',1,1,window,1,0,0,0,0,0,0,0,0,0,null)
            $('.volume-8e2726')?.[0]?.dispatchEvent(e2)
            $('.volume-silent-3eb726')?.[0]?.dispatchEvent(e2)
        }, 1000)
        $('.volume-bar-06542d').data('hhh_timeout', t)
    }

    //显示hint XXX
    function cut_InfoDisappear(){
        if($('.kui-message-information-item').css('animation-name') === 'InfoDisappear'){
            $('.kui-message-information-item').css('animation-name', 'InfoDisappear1')
        }else{
            $('.kui-message-information-item').css('animation-name', 'InfoDisappear')
        }
    }


    let log = console.log
    function dir(e) {console.dir(e)}
    function err(e) {console.error(e)}
    function waitForTrue(ifTrue, callback, time=100) {
        if(--time < 0) {err('waitForTrue 超时 '+ifTrue); return false;}
        const fn = waitForTrue;
        //let fn = arguments.callee;
        if (ifTrue()) {
            callback(); return true;
        } else {
            setTimeout(function() { fn(ifTrue, callback, time); }, 50);
        }
    }

    //滚轮音量调节;鼠标功能键全屏;快捷键:开关弹幕D、网页全屏W、隐藏有边框Q、↑↓键音量调节
    function run(){
        log('douyu快捷操作加载完毕')

        $('.ActBase').hide()

        //非全屏滚轮音量调节
        $('#__h5player').off('mousewheel.hhh_douyu').on('mousewheel.hhh_douyu',function(e){
            let delta = e.originalEvent.wheelDelta
            if(delta >= 120){  //up
                adjust_progress($('.volume-bar-06542d')[0], -1, 0, 100)  //volume-bar-06542d
            }else{
                adjust_progress($('.volume-bar-06542d')[0],  1, 0, 100)
            }
            return false
        })

        //功能键全屏
        $('#__h5player').off('mousedown.hhh_douyu').on('mousedown.hhh_douyu',function(e){
            if(e.buttons > 2){
                $('.wfs-2a8e83, .wfs-exit-180268').not('.removed-9d4c42').click()
                return false
            }
        })

        //快捷键
        $('body').off('keydown.hhh_douyu').on('keydown.hhh_douyu',function(e){
            if(e.keyCode === keycode['up'] || e.keyCode === keycode['down']){  //↑↓音量
                if(e.keyCode === keycode['up']){
                    adjust_progress($('.volume-bar-06542d')[0], -5, 0, 100)
                }else{
                    adjust_progress($('.volume-bar-06542d')[0],  5, 0, 100)
                }
                //$('.kui-message-information-text font').text($('#volume-tip').text())  //set hint text
                //cut_InfoDisappear()
                return false
            }else if(e.keyCode === keycode['NumPad_Decimal'] || e.keyCode === keycode['NumPad0']){  //NumPad_Decimal numpad1音量
                //log($(e.originalEvent.path[0]).attr('type'))
                //log(e.originalEvent.path[0].nodeName)
                let nodenames = ['INPUT', 'TEXTAREA']
                let nodetypes = ['text']
                let path0_nodename = e.originalEvent.path[0].nodeName
                let path0_type = $(e.originalEvent.path[0]).attr('type')
                if(nodenames.includes(path0_nodename) === false || (path0_nodename === 'INPUT' && nodetypes.includes(path0_type) === false)){  //排除发送弹幕等情况
                    if(e.keyCode === keycode['NumPad_Decimal']){
                        adjust_progress($('.volume-bar-06542d')[0], -1, 0, 100)
                    }else{
                        adjust_progress($('.volume-bar-06542d')[0],  1, 0, 100)
                    }
                    return false
                }
            }else if(e.keyCode === 'W'.charCodeAt()){  //W 网页全屏
                $('.wfs-2a8e83, .wfs-exit-180268').not('.removed-9d4c42').click()
            }else if(e.keyCode === 'F'.charCodeAt()){  //W 全屏
                $('.fs-781153, .fs-exit-b6e6a7').not('.removed-9d4c42').click()
            }else if(e.keyCode === 'Q'.charCodeAt()){  //W 隐藏右边框
                $('.layout-Player-asidetoggleButton').click()
            }else if(e.keyCode === 'D'.charCodeAt()){  //D 开关弹幕
                $('.showdanmu-42b0ac, .hidedanmu-5d54e2').not('.removed-9d4c42').click()
            }
        })
    }

    waitForTrue(()=>$('#player-control-video').length>0, ()=>{
        run()
    })

})();