Greasy Fork

Greasy Fork is available in English.

新盟网页助手

新盟网页助手 - 视频播放速度控制、视频下载、解除复制限制等功能

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         新盟网页助手
// @name:en      XinMeng Web Assistant
// @namespace    http://tampermonkey.net/
// @version      1.3.0
// @description  新盟网页助手 - 视频播放速度控制、视频下载、解除复制限制等功能
// @description:en  XinMeng Web Assistant - Video speed control, video download, and copy restriction removal
// @author       fengliunian
// @license      MIT
// @match        *://*/*
// @grant        GM_xmlhttpRequest
// @grant        GM_notification
// @grant        GM_download
// @connect      *
// @homepage     https://github.com/fengliunian/xinmeng-Web-Assistant
// @supportURL   https://github.com/fengliunian/xinmeng-Web-Assistant/issues
// ==/UserScript==

(function() {
    'use strict';

    // 定义默认快捷键
    const DEFAULT_HOTKEYS = {
        inputText: { key: 'm', ctrl: true, shift: false, alt: true },
    };

    // 清除之前的设置并使用新的默认值
    localStorage.removeItem('videoSpeedHotkeys');
    let hotkeys = DEFAULT_HOTKEYS;

    // 创建一个全局变量来存储按钮引用
    let inputTextButton = null;

    // 添加全局快捷键监听
    document.addEventListener('keydown', function(e) {
        // 如果焦点在设置窗口的输入框,不触发快捷键
        if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;

        const currentHotkey = hotkeys.inputText;
        if (e.ctrlKey === currentHotkey.ctrl &&
            e.shiftKey === currentHotkey.shift &&
            e.altKey === currentHotkey.alt &&
            e.key.toLowerCase() === currentHotkey.key) {
            e.preventDefault();
            // 使用全局变量引用按钮
            if (inputTextButton) {
                inputTextButton.click();
                console.log('Triggered input text button');
            } else {
                console.log('Button not found');
            }
        }
    });

    // 在创建输入文字按钮的地修改代码
    const disablePasteButton = document.createElement('button');
    disablePasteButton.id = 'input-text-button';
    disablePasteButton.textContent = '输入文字';
    disablePasteButton.style.cssText = `
        flex: 1;
        padding: 6px;
        border: none;
        border-radius: 4px;
        background: #9C27B0;
        color: white;
        cursor: pointer;
        font-size: 14px;
        transition: background 0.3s;
    `;

    // 保存按钮引用到全局变量
    inputTextButton = disablePasteButton;

    // 创建速度显示器
    const speedDisplay = document.createElement('div');
    speedDisplay.style.cssText = `
        position: fixed;
        top: 20px;
        right: 20px;
        background: rgba(0, 0, 0, 0.7);
        color: white;
        padding: 10px;
        border-radius: 5px;
        z-index: 9999;
        display: none;
        font-family: Arial, sans-serif;
    `;
    document.body.appendChild(speedDisplay);

    // 显示速度的函数
    function showSpeed(speed) {
        speedDisplay.textContent = `速度: ${speed.toFixed(2)}x`;
        speedDisplay.style.display = 'block';
        setTimeout(() => {
            speedDisplay.style.display = 'none';
        }, 1000);
    }

    // 更改视频速度的函数
    function changeVideoSpeed(delta) {
        const videos = document.getElementsByTagName('video');
        for (const video of videos) {
            let newSpeed = video.playbackRate + delta;
            // 限制速度范围在0.1到16之间
            newSpeed = Math.max(0.1, Math.min(16, newSpeed));
            video.playbackRate = newSpeed;
            showSpeed(newSpeed);
        }
    }

    // 监听键盘事
    document.addEventListener('keydown', function(e) {
        if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;

        switch (e.key) {
            case '[': // 减速
                changeVideoSpeed(-0.25);
                break;
            case ']': // 加速
                changeVideoSpeed(0.25);
                break;
            case '\\': // 重置速度
                const videos = document.getElementsByTagName('video');
                for (const video of videos) {
                    video.playbackRate = 1.0;
                    showSpeed(1.0);
                }
                break;
        }
    });

    // 监听新加载的视频
    const observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            mutation.addedNodes.forEach(function(node) {
                if (node.nodeName === 'VIDEO') {
                    // 新视频添加速度控制功能
                    node.addEventListener('ratechange', function() {
                        showSpeed(this.playbackRate);
                    });
                }
            });
        });
    });

    // 启动观察器
    observer.observe(document.body, {
        childList: true,
        subtree: true
    });

    // 修改面板创建和检查的逻辑
    const PANEL_ID = 'video-speed-controller-panel';

    // 将面板创建逻辑包装在一个函数中
    function createControlPanel() {
        // 移除所有已存在的控制面板(确保只有一个)
        function removeExistingPanels() {
            const existingPanels = document.querySelectorAll(`#${PANEL_ID}`);
            existingPanels.forEach(panel => panel.remove());
        }

        // 在创建新面板前先移除已存在的面板
        removeExistingPanels();

        // 修改控制面板的初始状态和样式
        const controlPanel = document.createElement('div');
        controlPanel.id = PANEL_ID;
        controlPanel.style.cssText = `
            position: fixed;
            top: 50%;
            right: 20px;
            background: rgba(0, 0, 0, 0.9);
            color: white;
            padding: 10px;
            border-radius: 8px;
            z-index: 2147483647;
            font-family: Arial, sans-serif;
            display: flex;
            flex-direction: column;
            gap: 6px;
            transform: translateY(-50%);
            box-shadow: 0 2px 10px rgba(0,0,0,0.3);
            min-width: 120px;
            user-select: none;
            -webkit-user-select: none;
            transition: all 0.3s ease;
        `;

        // 创建一个迷你版的控制按钮
        const miniButton = document.createElement('button');
        miniButton.textContent = '⚙️';
        miniButton.style.cssText = `
            position: fixed;
            top: 50%;
            right: 20px;
            width: 40px;
            height: 40px;
            background: rgba(0, 0, 0, 0.8);
            color: white;
            border: none;
            border-radius: 50%;
            cursor: pointer;
            z-index: 2147483647;
            transform: translateY(-50%);
            font-size: 20px;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.3s ease;
            box-shadow: 0 2px 8px rgba(0,0,0,0.2);
        `;

        // 默认隐藏控制面板,显示迷你按钮
        controlPanel.style.display = 'none';
        document.body.appendChild(miniButton);

        // 添加迷你按钮的悬停效果
        miniButton.addEventListener('mouseover', () => {
            miniButton.style.background = 'rgba(0, 0, 0, 0.9)';
            miniButton.style.transform = 'translateY(-50%) scale(1.1)';
        });

        miniButton.addEventListener('mouseout', () => {
            miniButton.style.background = 'rgba(0, 0, 0, 0.8)';
            miniButton.style.transform = 'translateY(-50%) scale(1)';
        });

        // 点击迷你按钮显示/隐藏控制面板
        let isPanelVisible = false;
        miniButton.addEventListener('click', () => {
            isPanelVisible = !isPanelVisible;
            controlPanel.style.display = isPanelVisible ? 'flex' : 'none';
            miniButton.style.display = isPanelVisible ? 'none' : 'flex';
        });

        // 修改按钮样式,使其更紧凑
        const buttonStyle = `
            padding: 4px 8px;
            font-size: 12px;
        `;

        // 修改所有按钮的尺寸
        controlPanel.querySelectorAll('button').forEach(button => {
            button.style.cssText += buttonStyle;
        });

        // 添加关闭按钮
        const closeButton = document.createElement('button');
        closeButton.innerHTML = '✕';
        closeButton.style.cssText = `
            position: absolute;
            top: 5px;
            right: 5px;
            background: transparent;
            border: none;
            color: rgba(255,255,255,0.6);
            cursor: pointer;
            font-size: 14px;
            padding: 2px 6px;
            border-radius: 4px;
        `;

        closeButton.addEventListener('click', () => {
            controlPanel.style.display = 'none';
            miniButton.style.display = 'flex';
            isPanelVisible = false;
        });

        controlPanel.appendChild(closeButton);

        // 将面板添加到页面
        document.body.appendChild(controlPanel);

        // 创建速度控制组件
        const speedControl = document.createElement('div');
        speedControl.style.cssText = `
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 8px;
        `;

        // 减速按钮
        const decreaseButton = document.createElement('button');
        decreaseButton.textContent = '-';
        decreaseButton.style.cssText = `
            width: 30px;
            height: 30px;
            border: none;
            border-radius: 4px;
            background: #4CAF50;
            color: white;
            cursor: pointer;
            font-size: 16px;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: background 0.3s;
        `;

        // 速度显示
        const speedDisplay = document.createElement('div');
        speedDisplay.style.cssText = `
            font-size: 16px;
            font-weight: bold;
            min-width: 60px;
            text-align: center;
        `;
        speedDisplay.textContent = '1.0x';

        // 加速按钮
        const increaseButton = document.createElement('button');
        increaseButton.textContent = '+';
        increaseButton.style.cssText = decreaseButton.style.cssText;

        // 添加事件监听
        let currentSpeed = 1.0;
        const speedStep = 0.25;
        const minSpeed = 0.25;
        const maxSpeed = 16;

        decreaseButton.addEventListener('click', () => {
            currentSpeed = Math.max(minSpeed, currentSpeed - speedStep);
            updateSpeed(currentSpeed);
        });

        increaseButton.addEventListener('click', () => {
            currentSpeed = Math.min(maxSpeed, currentSpeed + speedStep);
            updateSpeed(currentSpeed);
        });

        // 重置按钮
        const resetButton = document.createElement('button');
        resetButton.textContent = '重置';
        resetButton.style.cssText = `
            width: 100%;
            padding: 6px;
            border: none;
            border-radius: 4px;
            background: #2196F3;
            color: white;
            cursor: pointer;
            font-size: 14px;
            transition: background 0.3s;
        `;

        resetButton.addEventListener('click', () => {
            currentSpeed = 1.0;
            updateSpeed(currentSpeed);
        });

        // 更新速度的函数
        function updateSpeed(speed) {
            speedDisplay.textContent = `${speed.toFixed(1)}x`;
            const videos = document.getElementsByTagName('video');
            for (const video of videos) {
                video.playbackRate = speed;
            }
        }

        //
        speedControl.appendChild(decreaseButton);
        speedControl.appendChild(speedDisplay);
        speedControl.appendChild(increaseButton);

        controlPanel.appendChild(speedControl);
        controlPanel.appendChild(resetButton);

        // 加分隔线
        const separator = document.createElement('div');
        separator.style.cssText = `
            height: 1px;
            background: rgba(255,255,255,0.2);
            margin: 4px 0;
        `;
        controlPanel.appendChild(separator);

        // 下载按钮
        const downloadButton = document.createElement('button');
        downloadButton.textContent = '下载视频';
        downloadButton.style.cssText = `
            width: 100%;
            padding: 6px;
            border: none;
            border-radius: 4px;
            background: #FF5722;
            color: white;
            cursor: pointer;
            font-size: 14px;
            transition: background 0.3s;
        `;
        controlPanel.appendChild(downloadButton);

        // 在创建下载按钮后添加点击事件
        downloadButton.addEventListener('click', () => {
            const videos = document.getElementsByTagName('video');
            if (videos.length === 0) {
                alert('未找到可下载的视频!');
                return;
            }

            // 创建选择菜单
            const selectMenu = document.createElement('div');
            selectMenu.style.cssText = `
                position: fixed;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                background: white;
                padding: 20px;
                border-radius: 5px;
                box-shadow: 0 0 10px rgba(0,0,0,0.3);
                z-index: 999999;
                color: black;
            `;

            const title = document.createElement('h3');
            title.textContent = '请选择下载方式:';
            title.style.marginBottom = '15px';
            selectMenu.appendChild(title);

            // 创建按容器
            const buttonContainer = document.createElement('div');
            buttonContainer.style.display = 'flex';
            buttonContainer.style.gap = '10px';
            buttonContainer.style.justifyContent = 'center';

            // 直接下载按钮
            const directDownloadBtn = document.createElement('button');
            directDownloadBtn.textContent = '直接下载';
            directDownloadBtn.style.cssText = `
                padding: 8px 15px;
                border: none;
                border-radius: 4px;
                background: #4CAF50;
                color: white;
                cursor: pointer;
                font-size: 14px;
                transition: background 0.3s;
            `;
            directDownloadBtn.addEventListener('mouseover', () => directDownloadBtn.style.background = '#45a049');
            directDownloadBtn.addEventListener('mouseout', () => directDownloadBtn.style.background = '#4CAF50');
            directDownloadBtn.addEventListener('click', () => {
                document.body.removeChild(selectMenu);
                if (videos.length > 1) {
                    showVideoSelection(videos);
                } else {
                    downloadVideo(videos[0]);
                }
            });

            // 录制下载按钮
            const recordDownloadBtn = document.createElement('button');
            recordDownloadBtn.textContent = '录制下载';
            recordDownloadBtn.style.cssText = `
                padding: 8px 15px;
                border: none;
                border-radius: 4px;
                background: #FF5722;
                color: white;
                cursor: pointer;
                font-size: 14px;
                transition: background 0.3s;
            `;
            recordDownloadBtn.addEventListener('mouseover', () => recordDownloadBtn.style.background = '#F4511E');
            recordDownloadBtn.addEventListener('mouseout', () => recordDownloadBtn.style.background = '#FF5722');
            recordDownloadBtn.addEventListener('click', () => {
                document.body.removeChild(selectMenu);
                if (videos.length > 1) {
                    showVideoSelectionForRecording(videos);
                } else {
                    startRecording(videos[0]);
                }
            });

            buttonContainer.appendChild(directDownloadBtn);
            buttonContainer.appendChild(recordDownloadBtn);
            selectMenu.appendChild(buttonContainer);
            document.body.appendChild(selectMenu);

            // 添加拖动功能
            makeElementDraggable(selectMenu);
        });

        // 修改下载视频的函数
        function downloadVideo(video) {
            // 创建下载提示
            const downloadTip = createDownloadTip();
            downloadTip.textContent = '正在准备下载...';

            try {
                // 获取视频源的多种方式
                let videoUrl = '';

                // 方法1: 直接获取src
                videoUrl = video.currentSrc || video.src;

                // 方法2: 尝试获取source标签
                if (!videoUrl) {
                    const sources = video.getElementsByTagName('source');
                    if (sources.length > 0) {
                        videoUrl = sources[0].src;
                    }
                }

                // 方法3: 尝试从video标签的dataset中获取
                if (!videoUrl && video.dataset.src) {
                    videoUrl = video.dataset.src;
                }

                // 如果找不到视频源或是blob URL,提示使用录制方式
                if (!videoUrl || videoUrl.startsWith('blob:')) {
                    downloadTip.textContent = '无法直接下载视频,请使用录制方式!';
                    downloadTip.style.background = 'rgba(255, 0, 0, 0.8)';
                    setTimeout(() => document.body.removeChild(downloadTip), 3000);
                    return;
                }

                // 使用 GM_download 进行下载
                GM_download({
                    url: videoUrl,
                    name: `video_${new Date().getTime()}.mp4`,
                    headers: {
                        'Referer': window.location.href,
                        'Origin': window.location.origin,
                        'User-Agent': navigator.userAgent
                    },
                    onload: function() {
                        downloadTip.textContent = '下载已开始!';
                        setTimeout(() => document.body.removeChild(downloadTip), 2000);
                    },
                    onerror: function(error) {
                        console.error('Download failed:', error);
                        // 如果GM_download失败,尝试使用fetch方法
                        fallbackDownload(videoUrl, downloadTip);
                    }
                });

            } catch (error) {
                console.error('Download error:', error);
                // 如果主下载方法失败,尝试备用下载方法
                fallbackDownload(videoUrl, downloadTip);
            }
        }

        // 添加备用下载方法
        function fallbackDownload(videoUrl, downloadTip) {
            fetch(videoUrl, {
                method: 'GET',
                headers: {
                    'Referer': window.location.href,
                    'Origin': window.location.origin,
                    'Range': 'bytes=0-'
                },
                mode: 'cors',
                credentials: 'include'
            })
            .then(response => response.blob())
            .then(blob => {
                const url = window.URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.style.display = 'none';
                a.href = url;
                a.download = `video_${new Date().getTime()}.mp4`;
                document.body.appendChild(a);
                a.click();
                window.URL.revokeObjectURL(url);
                document.body.removeChild(a);

                downloadTip.textContent = '下载已开始!';
                setTimeout(() => document.body.removeChild(downloadTip), 2000);
            })
            .catch(error => {
                console.error('Fallback download failed:', error);
                downloadTip.textContent = '下载失败,请尝试使用录制方式';
                downloadTip.style.background = 'rgba(255, 0, 0, 0.8)';
                setTimeout(() => document.body.removeChild(downloadTip), 3000);
            });
        }

        // 创建下载提示的辅助函数
        function createDownloadTip() {
            const downloadTip = document.createElement('div');
            downloadTip.style.cssText = `
                position: fixed;
                top: 20px;
                left: 50%;
                transform: translateX(-50%);
                background: rgba(0, 0, 0, 0.8);
                color: white;
                padding: 10px 20px;
                border-radius: 5px;
                z-index: 999999;
                transition: all 0.3s ease;
            `;
            document.body.appendChild(downloadTip);
            return downloadTip;
        }

        // 添加拖动功能
        let isDragging = false;
        let currentX;
        let currentY;
        let initialX;
        let initialY;
        let xOffset = 0;
        let yOffset = 0;

        controlPanel.addEventListener('mousedown', dragStart);
        document.addEventListener('mousemove', drag);
        document.addEventListener('mouseup', dragEnd);

        function dragStart(e) {
            if (e.target === controlPanel) {
                isDragging = true;
                initialX = e.clientX - xOffset;
                initialY = e.clientY - yOffset;
            }
        }

        function drag(e) {
            if (isDragging) {
                e.preventDefault();
                currentX = e.clientX - initialX;
                currentY = e.clientY - initialY;
                xOffset = currentX;
                yOffset = currentY;

                setTranslate(currentX, currentY, controlPanel);
            }
        }

        function setTranslate(xPos, yPos, el) {
            el.style.transform = `translate(${xPos}px, ${yPos}px)`;
        }

        function dragEnd() {
            isDragging = false;
        }

        // 添加一个拖动提示
        controlPanel.title = '按住空白处拖动位置';

        // 在添加下载按钮后,添加另一个分隔线解除粘贴限制按钮
        const separator2 = document.createElement('div');
        separator2.style.cssText = `
            height: 1px;
            background: rgba(255,255,255,0.2);
            margin: 4px 0;
        `;
        controlPanel.appendChild(separator2);

        // 创建一个容器来放置两个按钮
        const pasteControlContainer = document.createElement('div');
        pasteControlContainer.style.cssText = `
            display: flex;
            gap: 5px;
            width: 100%;
        `;

        // 创建解除限制按钮
        const pasteButton = document.createElement('button');
        pasteButton.textContent = '限制已解除';
        pasteButton.style.cssText = `
            width: 100%;
            padding: 6px;
            border: none;
            border-radius: 4px;
            background: #4CAF50;
            color: white;
            cursor: pointer;
            font-size: 14px;
            transition: background 0.3s;
        `;

        // 添加点击事件
        pasteButton.addEventListener('click', () => {
            removeCopyLimits();
            showMessage('已解除输入限制!', 'success');
        });

        // 解除复制粘贴限制的核心函数
        function removeCopyLimits() {
            try {
                // 移除基本限
                document.body.removeAttribute("onselectstart");
                document.documentElement.style.userSelect = "unset";

                // 移除编辑器限制
                if (window.UE && window.UE.instants && typeof window.UE.instants === "object") {
                    for (const [key, instance] of Object.entries(window.UE.instants)) {
                        try {
                            if (instance.options) {
                                instance.options.disablePasteImage = false;
                            }
                            if (instance.removeListener) {
                                instance.removeListener("beforepaste", window.editorPaste);
                            }
                        } catch (error) {
                            console.error("[Input Helper] Failed to remove copy limits from editor instance", key, error);
                        }
                    }
                }

                // 移除调试器限制
                const constructorHook = Function.prototype.constructor;
                Function.prototype.constructor = (s) => {
                    if (s === "debugger") {
                        return () => {};
                    }
                    return constructorHook(s);
                };

                // 添加全样式
                const style = document.createElement('style');
                style.textContent = `
                    * {
                        user-select: text !important;
                        -webkit-user-select: text !important;
                        -moz-user-select: text !important;
                        -ms-user-select: text !important;
                    }
                `;
                document.head.appendChild(style);

                console.info("[Input Helper] Successfully removed copy limits.");
            } catch (error) {
                console.error("[Input Helper] Failed to remove copy limits:", error);
            }
        }

        // 在页面加载完成后自动执行一次
        setTimeout(removeCopyLimits, 1000);

        // 将按钮添加到控制面板
        pasteControlContainer.appendChild(pasteButton);

        // 将容器添加到控制面板
        controlPanel.appendChild(pasteControlContainer);

        // 添加分隔线
        const separator3 = document.createElement('div');
        separator3.style.cssText = `
            height: 1px;
            background: rgba(255,255,255,0.2);
            margin: 4px 0;
        `;
        controlPanel.appendChild(separator3);

        // 换原来的快捷键设置钮为更新检查按钮
        const updateButton = document.createElement('button');
        updateButton.textContent = '检查更新';
        updateButton.style.cssText = `
            width: 100%;
            padding: 6px;
            border: none;
            border-radius: 4px;
            background: #2196F3;
            color: white;
            cursor: pointer;
            font-size: 14px;
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 6px;
        `;

        // 添加更新图标
        const updateIcon = document.createElement('span');
        updateIcon.innerHTML = '↻';
        updateIcon.style.cssText = `
            display: inline-block;
            transition: transform 0.3s ease;
        `;
        updateButton.prepend(updateIcon);

        // 添加悬停效果
        updateButton.addEventListener('mouseover', () => {
            updateButton.style.background = '#1976D2';
            updateIcon.style.transform = 'rotate(180deg)';
        });
        updateButton.addEventListener('mouseout', () => {
            updateButton.style.background = '#2196F3';
            updateIcon.style.transform = 'rotate(0)';
        });

        // 添加点击事件
        updateButton.addEventListener('click', () => {
            // 添加旋转动画
            updateIcon.style.animation = 'checking 1s linear infinite';

            // 跳转到更新页面
            window.open('http://113.44.209.113:9002/', '_blank');

            // 移除动画
            setTimeout(() => {
                updateIcon.style.animation = 'none';
            }, 1000);
        });

        // 添加动画样式
        const style = document.createElement('style');
        style.textContent = `
            @keyframes checking {
                0% { transform: rotate(0deg); }
                100% { transform: rotate(360deg); }
            }
        `;
        document.head.appendChild(style);

        // 将更新按钮添加到控制面板
        controlPanel.appendChild(updateButton);

        // 更新按钮提示文本
        disablePasteButton.title = `快捷键:${formatHotkey(hotkeys.inputText)}`;

        // 添加辅助函数到作用域
        function formatHotkey(hotkey) {
            const parts = [];
            if (hotkey.ctrl) parts.push('Ctrl');
            if (hotkey.shift) parts.push('Shift');
            if (hotkey.alt) parts.push('Alt');
            parts.push(hotkey.key.toUpperCase());
            return parts.join(' + ');
        }

        function showTip(message) {
            const tip = document.createElement('div');
            tip.style.cssText = `
                position: fixed;
                top: 20px;
                left: 50%;
                transform: translateX(-50%);
                background: rgba(0, 0, 0, 0.8);
                color: white;
                padding: 10px 20px;
                border-radius: 5px;
                z-index: 999999;
            `;
            tip.textContent = message;
            document.body.appendChild(tip);
            setTimeout(() => {
                document.body.removeChild(tip);
            }, 2000);
        }

        function createSettingsWindow() {
            const settingsWindow = document.createElement('div');
            settingsWindow.style.cssText = `
                position: fixed;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                background: white;
                padding: 20px;
                border-radius: 5px;
                box-shadow: 0 0 10px rgba(0,0,0,0.3);
                z-index: 999999;
                min-width: 300px;
                color: black;
            `;

            const title = document.createElement('h3');
            title.textContent = '快捷键设置';
            title.style.marginBottom = '15px';
            settingsWindow.appendChild(title);

            // 创建快捷键输入区域
            const hotkeyInput = document.createElement('input');
            hotkeyInput.type = 'text';
            hotkeyInput.readOnly = true;
            hotkeyInput.value = formatHotkey(hotkeys.inputText);
            hotkeyInput.style.cssText = `
                width: 100%;
                padding: 8px;
                margin: 10px 0;
                border: 1px solid #ccc;
                border-radius: 4px;
            `;

            const label = document.createElement('div');
            label.textContent = '输入文字快捷键:';
            label.style.color = '#333';
            settingsWindow.appendChild(label);
            settingsWindow.appendChild(hotkeyInput);

            // 添加提示文本
            const tip = document.createElement('div');
            tip.textContent = '点击输入框并按下新的快捷键组合';
            tip.style.cssText = `
                font-size: 12px;
                color: #666;
                margin: 5px 0 15px 0;
            `;
            settingsWindow.appendChild(tip);

            // 添加按钮容器
            const buttonContainer = document.createElement('div');
            buttonContainer.style.cssText = `
                display: flex;
                gap: 10px;
                margin-top: 20px;
            `;

            // 保存按钮
            const saveButton = document.createElement('button');
            saveButton.textContent = '保存';
            saveButton.style.cssText = `
                flex: 1;
                padding: 8px;
                border: none;
                border-radius: 4px;
                background: #4CAF50;
                color: white;
                cursor: pointer;
            `;

            // 取消按钮
            const cancelButton = document.createElement('button');
            cancelButton.textContent = '取消';
            cancelButton.style.cssText = `
                flex: 1;
                padding: 8px;
                border: none;
                border-radius: 4px;
                background: #f44336;
                color: white;
                cursor: pointer;
            `;

            // 添加快捷键监听
            hotkeyInput.addEventListener('keydown', (e) => {
                e.preventDefault();
                const newHotkey = {
                    key: e.key.toLowerCase(),
                    ctrl: e.ctrlKey,
                    shift: e.shiftKey,
                    alt: e.altKey
                };
                hotkeys.inputText = newHotkey;
                hotkeyInput.value = formatHotkey(newHotkey);
            });

            // 添加按钮事件
            saveButton.addEventListener('click', () => {
                localStorage.setItem('videoSpeedHotkeys', JSON.stringify(hotkeys));
                disablePasteButton.title = `快捷键:${formatHotkey(hotkeys.inputText)}`;
                document.body.removeChild(settingsWindow);
                showTip('快捷键设置已保存!');
            });

            cancelButton.addEventListener('click', () => {
                document.body.removeChild(settingsWindow);
            });

            buttonContainer.appendChild(saveButton);
            buttonContainer.appendChild(cancelButton);
            settingsWindow.appendChild(buttonContainer);

            // 添加拖动功能
            makeElementDraggable(settingsWindow);

            document.body.appendChild(settingsWindow);
        }

        // 在添加更新按钮后,添加版本显示
        const versionInfo = document.createElement('div');
        versionInfo.style.cssText = `
            text-align: center;
            color: rgba(255, 255, 255, 0.6);
            font-size: 12px;
            margin-top: 8px;
            padding: 4px;
            border-radius: 4px;
            background: rgba(255, 255, 255, 0.1);
        `;
        versionInfo.textContent = 'v1.0.0';  // 使用脚本的当前版本

        // 将版本信息添加到控制面板
        controlPanel.appendChild(versionInfo);

        // 为版本信息添加悬停效果
        versionInfo.addEventListener('mouseover', () => {
            versionInfo.style.background = 'rgba(255, 255, 255, 0.15)';
        });
        versionInfo.addEventListener('mouseout', () => {
            versionInfo.style.background = 'rgba(255, 255, 255, 0.1)';
        });

        function startRecording(video) {
            try {
                const stream = video.captureStream();
                const mediaRecorder = new MediaRecorder(stream, {
                    mimeType: 'video/webm;codecs=h264,opus', // 使用H264编码
                    videoBitsPerSecond: 2500000, // 2.5Mbps视频比特率
                    audioBitsPerSecond: 128000   // 128kbps音频比特率
                });
                const chunks = [];

                // 创建录制控制界面
                const recordControl = document.createElement('div');
                recordControl.style.cssText = `
                    position: fixed;
                    top: 50%;
                    left: 50%;
                    transform: translate(-50%, -50%);
                    background: white;
                    padding: 20px;
                    border-radius: 5px;
                    box-shadow: 0 0 10px rgba(0,0,0,0.3);
                    z-index: 999999;
                    color: black;
                    text-align: center;
                `;

                // 添加进度条
                const progress = document.createElement('div');
                progress.style.cssText = `
                    width: 300px;
                    height: 20px;
                    background: #f0f0f0;
                    border-radius: 10px;
                    margin: 10px 0;
                    overflow: hidden;
                `;

                const progressBar = document.createElement('div');
                progressBar.style.cssText = `
                    width: 0%;
                    height: 100%;
                    background: #4CAF50;
                    transition: width 1s linear;
                `;
                progress.appendChild(progressBar);

                // 添加时显示
                const timeDisplay = document.createElement('div');
                timeDisplay.style.marginBottom = '10px';

                // 添加控制按钮
                const controlButtons = document.createElement('div');
                controlButtons.style.marginTop = '10px';

                const stopButton = document.createElement('button');
                stopButton.textContent = '停止录制';
                stopButton.style.cssText = `
                    padding: 5px 15px;
                    margin: 0 5px;
                    border: none;
                    border-radius: 3px;
                    background: #f44336;
                    color: white;
                    cursor: pointer;
                `;

                recordControl.appendChild(timeDisplay);
                recordControl.appendChild(progress);
                recordControl.appendChild(controlButtons);
                controlButtons.appendChild(stopButton);

                document.body.appendChild(recordControl);

                // 开始录制
                let startTime = Date.now();
                let duration = 0;
                mediaRecorder.start(1000); // 每秒保存一次数据

                // 更新进度的函数
                const updateProgress = () => {
                    if (mediaRecorder.state === 'recording') {
                        duration = Math.floor((Date.now() - startTime) / 1000);
                        timeDisplay.textContent = `录制 ${duration} 秒`;
                        progressBar.style.width = `${Math.min((duration / 300) * 100, 100)}%`;

                        if (duration >= 300) {
                            mediaRecorder.stop();
                            return;
                        }

                        requestAnimationFrame(updateProgress);
                    }
                };

                updateProgress();

                // 修改处理录制数据的部分
                mediaRecorder.ondataavailable = (e) => {
                    if (e.data && e.data.size > 0) {
                        chunks.push(e.data);
                    }
                };

                // 修改停止制的处理
                mediaRecorder.onstop = () => {
                    if (chunks.length > 0) {
                        const blob = new Blob(chunks, {
                            type: 'video/webm;codecs=h264,opus'
                        });
                        // 添加metadata以支持进度条
                        const metadata = {
                            duration: duration,
                            lastModified: new Date().getTime()
                        };
                        const finalBlob = new Blob([blob], {
                            type: 'video/webm;codecs=h264,opus',
                            ...metadata
                        });
                        const url = window.URL.createObjectURL(finalBlob);
                        const a = document.createElement('a');
                        a.href = url;
                        a.download = `recorded_video_${new Date().getTime()}.webm`;
                        document.body.appendChild(a);
                        a.click();
                        window.URL.revokeObjectURL(url);
                        document.body.removeChild(a);

                        // 显示下载提示
                        const downloadTip = document.createElement('div');
                        downloadTip.style.cssText = `
                            position: fixed;
                            top: 20px;
                            left: 50%;
                            transform: translateX(-50%);
                            background: rgba(0, 0, 0, 0.8);
                            color: white;
                            padding: 10px 20px;
                            border-radius: 5px;
                            z-index: 999999;
                        `;
                        downloadTip.textContent = '录制完成,开始下载!';
                        document.body.appendChild(downloadTip);
                        setTimeout(() => {
                            document.body.removeChild(downloadTip);
                        }, 2000);
                    }
                    // 移除录制控制界面
                    document.body.removeChild(recordControl);
                };

                // 停止按钮��件
                stopButton.addEventListener('click', () => {
                    if (mediaRecorder.state === 'recording') {
                        mediaRecorder.stop();
                    }
                });

                // 添加拖动功能
                makeElementDraggable(recordControl);
                recordControl.title = '按住可拖动';

                return mediaRecorder;
            } catch (err) {
                // 如果H264编码不支持,回退到VP8
                try {
                    const mediaRecorder = new MediaRecorder(stream, {
                        mimeType: 'video/webm;codecs=vp8,opus',
                        videoBitsPerSecond: 2500000,
                        audioBitsPerSecond: 128000
                    });
                    // ... 继续录制流程 ...
                } catch (fallbackErr) {
                    console.error('录制失败:', fallbackErr);
                    alert('录制失败,该视频可能无法录制');
                    return null;
                }
            }
        }

        // 添加视频选择函数
        function showVideoSelection(videos) {
            const selectMenu = document.createElement('div');
            selectMenu.style.cssText = `
                position: fixed;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                background: white;
                padding: 20px;
                border-radius: 5px;
                box-shadow: 0 0 10px rgba(0,0,0,0.3);
                z-index: 999999;
                color: black;
            `;

            const title = document.createElement('h3');
            title.textContent = '选择要下载的视频:';
            title.style.marginBottom = '10px';
            selectMenu.appendChild(title);

            Array.from(videos).forEach((video, index) => {
                const button = document.createElement('button');
                button.textContent = `视频 ${index + 1}`;
                button.style.cssText = buttonStyle;
                button.style.margin = '5px';
                button.style.background = '#4CAF50';
                button.addEventListener('click', () => {
                    downloadVideo(video);
                    document.body.removeChild(selectMenu);
                });
                selectMenu.appendChild(button);
            });

            document.body.appendChild(selectMenu);
        }

        // 添加录制视频选择函数
        function showVideoSelectionForRecording(videos) {
            const selectMenu = document.createElement('div');
            selectMenu.style.cssText = `
                position: fixed;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                background: white;
                padding: 20px;
                border-radius: 5px;
                box-shadow: 0 0 10px rgba(0,0,0,0.3);
                z-index: 999999;
                color: black;
            `;

            const title = document.createElement('h3');
            title.textContent = '选择录制的视频:';
            title.style.marginBottom = '10px';
            selectMenu.appendChild(title);

            Array.from(videos).forEach((video, index) => {
                const button = document.createElement('button');
                button.textContent = `视频 ${index + 1}`;
                button.style.cssText = buttonStyle;
                button.style.margin = '5px';
                button.style.background = '#FF5722';
                button.addEventListener('click', () => {
                    startRecording(video);
                    document.body.removeChild(selectMenu);
                });
                selectMenu.appendChild(button);
            });

            document.body.appendChild(selectMenu);
        }

        // 修改录制控制面板,添加拖动功能
        function makeElementDraggable(element) {
            let isDragging = false;
            let currentX;
            let currentY;
            let initialX;
            let initialY;
            let xOffset = 0;
            let yOffset = 0;

            element.style.cursor = 'move';

            element.addEventListener('mousedown', dragStart);
            document.addEventListener('mousemove', drag);
            document.addEventListener('mouseup', dragEnd);

            function dragStart(e) {
                if (e.target === element || e.target.parentNode === element) {
                    initialX = e.clientX - xOffset;
                    initialY = e.clientY - yOffset;
                    isDragging = true;
                }
            }

            function drag(e) {
                if (isDragging) {
                    e.preventDefault();
                    currentX = e.clientX - initialX;
                    currentY = e.clientY - initialY;
                    xOffset = currentX;
                    yOffset = currentY;

                    setTranslate(currentX, currentY, element);
                }
            }

            function setTranslate(xPos, yPos, el) {
                el.style.transform = `translate(${xPos}px, ${yPos}px)`;
            }

            function dragEnd() {
                isDragging = false;
            }
        }

        // 添��一个变量来存储最后聚焦的输入框
        let lastFocusedElement = null;

        // 添加全局焦点监听
        document.addEventListener('focusin', (e) => {
            if (e.target.tagName === 'INPUT' ||
                e.target.tagName === 'TEXTAREA' ||
                e.target.getAttribute('contenteditable') === 'true') {
                lastFocusedElement = e.target;
            }
        });
    }

    // 在页面加载完成后建面板
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', createControlPanel);
    } else {
        createControlPanel();
    }

    // 添加一个定时检查,确保面板存在
    setInterval(() => {
        if (!document.getElementById(PANEL_ID)) {
            createControlPanel();
        }
    }, 1000);
})();