播放器快捷键扩展

腾讯视频、优酷、爱奇艺播放器添加快捷键支持,F=全屏, D=弹幕开关

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         播放器快捷键扩展
// @namespace    https://greasyfork.org/users/726822
// @version      1.0.1
// @description  腾讯视频、优酷、爱奇艺播放器添加快捷键支持,F=全屏, D=弹幕开关
// @author       nosora
// @match        *://*.qq.com/*
// @match        *://*.youku.com/*
// @match        *://*.iqiyi.com/*
// @license      MIT
// @run-at       document-idle
// ==/UserScript==

(function() {
    'use strict';

    // 点击选择器列表中的任意一个按钮
    function clickButton(selectors) {
        for (const sel of selectors) {
            const btn = document.querySelector(sel);
            if (btn) {
                btn.click();
                return btn;
            }
        }
        return null;
    }

    // 提示缓存(腾讯/优酷使用)
    const tipCache = { '开启': null, '关闭': null };

    // 显示提示文字
    function showTip(container, text) {
        if (!container) return;

        if (text.includes('开启') && tipCache['关闭']) {
            tipCache['关闭'].remove();
            tipCache['关闭'] = null;
        }
        if (text.includes('关闭') && tipCache['开启']) {
            tipCache['开启'].remove();
            tipCache['开启'] = null;
        }

        const tip = document.createElement('div');
        tip.textContent = text;
        tip.style.position = 'absolute';
        tip.style.background = 'rgba(0,0,0,0.5)';
        tip.style.color = '#fff';
        tip.style.padding = '6px 12px';
        tip.style.borderRadius = '4px';
        tip.style.fontSize = '14px';
        tip.style.zIndex = '9999';
        tip.style.pointerEvents = 'none';
        tip.style.opacity = '0';
        tip.style.transition = 'opacity 0.2s';
        tip.style.left = '50%';
        tip.style.top = '50%';
        tip.style.transform = 'translate(-50%, -50%)';

        const style = getComputedStyle(container);
        if (style.position === 'static') container.style.position = 'relative';

        container.appendChild(tip);

        if (text.includes('开启')) tipCache['开启'] = tip;
        if (text.includes('关闭')) tipCache['关闭'] = tip;

        requestAnimationFrame(() => { tip.style.opacity = '1'; });
        setTimeout(() => {
            tip.style.opacity = '0';
            tip.addEventListener('transitionend', () => {
                tip.remove();
                if (text.includes('开启')) tipCache['开启'] = null;
                if (text.includes('关闭')) tipCache['关闭'] = null;
            });
        }, 1000);
    }

    // 快捷键监听
    document.addEventListener('keydown', function(e) {
        const tag = document.activeElement.tagName.toLowerCase();
        if (tag === 'input' || tag === 'textarea') return;

        switch (e.key) {
            // 全屏(腾讯/优酷)
            case 'f':
            case 'F': {
                clickButton([
                    '.txp_fullscreen',
                    '.txp_btn_fullscreen',
                    '.player_fullscreen_btn',
                    '#fullscreen-icon'
                ]);
                break;
            }

            // 弹幕开关
            case 'd':
            case 'D': {
                // 腾讯弹幕
                {
                    const tencentBtn = clickButton(['.barrage-switch']);
                    if (tencentBtn) {
                        const title = tencentBtn.getAttribute('title');
                        let status = '';
                        if (title === '开启弹幕') status = '弹幕已开启';
                        else if (title === '关闭弹幕') status = '弹幕已关闭';
                        else return;

                        const iframe = document.querySelector('#magicdanmaku-iframe-wrapper');
                        const container = iframe ? iframe.parentElement : document.body;
                        showTip(container, status);
                        break;
                    }
                }

                // 优酷弹幕
                {
                    const youkuBtn = document.querySelector('#barrage-switch');
                    if (youkuBtn) {
                        const isOpen = youkuBtn.classList.contains('turn-on_3h6RT');
                        youkuBtn.click();
                        const player = document.querySelector('.player-container') || document.body;
                        showTip(player, isOpen ? '弹幕已关闭' : '弹幕已开启');
                        break;
                    }
                }

                // 爱奇艺弹幕(无需额外提示)
                {
                    const iqiyiBtn = document.querySelector(
                        '.player-buttons_danmu_on__MoE7i, .player-buttons_danmu_off__qpF6V, .player-buttons_danmu_simple__aS7of'
                    );
                    if (iqiyiBtn) {
                        iqiyiBtn.click();
                    }
                }

                break;
            }
        }
    });

})();