自动全屏,但是目前因为浏览器安全限制(只能手动。。。)

给家里人用的自动全屏,但是浏览器安全策略无法在油猴脚本自动全屏,只能手动键入F全屏

目前為 2025-01-27 提交的版本,檢視 最新版本

// ==UserScript==
// @name         自动全屏,但是目前因为浏览器安全限制(只能手动。。。)
// @namespace    http://tampermonkey.net/
// @version      0.142
// @description  给家里人用的自动全屏,但是浏览器安全策略无法在油猴脚本自动全屏,只能手动键入F全屏
// @author       zsanjin
// @match        https://xiaoxintv.cc/index.php/vod/play/id/*
// @license      BSD-2-Clause
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    function createEnhancedButton() {
        const button = document.createElement('button');
        button.id = 'easy-fullscreen-button';
        button.innerHTML = '📺 点击这里/或按F全屏播放,退出按Esc';
        button.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            z-index: 999999;
            padding: 15px 25px;
            background: #4CAF50;
            color: white;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            font-size: 18px;
            font-weight: bold;
            box-shadow: 0 4px 8px rgba(0,0,0,0.2);
            transition: all 0.3s ease;
        `;

        // 按钮悬停效果
        button.onmouseover = () => {
            button.style.background = '#45a049';
            button.style.transform = 'scale(1.05)';
        };
        button.onmouseout = () => {
            button.style.background = '#4CAF50';
            button.style.transform = 'scale(1)';
        };

        // 按钮点击效果
        button.onmousedown = () => button.style.transform = 'scale(0.95)';
        button.onmouseup = () => button.style.transform = 'scale(1)';

        // 按钮点击处理
        button.onclick = async () => {
            try {
                console.log('按钮点击事件已触发');
                button.innerHTML = '⌛ 正在设置全屏...';
                
                // 先模拟F键
                simulateFKeyPress();
                
                // 等待一小段时间确保按键事件已处理
                await new Promise(resolve => setTimeout(resolve, 500));
                
                // 发送请求到Flask服务器
                const result = await sendFKeySignal();
                console.log('服务器响应:', result);
                
                if (result.status === 'success') {
                    button.innerHTML = '✅ 全屏设置成功';
                    setTimeout(() => {
                        button.style.opacity = '0';
                        setTimeout(() => button.style.display = 'none', 1000);
                    }, 2000);
                } else {
                    throw new Error('服务器返回错误');
                }
            } catch (error) {
                console.error('操作失败:', error);
                button.innerHTML = '❌ 操作失败,请重试';
                setTimeout(() => {
                    button.innerHTML = '📺 点击这里/或按F全屏播放,退出按Esc';
                }, 3000);
            }
        };

        document.body.appendChild(button);
    }

    // 模拟F键按下
    function simulateFKeyPress() {
        console.log('模拟按下 F 键');
        const event = new KeyboardEvent('keydown', {
            key: 'f',
            keyCode: 70,
            code: 'KeyF',
            which: 70,
            bubbles: true,
        });
        document.dispatchEvent(event);
    }

    // 使用GM_xmlhttpRequest发送请求
    function sendFKeySignal() {
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: 'POST',
                url: 'http://localhost:3000/trigger-f',
                headers: {
                    'Content-Type': 'application/json',
                },
                data: JSON.stringify({
                    action: 'press_f'
                }),
                onload: function(response) {
                    try {
                        const result = JSON.parse(response.responseText);
                        resolve(result);
                    } catch (error) {
                        reject(new Error('解析响应失败'));
                    }
                },
                onerror: function(error) {
                    reject(new Error('请求失败'));
                }
            });
        });
    }

    async function tryFullscreen() {
        const iframes = Array.from(document.querySelectorAll('iframe'))
            .filter(iframe => iframe.src.includes('player'));

        for (const iframe of iframes) {
            try {
                const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
                const videoElement = iframeDoc.querySelector('.yzmplayer-video');
                const fullscreenButton = iframeDoc.querySelector('.yzmplayer-full-icon');

                if (videoElement && fullscreenButton) {
                    fullscreenButton.click();
                    await new Promise(resolve => setTimeout(resolve, 1000));
                    
                    try {
                        await videoElement.requestFullscreen();
                    } catch (e) {
                        console.log('尝试其他全屏方法');
                        const methods = [
                            'webkitRequestFullscreen',
                            'mozRequestFullScreen',
                            'msRequestFullscreen'
                        ];
                        
                        for (const method of methods) {
                            if (videoElement[method]) {
                                await videoElement[method]();
                                break;
                            }
                        }
                    }
                    return true;
                }
            } catch (e) {
                console.log('在iframe中请求全屏失败:', e);
            }
        }
        return false;
    }

    function init() {
        createEnhancedButton();
        
        // 监听F键
        document.addEventListener('keydown', (e) => {
            if (e.key.toLowerCase() === 'f') {
                tryFullscreen();
            }
        });
    }

    // 在页面加载完成后初始化
    if (document.readyState === 'complete') {
        init();
    } else {
        window.addEventListener('load', init);
    }
})();