您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
自动识别课程并挂机播放视频,完成指定学时自动跳转下一门课程。
// ==UserScript== // @name 国家智慧教育公共服务平台 | 高等教育教师专业发展 | 2025年暑期教师研修 | 自动挂机 // @version 2025.07.31 // @description 自动识别课程并挂机播放视频,完成指定学时自动跳转下一门课程。 // @author FlowPeakFish // @match https://core.teacher.vocational.smartedu.cn/p/course/* // @icon https://teacher.vocational.smartedu.cn/favicon.ico // @grant GM_setValue // @grant GM_getValue // @license MIT // @namespace https://greasyfork.org/users/1497801 // ==/UserScript== // ============================== // 🔧 课程名称与链接配置 // ============================== const courseTitles = [ "大力弘扬教育家精神", "数字素养提升", "科学素养提升", "心理健康教育能力提升", "教学科研能力提升" ]; const courseLinks = [ "https://core.teacher.vocational.smartedu.cn/p/course/vocational/v_1006809341534883840?itemId=1003784879729774592&type=1&segId=1003784832051576832&projectId=1003784624690925568&orgId=608196190709395456&originP=1", "https://core.teacher.vocational.smartedu.cn/p/course/vocational/v_1006809341547466752?itemId=1003784976377577472&type=1&segId=1003784928350146560&projectId=1003784624690925568&orgId=608196190709395456&originP=1", "https://core.teacher.vocational.smartedu.cn/p/course/vocational/v_1006809341560049664?itemId=1003785080355917824&type=1&segId=1003785029070618624&projectId=1003784624690925568&orgId=608196190709395456&originP=1", "https://core.teacher.vocational.smartedu.cn/p/course/vocational/v_1006809341572632576?itemId=1003785177923817472&type=1&segId=1003785131789123584&projectId=1003784624690925568&orgId=608196190709395456&originP=1", "https://core.teacher.vocational.smartedu.cn/p/course/vocational/v_1006809341585215488?itemId=1003785287292944384&type=1&segId=1003785243122728960&projectId=1003784624690925568&orgId=608196190709395456&originP=1", "https://teacher.higher.smartedu.cn/h/subject/summer2025/", ]; // 每门课程所需学时(单位:学时,1 学时 = 45 分钟) const courseRequiredPeriods = [2, 2, 1, 2, 3]; // ============================== // 🚀 脚本入口:识别课程并启动定时器 // ============================== (function () { 'use strict'; const currentURL = window.location.href; // 只在课程播放页执行 if (currentURL.includes("/p/course/vocational/v")) { const courseTitle = document.querySelector("h1")?.textContent?.trim(); if (courseTitle) { const index = courseTitles.findIndex(t => courseTitle.includes(t)); if (index !== -1) { GM_setValue("下标", index); createLogBox(); addLog(`✅ 识别课程标题:${courseTitle}(第 ${index+1} 个课程)`); setInterval(mainLoop, 5000); } else { createLogBox(); addLog(`⚠️ 未匹配课程标题:${courseTitle}`); } } else { createLogBox(); addLog(`⚠️ 页面未找到课程标题(h1 标签)`); } } })(); // ============================== // 🎬 主执行循环函数 // ============================== function mainLoop() { switchToNextUnfinishedVideo(); ensureVideoIsPlaying(); checkIfStudyTimeComplete(); clickConfirmIfPopupVisible(); } // ============================== // 🎯 切换下一个未播放完的视频 // ============================== function switchToNextUnfinishedVideo() { const current = document.querySelector('.video-title.clearfix.on .four')?.textContent; if (current === '100%') { const all = document.getElementsByClassName('video-title clearfix'); for (let i = 1; i < all.length; i++) { const four = all[i].querySelector('.four')?.textContent; if (four !== '100%') { all[i].click(); addLog(`➡️ 切换至未完成视频:第 ${i + 1} 个`); break; } } } } // ============================== // ⏱️ 学时统计与自动跳转下一门课 // ============================== function checkIfStudyTimeComplete() { const index = GM_getValue("下标"); const requiredPeriods = courseRequiredPeriods[index]; // 学时 const videoDivs = document.getElementsByClassName("video-title"); let totalSeconds = 0; for (let videoDiv of videoDivs) { const percent = videoDiv.querySelector(".four")?.textContent?.trim(); const time = videoDiv.querySelector(".three")?.textContent?.trim(); if (percent === "100%" && time) { const [hh, mm, ss] = time.replace(/[()]/g, "").split(":").map(Number); totalSeconds += hh * 3600 + mm * 60 + ss; } } const completedPeriods = totalSeconds / 2700; // ✅ 1 学时 = 2700 秒 = 45 分钟 addLog(`⏳ 当前已完成 ${(completedPeriods).toFixed(2)} 学时 / 目标 ${requiredPeriods} 学时`); if (completedPeriods >= requiredPeriods) { const nextIndex = index + 1; if (courseLinks[nextIndex]) { GM_setValue("下标", nextIndex); addLog(`✅ 学时达标,准备跳转下一课程:下标 ${nextIndex}`); setTimeout(() => { window.location.href = courseLinks[nextIndex]; }, 500); } else { addLog("🎉 所有课程已完成!"); } } } // ============================== // 📺 强制播放视频(静音避免浏览器限制) // ============================== function ensureVideoIsPlaying() { const video = document.querySelector("#video-Player > video"); if (!video) { addLog("⚠️ 未找到视频元素"); return; } // 如果没有静音,自动设置为静音 if (!video.muted) { video.muted = true; addLog("🔇 自动设置为静音"); } // 如果播放速率为 1,则改为 2 if (video.playbackRate === 1) { video.playbackRate = 2; addLog("⏩ 播放速率设置为 2 倍速"); } if (!video.paused) { addLog("📡 正在挂机中..."); return; } video.play().then(() => { addLog("🎬 视频恢复播放"); }).catch(err => { addLog("⚠️ 视频播放失败:" + err.message); }); } // ============================== // ✅ 弹窗检测与“确定”按钮点击处理 // ============================== function clickConfirmIfPopupVisible() { const confirmBtn = document.querySelector(".layui-layer-btn .layui-layer-btn0"); if (confirmBtn) { confirmBtn.click(); addLog("🧩 检测到弹窗,已自动点击“确定”按钮"); } } // ============================== // 🪵 日志输出框与记录函数 // ============================== function createLogBox() { const box = document.createElement('div'); box.id = 'logBox'; Object.assign(box.style, { position: 'fixed', bottom: '20px', left: '20px', width: '420px', height: '260px', backgroundColor: 'rgba(0, 0, 0, 0.85)', color: '#00FF00', border: '2px solid #00FF00', borderRadius: '10px', boxShadow: '0 0 10px #00FF00', overflowY: 'auto', padding: '12px', fontFamily: 'monospace', fontSize: '14px', zIndex: '99999', lineHeight: '1.5', whiteSpace: 'pre-wrap', wordBreak: 'break-word', }); box.innerHTML = `<div style="font-weight:bold;font-size:16px;margin-bottom:8px;color:#00FFFF; border-bottom:1px solid #00FF00;padding-bottom:4px">📋 智慧教育挂机日志</div>`; const style = document.createElement('style'); style.textContent = ` #logBox::-webkit-scrollbar { width: 8px; } #logBox::-webkit-scrollbar-thumb { background: #00ff00; border-radius: 4px; box-shadow: inset 0 0 6px rgba(0,255,0,0.5); } #logBox::-webkit-scrollbar-track { background: rgba(0, 0, 0, 0.3); } `; document.head.appendChild(style); document.body.appendChild(box); } function addLog(message) { const log = document.getElementById('logBox'); if (!log) return; const time = new Date().toLocaleTimeString('zh-CN', { hour12: false }); const line = document.createElement('div'); line.textContent = `[${time}] ${message}`; log.appendChild(line); log.scrollTop = log.scrollHeight; console.log(`[${time}] ${message}`); }