上海开放大学视频自动播放静音助手

上海开放大学学习平台专用,自动播放课程视频并默认静音,提升学习效率,客服V:wkwk796

// ==UserScript==
// @name         上海开放大学视频自动播放静音助手
// @namespace    http://tampermonkey.net/
// @version      1.3
// @description  上海开放大学学习平台专用,自动播放课程视频并默认静音,提升学习效率,客服V:wkwk796
// @author       wkwk796
// @match        *://*.shtvu.edu.cn/*
// @match        *://elearning.shtvu.edu.cn/*
// @match        *://study.shtvu.edu.cn/*
// @match        *://course.shtvu.edu.cn/*
// @match        *://mooc.shtvu.edu.cn/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=shtvu.edu.cn
// @grant        GM_addStyle
// @grant        GM_registerMenuCommand
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        unsafeWindow
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // 配置项
    const config = {
        autoPlay: GM_getValue('autoPlay', true),
        autoMute: GM_getValue('autoMute', true),
        autoNext: GM_getValue('autoNext', true),
        showContact: GM_getValue('showContact', true),
        customSpeed: parseFloat(GM_getValue('customSpeed', 1.0)),
        skipCompleted: GM_getValue('skipCompleted', true),
        disableMonitor: GM_getValue('disableMonitor', false)
    };

    // 保存配置
    function saveConfig() {
        try {
            GM_setValue('autoPlay', config.autoPlay);
            GM_setValue('autoMute', config.autoMute);
            GM_setValue('autoNext', config.autoNext);
            GM_setValue('showContact', config.showContact);
            GM_setValue('customSpeed', config.customSpeed);
            GM_setValue('skipCompleted', config.skipCompleted);
            GM_setValue('disableMonitor', config.disableMonitor);
        } catch (e) {
            console.error('保存配置失败:', e);
        }
    }

    // 显示通知
    function showNotification(message, type = 'info') {
        try {
            if (!document || !document.body) return;
            
            const notification = document.createElement('div');
            notification.className = 'shtvu-notification notification-' + type;
            notification.textContent = message;
            
            document.body.appendChild(notification);
            
            setTimeout(() => {
                notification.classList.add('fade-out');
                setTimeout(() => {
                    if (document.body && document.body.contains(notification)) {
                        document.body.removeChild(notification);
                    }
                }, 300);
            }, 3000);
        } catch (e) {
            console.error('显示通知失败:', e);
        }
    }

    // 创建控制面板
    function createControlPanel() {
        try {
            if (!document || !document.body) return;
            
            // 检查是否已存在控制面板
            const existingPanel = document.getElementById('shtvu-auto-play-panel');
            if (existingPanel) {
                existingPanel.style.display = 'block';
                return;
            }

            const panel = document.createElement('div');
            panel.id = 'shtvu-auto-play-panel';
            
            // 使用字符串拼接避免语法问题
            let panelHTML = '';
            panelHTML += '<div class="shtvu-panel-header">';
            panelHTML += '    <h3>上海开放大学视频助手控制面板</h3>';
            panelHTML += '    <button id="shtvu-close-panel">×</button>';
            panelHTML += '</div>';
            panelHTML += '<div class="shtvu-panel-body">';
            panelHTML += '    <div class="shtvu-control-item">';
            panelHTML += '        <label>';
            panelHTML += '            <input type="checkbox" id="shtvu-auto-play"' + (config.autoPlay ? ' checked' : '') + '>';
            panelHTML += '            自动播放视频';
            panelHTML += '        </label>';
            panelHTML += '    </div>';
            panelHTML += '    <div class="shtvu-control-item">';
            panelHTML += '        <label>';
            panelHTML += '            <input type="checkbox" id="shtvu-auto-mute"' + (config.autoMute ? ' checked' : '') + '>';
            panelHTML += '            自动静音';
            panelHTML += '        </label>';
            panelHTML += '    </div>';
            panelHTML += '    <div class="shtvu-control-item">';
            panelHTML += '        <label>';
            panelHTML += '            <input type="checkbox" id="shtvu-auto-next"' + (config.autoNext ? ' checked' : '') + '>';
            panelHTML += '            自动播放下一节';
            panelHTML += '        </label>';
            panelHTML += '    </div>';
            panelHTML += '    <div class="shtvu-control-item">';
            panelHTML += '        <label>';
            panelHTML += '            <input type="checkbox" id="shtvu-skip-completed"' + (config.skipCompleted ? ' checked' : '') + '>';
            panelHTML += '            跳过已完成视频';
            panelHTML += '        </label>';
            panelHTML += '    </div>';
            panelHTML += '    <div class="shtvu-control-item">';
            panelHTML += '        <label>';
            panelHTML += '            <input type="checkbox" id="shtvu-disable-monitor"' + (config.disableMonitor ? ' checked' : '') + '>';
            panelHTML += '            禁用多端监控';
            panelHTML += '        </label>';
            panelHTML += '    </div>';
            panelHTML += '    <div class="shtvu-control-item">';
            panelHTML += '        <label>';
            panelHTML += '            播放速度:';
            panelHTML += '            <select id="shtvu-playback-speed">';
            panelHTML += '                <option value="0.5"' + (config.customSpeed === 0.5 ? ' selected' : '') + '>0.5x</option>';
            panelHTML += '                <option value="1.0"' + (config.customSpeed === 1.0 ? ' selected' : '') + '>1.0x</option>';
            panelHTML += '                <option value="1.25"' + (config.customSpeed === 1.25 ? ' selected' : '') + '>1.25x</option>';
            panelHTML += '                <option value="1.5"' + (config.customSpeed === 1.5 ? ' selected' : '') + '>1.5x</option>';
            panelHTML += '                <option value="2.0"' + (config.customSpeed === 2.0 ? ' selected' : '') + '>2.0x</option>';
            panelHTML += '                <option value="3.0"' + (config.customSpeed === 3.0 ? ' selected' : '') + '>3.0x</option>';
            panelHTML += '                <option value="4.0"' + (config.customSpeed === 4.0 ? ' selected' : '') + '>4.0x</option>';
            panelHTML += '            </select>';
            panelHTML += '        </label>';
            panelHTML += '    </div>';
            
            if (config.showContact) {
                panelHTML += '    <div class="shtvu-contact-info">';
                panelHTML += '        <p>开发者联系方式: wkwk796</p>';
                panelHTML += '    </div>';
            }
            
            panelHTML += '    <div class="shtvu-panel-footer">';
            panelHTML += '        <button id="shtvu-toggle-contact">' + (config.showContact ? '隐藏联系方式' : '显示联系方式') + '</button>';
            panelHTML += '        <button id="shtvu-refresh-video">刷新视频检测</button>';
            panelHTML += '    </div>';
            panelHTML += '</div>';
            
            panel.innerHTML = panelHTML;
            document.body.appendChild(panel);

            // 添加事件监听器
            setupPanelEventListeners(panel);
        } catch (e) {
            console.error('创建控制面板失败:', e);
        }
    }

    // 设置面板事件监听器
    function setupPanelEventListeners(panel) {
        try {
            const closeBtn = document.getElementById('shtvu-close-panel');
            if (closeBtn) {
                closeBtn.addEventListener('click', () => {
                    panel.style.display = 'none';
                });
            }

            const autoPlayCheckbox = document.getElementById('shtvu-auto-play');
            if (autoPlayCheckbox) {
                autoPlayCheckbox.addEventListener('change', (e) => {
                    config.autoPlay = e.target.checked;
                    saveConfig();
                });
            }

            const autoMuteCheckbox = document.getElementById('shtvu-auto-mute');
            if (autoMuteCheckbox) {
                autoMuteCheckbox.addEventListener('change', (e) => {
                    config.autoMute = e.target.checked;
                    saveConfig();
                    // 如果启用静音,立即将所有视频设为静音
                    if (config.autoMute && document) {
                        const videos = document.querySelectorAll('video');
                        videos.forEach(video => {
                            if (video && video.volume !== undefined) {
                                video.muted = true;
                            }
                        });
                    }
                });
            }

            const autoNextCheckbox = document.getElementById('shtvu-auto-next');
            if (autoNextCheckbox) {
                autoNextCheckbox.addEventListener('change', (e) => {
                    config.autoNext = e.target.checked;
                    saveConfig();
                });
            }

            const skipCompletedCheckbox = document.getElementById('shtvu-skip-completed');
            if (skipCompletedCheckbox) {
                skipCompletedCheckbox.addEventListener('change', (e) => {
                    config.skipCompleted = e.target.checked;
                    saveConfig();
                });
            }

            const disableMonitorCheckbox = document.getElementById('shtvu-disable-monitor');
            if (disableMonitorCheckbox) {
                disableMonitorCheckbox.addEventListener('change', (e) => {
                    config.disableMonitor = e.target.checked;
                    saveConfig();
                    if (config.disableMonitor) {
                        disableMultiDeviceMonitor();
                    }
                });
            }

            const playbackSpeedSelect = document.getElementById('shtvu-playback-speed');
            if (playbackSpeedSelect) {
                playbackSpeedSelect.addEventListener('change', (e) => {
                    config.customSpeed = parseFloat(e.target.value);
                    saveConfig();
                    applyPlaybackSpeed();
                });
            }

            const toggleContactBtn = document.getElementById('shtvu-toggle-contact');
            if (toggleContactBtn) {
                toggleContactBtn.addEventListener('click', () => {
                    config.showContact = !config.showContact;
                    saveConfig();
                    const contactInfo = document.querySelector('.shtvu-contact-info');
                    if (contactInfo) {
                        contactInfo.style.display = config.showContact ? 'block' : 'none';
                    }
                    toggleContactBtn.textContent = config.showContact ? '隐藏联系方式' : '显示联系方式';
                });
            }

            const refreshVideoBtn = document.getElementById('shtvu-refresh-video');
            if (refreshVideoBtn) {
                refreshVideoBtn.addEventListener('click', () => {
                    handleVideo();
                    setupVideoEndDetection();
                    showNotification('视频检测已刷新', 'success');
                });
            }
        } catch (e) {
            console.error('设置面板事件监听器失败:', e);
        }
    }

    // 处理视频播放和静音
    function handleVideo() {
        try {
            if (!document) return;
            
            // 跳过已完成视频检查
            if (config.skipCompleted) {
                const completedMarks = document.querySelectorAll(
                    '.completed, .finished, .success, .check, ' +
                    '.icon-finish, .status-completed, .task-finished,' +
                    '[class*="finish"], [class*="complete"]'
                );
                
                // 如果页面上有多个完成标记但没有正在播放的视频,尝试跳转到下一个任务
                if (completedMarks.length > 2 && !isVideoPlaying()) {
                    showNotification('检测到已完成视频,正在尝试跳转到下一个任务', 'info');
                    setTimeout(tryNavigateToNextTask, 1000);
                    return;
                }
            }

            // 查找所有视频元素
            const videos = document.querySelectorAll('video');
            let foundVideo = false;

            videos.forEach(video => {
                try {
                    if (!video) return;
                    
                    foundVideo = true;
                    
                    // 自动静音
                    if (config.autoMute && !video.muted && video.volume !== undefined) {
                        video.muted = true;
                    }

                    // 应用播放速度
                    applyPlaybackSpeed();

                    // 自动播放
                    if (config.autoPlay && video.paused && canPlayVideo(video)) {
                        // 尝试直接播放
                        Promise.resolve(video.play()).then(() => {
                            showNotification('视频已自动播放', 'success');
                        }).catch(err => {
                            console.log('直接播放失败,尝试模拟用户交互:', err);
                            // 尝试模拟用户交互后播放
                            simulateUserInteraction(video);
                        });
                    }
                } catch (e) {
                    console.error('处理单个视频元素时出错:', e);
                }
            });

            // 如果没找到视频元素,尝试查找上海开放大学平台常见的播放按钮
            if (!foundVideo && config.autoPlay) {
                clickPlayButtons();
            }
        } catch (e) {
            console.error('处理视频播放失败:', e);
        }
    }

    // 检查视频是否可以播放
    function canPlayVideo(video) {
        try {
            if (!video) return false;
            // 检查视频是否有有效的源
            if ((video.src && video.src.trim() !== '') || (video.currentSrc && video.currentSrc.trim() !== '')) {
                // 检查视频是否已经加载了一些数据
                if (video.readyState > 0 || video.duration > 0) {
                    return true;
                }
            }
            return false;
        } catch (e) {
            console.error('检查视频可用性失败:', e);
            return false;
        }
    }

    // 检查是否有视频正在播放
    function isVideoPlaying() {
        try {
            if (!document) return false;
            const videos = document.querySelectorAll('video');
            return Array.from(videos).some(video => {
                try {
                    return video && !video.paused && !video.ended && video.currentTime > 0;
                } catch (e) {
                    return false;
                }
            });
        } catch (e) {
            console.error('检查视频播放状态失败:', e);
            return false;
        }
    }

    // 应用播放速度
    function applyPlaybackSpeed() {
        try {
            if (!document) return;
            const videos = document.querySelectorAll('video');
            videos.forEach(video => {
                try {
                    if (video && typeof video.playbackRate !== 'undefined') {
                        video.playbackRate = config.customSpeed;
                    }
                } catch (e) {
                    console.error('设置播放速度失败:', e);
                }
            });
        } catch (e) {
            console.error('应用播放速度失败:', e);
        }
    }

    // 模拟用户交互
    function simulateUserInteraction(video) {
        try {
            if (!video) return;
            
            // 创建一个临时按钮并点击
            const tempBtn = document.createElement('button');
            tempBtn.style.position = 'absolute';
            tempBtn.style.left = '-9999px';
            document.body.appendChild(tempBtn);
            
            tempBtn.addEventListener('click', () => {
                video.play().catch(err => {
                    console.log('模拟用户交互后播放仍失败:', err);
                });
            });
            
            // 触发点击事件
            tempBtn.click();
            
            // 清理临时按钮
            setTimeout(() => {
                if (document.body && document.body.contains(tempBtn)) {
                    document.body.removeChild(tempBtn);
                }
            }, 100);
        } catch (e) {
            console.error('模拟用户交互失败:', e);
        }
    }

    // 点击上海开放大学平台常见的播放按钮
    function clickPlayButtons() {
        try {
            if (!document) return;
            
            // 上海开放大学平台常见的播放按钮选择器
            const playButtonSelectors = [
                '.play, .play-button, .video-play, .btn-play',
                '.start, .start-button, .btn-start',
                '.video-control .play, .player-control .play',
                '.shtvu-play, .shtvu-video-play',
                '.elearning-play, .mooc-play',
                '.course-video-play, .lesson-play',
                '.video-content .play, .video-wrapper .play',
                '[class*="play"][class*="btn"], [class*="play"][class*="button"]',
                '.icon-play, .play-icon, .iconfont.icon-play',
                '.fa-play, .fa-play-circle'
            ];

            let clicked = false;

            playButtonSelectors.forEach(selector => {
                try {
                    const buttons = document.querySelectorAll(selector);
                    buttons.forEach(button => {
                        // 确保按钮可见且可点击
                        if (button.offsetParent !== null && 
                            button.style.display !== 'none' && 
                            button.style.visibility !== 'hidden') {
                            // 添加随机延迟,避免检测
                            setTimeout(() => {
                                button.click();
                                if (!clicked) {
                                    showNotification('尝试点击播放按钮', 'info');
                                    clicked = true;
                                }
                            }, Math.random() * 500);
                        }
                    });
                } catch (e) {
                    console.log('选择器 ' + selector + ' 出错:', e);
                }
            });

            // 特殊处理:查找iframe中的视频播放按钮
            try {
                const iframes = document.querySelectorAll('iframe');
                iframes.forEach(iframe => {
                    try {
                        const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
                        if (iframeDoc) {
                            const iframeButtons = iframeDoc.querySelectorAll(
                                '.play, .play-button, .video-play, .icon-play'
                            );
                            iframeButtons.forEach(button => {
                                setTimeout(() => {
                                    button.click();
                                }, Math.random() * 1000);
                            });
                        }
                    } catch (e) {
                        // 跨域iframe可能会抛出错误,忽略
                    }
                });
            } catch (e) {
                console.log('处理iframe播放按钮时出错:', e);
            }
        } catch (e) {
            console.error('点击播放按钮失败:', e);
        }
    }

    // 设置视频结束检测
    function setupVideoEndDetection() {
        try {
            if (!document) return;
            
            const videos = document.querySelectorAll('video');
            videos.forEach(video => {
                try {
                    if (!video) return;
                    
                    // 移除已存在的监听器,避免重复
                    video.removeEventListener('ended', onVideoEnded);
                    video.addEventListener('ended', onVideoEnded);
                } catch (e) {
                    console.error('设置视频结束监听失败:', e);
                }
            });

            // 监听进度变化,检测是否播放完成(有些平台可能不会触发ended事件)
            videos.forEach(video => {
                try {
                    if (!video) return;
                    
                    video.addEventListener('timeupdate', () => {
                        try {
                            if (video.duration > 0 && video.currentTime >= video.duration - 0.5) {
                                onVideoEnded();
                            }
                        } catch (e) {
                            console.error('检测视频进度时出错:', e);
                        }
                    });
                } catch (e) {
                    console.error('设置视频进度监听失败:', e);
                }
            });
        } catch (e) {
            console.error('设置视频结束检测失败:', e);
        }
    }

    // 视频播放结束后的处理
    function onVideoEnded() {
        try {
            showNotification('视频播放完成', 'success');
            
            if (config.autoNext) {
                setTimeout(() => {
                    tryNavigateToNextTask();
                }, 2000);
            }
        } catch (e) {
            console.error('处理视频结束事件失败:', e);
        }
    }

    // 尝试导航到下一个任务
    function tryNavigateToNextTask() {
        try {
            if (!document || !config.autoNext) return;
            
            // 上海开放大学平台常见的下一节按钮选择器
            const nextButtonSelectors = [
                '.next, .next-button, .btn-next',
                '.next-step, .step-next, .next-lesson',
                '.next-chapter, .chapter-next',
                '.shtvu-next, .shtvu-next-button',
                '.elearning-next, .mooc-next',
                '.course-next, .lesson-next',
                '[class*="next"][class*="btn"], [class*="next"][class*="button"]',
                '.finish-button, .complete-button, .continue-button',
                '.task-finish-button, .lesson-complete-button'
            ];

            let navigated = false;

            nextButtonSelectors.forEach(selector => {
                try {
                    const buttons = document.querySelectorAll(selector);
                    buttons.forEach(button => {
                        if (button.offsetParent !== null && !navigated) {
                            // 滚动到按钮位置
                            button.scrollIntoView({ behavior: 'smooth', block: 'center' });
                            
                            // 模拟点击
                            setTimeout(() => {
                                button.click();
                                navigated = true;
                                showNotification('已自动跳转到下一节', 'success');
                            }, 500);
                        }
                    });
                } catch (e) {
                    console.log('下一节按钮选择器 ' + selector + ' 出错:', e);
                }
            });

            // 尝试在任务列表中查找下一个未完成的任务
            if (!navigated) {
                const taskItemSelectors = [
                    '.task-item, .lesson-item, .chapter-item',
                    '.course-item, .content-item, .video-item',
                    '.list-item, .menu-item, .nav-item'
                ];

                taskItemSelectors.forEach(selector => {
                    try {
                        const items = document.querySelectorAll(selector);
                        for (let i = 0; i < items.length; i++) {
                            const item = items[i];
                            // 检查是否包含完成标记
                            const hasCompletedMark = item.querySelector(
                                '.completed, .finished, .success, .check'
                            );
                            
                            // 如果找到一个没有完成标记的项目,点击它
                            if (!hasCompletedMark && item.offsetParent !== null && !navigated) {
                                item.scrollIntoView({ behavior: 'smooth', block: 'center' });
                                setTimeout(() => {
                                    item.click();
                                    navigated = true;
                                    showNotification('已跳转到下一个未完成任务', 'success');
                                }, 500);
                                break;
                            }
                        }
                    } catch (e) {
                        console.log('任务列表选择器 ' + selector + ' 出错:', e);
                    }
                });
            }

            if (!navigated) {
                showNotification('未找到可跳转的下一节内容', 'info');
            }
        } catch (e) {
            console.error('尝试导航到下一个任务失败:', e);
        }
    }

    // 禁用多端监控(如果需要)
    function disableMultiDeviceMonitor() {
        try {
            if (!config.disableMonitor) return;
            
            // 尝试禁用常见的多端监控方法
            if (unsafeWindow && typeof unsafeWindow === 'object') {
                // 覆盖常见的监控函数
                const monitorFunctions = ['checkMultiDevice', 'detectMultiLogin', 'monitorUserActivity', 'checkUserSession', 'validateLogin'];
                monitorFunctions.forEach(func => {
                    if (unsafeWindow[func]) {
                        unsafeWindow[func] = () => true;
                    }
                });
                
                // 模拟用户活动
                if (typeof unsafeWindow.dispatchEvent === 'function') {
                    const events = ['mousemove', 'keydown', 'mousedown'];
                    events.forEach(eventName => {
                        setInterval(() => {
                            try {
                                const event = new Event(eventName, { bubbles: true });
                                unsafeWindow.dispatchEvent(event);
                            } catch (innerErr) {
                                // 忽略错误,继续执行
                            }
                        }, 30000); // 每30秒模拟一次活动
                    });
                }
            }
            
            showNotification('多端监控已尝试禁用', 'success');
        } catch (e) {
            console.log('禁用多端监控失败:', e);
        }
    }

    // 检查是否在视频页面
    function isVideoPage() {
        try {
            const url = window.location.href.toLowerCase();
            const videoPagePatterns = [
                /video/, /course\/video/, /watch/, /learnvideo/, 
                /ananas/, /knowledge/, /play/, /chapter/,
                /lesson/, /courseware/, /content/, /player/,
                /学习/, /课程/, /视频/, /讲课/
            ];
            
            // 检查URL是否匹配视频页面模式
            for (const pattern of videoPagePatterns) {
                if (pattern.test(url)) {
                    return true;
                }
            }
            
            // 检查页面中是否有视频元素或视频播放器
            return document.querySelectorAll('video, .video-player, .player-container, [class*="video"][class*="player"]').length > 0;
        } catch (e) {
            console.error('检查是否视频页面失败:', e);
            return false;
        }
    }

    // 初始化函数
    function init() {
        try {
            // 注册(不可用)菜单项
            GM_registerMenuCommand('显示控制面板', createControlPanel);
            GM_registerMenuCommand('刷新视频检测', handleVideo);
            GM_registerMenuCommand('跳转到下一节', tryNavigateToNextTask);

            // 添加样式
            GM_addStyle(`
                /* 控制面板样式 */
                #shtvu-auto-play-panel {
                    position: fixed;
                    top: 50%;
                    left: 50%;
                    transform: translate(-50%, -50%);
                    width: 350px;
                    background: #fff;
                    border-radius: 8px;
                    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
                    z-index: 9999;
                    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Microsoft YaHei', sans-serif;
                }
                
                .shtvu-panel-header {
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    padding: 15px 20px;
                    background: #1890ff;
                    color: white;
                    border-radius: 8px 8px 0 0;
                }
                
                .shtvu-panel-header h3 {
                    margin: 0;
                    font-size: 16px;
                    font-weight: 500;
                }
                
                #shtvu-close-panel {
                    background: none;
                    border: none;
                    color: white;
                    font-size: 24px;
                    cursor: pointer;
                    padding: 0;
                    width: 24px;
                    height: 24px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    border-radius: 50%;
                    transition: background 0.2s;
                }
                
                #shtvu-close-panel:hover {
                    background: rgba(255, 255, 255, 0.2);
                }
                
                .shtvu-panel-body {
                    padding: 20px;
                }
                
                .shtvu-control-item {
                    margin-bottom: 12px;
                }
                
                .shtvu-control-item label {
                    display: flex;
                    align-items: center;
                    cursor: pointer;
                    font-size: 14px;
                    color: #333;
                }
                
                .shtvu-control-item input[type="checkbox"] {
                    margin-right: 8px;
                    width: 16px;
                    height: 16px;
                    cursor: pointer;
                }
                
                .shtvu-control-item select {
                    margin-left: 8px;
                    padding: 4px 8px;
                    border: 1px solid #d9d9d9;
                    border-radius: 4px;
                    font-size: 14px;
                    cursor: pointer;
                }
                
                .shtvu-contact-info {
                    margin-top: 15px;
                    padding: 10px;
                    background: #f0f0f0;
                    border-radius: 4px;
                    text-align: center;
                }
                
                .shtvu-contact-info p {
                    margin: 0;
                    font-size: 13px;
                    color: #666;
                }
                
                .shtvu-panel-footer {
                    margin-top: 15px;
                    display: flex;
                    justify-content: space-between;
                    gap: 10px;
                }
                
                .shtvu-panel-footer button {
                    flex: 1;
                    padding: 8px 12px;
                    background: #1890ff;
                    color: white;
                    border: none;
                    border-radius: 4px;
                    cursor: pointer;
                    font-size: 13px;
                    transition: background 0.2s;
                }
                
                .shtvu-panel-footer button:hover {
                    background: #40a9ff;
                }
                
                /* 通知样式 */
                .shtvu-notification {
                    position: fixed;
                    top: 20px;
                    right: 20px;
                    padding: 12px 20px;
                    background: #333;
                    color: white;
                    border-radius: 4px;
                    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
                    z-index: 10000;
                    font-size: 14px;
                    transition: all 0.3s ease;
                }
                
                .notification-success {
                    background: #52c41a;
                }
                
                .notification-error {
                    background: #ff4d4f;
                }
                
                .notification-info {
                    background: #1890ff;
                }
                
                .shtvu-notification.fade-out {
                    opacity: 0;
                    transform: translateY(-10px);
                }
            `);

            // 初始化检查和处理
            if (isVideoPage()) {
                // 初始处理视频
                handleVideo();
                setupVideoEndDetection();
                
                // 处理可能的视频播放器加载延迟
                setTimeout(() => {
                    handleVideo();
                    setupVideoEndDetection();
                }, 3000);
                
                setTimeout(() => {
                    handleVideo();
                    setupVideoEndDetection();
                }, 8000);
            }

            // 启用多端监控禁用功能(如果配置启用)
            if (config.disableMonitor) {
                disableMultiDeviceMonitor();
            }

            // 监听页面变化
            const observer = new MutationObserver(() => {
                if (isVideoPage()) {
                    handleVideo();
                    setupVideoEndDetection();
                }
            });

            observer.observe(document.body, {
                childList: true,
                subtree: true
            });

            console.log('上海开放大学视频助手已启动');
        } catch (e) {
            console.error('脚本初始化失败:', e);
        }
    }

    // 启动脚本
    init();
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址