您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
学习通课程自动挂机,当前脚本支持课程视频播放完成,自动跳转下一小节,章节测试自动跳过,后台播放防止视频暂停。
当前为
// ==UserScript== // @name 学习通刷课助手-自动静音,防止鼠标移出暂停,章节结束自动跳转下一节 // @namespace http://tampermonkey.net/ // @version 0.0.7 // @description 学习通课程自动挂机,当前脚本支持课程视频播放完成,自动跳转下一小节,章节测试自动跳过,后台播放防止视频暂停。 // @author Sweek // @match *://*.chaoxing.com/* // @license GPLv3 // @icon https://www.google.com/s2/favicons?sz=64&domain=csdn.net // @grant unsafeWindow // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @require https://code.jquery.com/jquery-2.1.4.min.js // ==/UserScript== // 定义全局变量 let currentTime = null // 当前视频当前播放节点 let duration = null // 当前视频总长度 let progress = null // 当前视频播放进度 let playbackRate = 1 // 当前视频播放倍速 // 课程章节相关数据 let courseName = null // 当前课程名称 let chapterInfo = [] // 当前课程所有章节数据 let currentChapterId = null // 当前所在章节id let currentChapterName = null // 当前所在章节名称 let allChapterName = [] // 所有章节名称 let currentChapterTabArr = [] // 当前页面所有的分栏 let currentChapterTabName = '' // 当前页面激活的分栏名称 let videoProgressId = '' // 定时监听页面内容监听事件 // 获取当前页面的 URL url = '' chapterId = '' // 页面样式 var popCSs = ` #my-window { position: fixed; top: 5px; left: 20px; width: 300px; height: auto; background-color: rgba(247, 247, 247, 1); border: 1px solid #fff; border-radius: 5px; z-index: 9999; overflow: hidden; } #my-window .header { background-color: #4497fa; color: #fff; padding: 5px; font-size: 16px; font-family: 'fangsong'; font-weight: bold; border-radius: 5px; cursor: move; height: 25px; width: 300px; } #my-window .content { width: 300px; height: 500px; } #my-window .content .content-title { height: 22px; width: 280px; background-color: #dadada; line-height: 22px; padding-left: 5px; font-size: 12px; font-family: 'fangsong'; font-weight: 600; boder-radius: 5px; border-left: 4px solid #2196f3; border-right: 4px solid #dadada; margin-top: 5px; } #my-window .content .content-notice { height: 80px; width: 280px; overflow: auto; border: 1px solid gray; border-radius: 5px; padding: 5px; margin-top: 5px; } #my-window .content .content-process { height: 60px; width: 280px; overflow: auto; border: 1px solid gray; border-radius: 5px; padding: 5px; margin-top: 5px; } #my-window .content .content-log { height: 120px; width: 280px; overflow: auto; border: 1px solid gray; border-radius: 5px; padding: 5px; margin-top: 5px; } #my-window .content .content-set { height: 55px; width: 280px; overflow: auto; border: 1px solid gray; border-radius: 5px; padding: 5px; margin-top: 5px; } #my-window .resizer { position: absolute; bottom: 0; right: 0; width: 20px; height: 20px; background-color: #2196f3; cursor: se-resize; border-radius: 0px; z-index: 1; } #hide-btn { height: 25px; width: auto; float: right; margin-right: 10px; background-color: #fff; border: 1px solid gray; border-radius: 5px; font-size: 12px; padding: 0 5px; font-family: 'fangsong'; } #hide-btn:active { background-color: #4497fa; } ` // 页面Html var popHtml = ` <div class="header">学习通助手 <button id="hide-btn">显示/隐藏</button> </div> <div class="content" id="my-window-content"> <div class="resizer" style="display: none;"></div> <div class="row" style="border: 1px solid #ccc; padding: 5px;"> <div class="content-title">公告</div> <div class="content-notice" id="content-notice"> </div> <div class="content-title">播放进度</div> <div class="content-process" id="content-process"></div> <div class="content-title">执行日志</div> <div class="content-log" id="content-log"></div> <div class="content-title">配置</div> <div class="content-set" id="content-set"> 开发中... </div> </div> </div> ` // 开始播放视频 function startVideo() { setTimeout(function() { if(location.pathname === '/ananas/modules/video/index.html') { var video = document.querySelector('video'); if (video) { video.volume = 0; // 将声音调节至0 addlog('已将视频声音调至0') addlog('当前视频倍速为' + video.playbackRate) if (video) { video.play(); addlog('视频开始播放') } } } }, 2000); } // 获取视频播放进度-定时监听页面内容进行下一步处理 function getVideoProgress() { var video = null // console.log('location.pathname:::+ ', location.pathname) getSubChapter() // 学习目标模块显示时 if(location.pathname === '/mycourse/studentstudy') { var studyModel = window.top.document.querySelector('#dct1') var ifStudyModel = studyModel.classList.contains('active') && studyModel.getAttribute('title') === '学习目标' if (ifStudyModel) { addlog('当前小节为学习目标,自动跳过') return toNextChapter() } } // 章节测试模块显示时 if(location.pathname === '/ananas/modules/work/index.html') { addlog('当前小节为章节测试,自动跳过') return toNextChapter() } // 章节小节模块显示时 if(location.pathname === '/ananas/modules/questionnaire/index.html') { addlog('当前小节为章节小节,自动跳过') return toNextChapter() } // 阅读模块显示时 if (location.pathname === '/mooc-ans/coursedata/readjobv2/show') { addlog('当前小节为阅读,自动跳过') return toNextChapter() } // 调查问卷模块显示时 if (location.pathname === '/ananas/modules/zt/vote/index-pc-new.html') { addlog('当前小节为调查问卷,课程已结束') // 清除定时器任务 clearInterval(videoProgressId); addlog('脚本已终止') return toNextChapter() } // 视频模块显示时 if(location.pathname === '/ananas/modules/video/index.html') { video = document.querySelector('video'); if (video) { // currentTime = video.currentTime; // 当前播放时间(以秒为单位) // duration = video.duration; // 视频总时长(以秒为单位) // if (!isNaN(duration)) { // 检查视频总时长是否可用 // progress = (currentTime / duration) * 100; // 计算播放进度百分比 // // console.log('progress:::+ ', progress) // // console.log('当前播放进度:' + progress.toFixed(2) + '%' + ';' + '视频时长' + currentTime.toFixed(0) + 's' + '/' + duration.toFixed() + 's'); // // addlog('当前播放进度:' + progress.toFixed(2) + '%' + ';' + '视频时长' + currentTime.toFixed(0) + 's' + '/' + duration.toFixed() + 's') // } } } else if (currentChapterTabName.length > 1 && currentChapterTabName.indexOf("视频") === -1) { if(location.pathname == '/mycourse/studentstudy') { // console.log('currentChapterTabName:::+ ', currentChapterTabName) addlog('当前小节为非视频内容:' + currentChapterTabName + ',自动跳过') return toNextChapter() } } } // 定时处理监听视频事件 function setIntervalStart() { if (location.pathname === '/ananas/modules/video/index.html') { let video = document.querySelector('video'); let intervalId; function restartVideo() { if (video && video.paused && video.currentTime < video.duration) { video.play(); // 重新开始播放 } } function goToNextChapter() { clearInterval(intervalId); // 清除定时器 addlog('当前视频观看进度为100%,自动跳转到下一小节'); toNextChapter(); } function handleErrors() { clearInterval(intervalId); // 清除定时器 addlog('遇到错误,页面将刷新'); location.reload(); // 刷新页面 } // 处理视频暂停 video.addEventListener("pause", restartVideo); // 处理视频观看完成 video.addEventListener("timeupdate", function() { let currentTime = video.currentTime; // 当前播放时间(以秒为单位) let duration = video.duration; // 视频总时长(以秒为单位) let progress = (currentTime / duration) * 100; // 计算播放进度百分比 setVideoProcess(progress.toFixed(2) + '%', currentTime.toFixed(0), duration.toFixed(0)); // 设置视频播放进度显示 // 如果播放进度大于等于100%,则跳转到下一章节 if (progress >= 100) { goToNextChapter(); } }); // 定期检查视频是否出现错误 intervalId = setInterval(function() { if (video.error) { handleErrors(); } }, 10000); // 每秒检查一次 } } // 跳转到下一章节 function toNextChapter() { var nextButton = window.top.document.querySelector('#prevNextFocusNext'); // console.log('nextButton:::+ ', nextButton) if (nextButton) { nextButton.click(); } } // 获取页面url function getURLInfo() { if(location.pathname == '/mycourse/studentstudy') { url = location.href // console.log('url:::+ ', url) // 获取问号后面的部分 var queryString = url.split('?')[1]; // 将查询字符串拆分为参数对 var queryParams = queryString.split('&'); // 创建一个对象来存储参数 var params = {}; // 遍历参数对,将它们存储在对象中 queryParams.forEach(function(queryParam) { var parts = queryParam.split('='); var key = decodeURIComponent(parts[0]); var value = decodeURIComponent(parts[1]); params[key] = value; }); chapterId = params['chapterId'] } } // 初始化添加页面弹窗以及悬浮球 function initPopup() { // 添加CSS样式 GM_addStyle(popCSs); // 创建窗口元素 const myWindow = document.createElement("div"); myWindow.id = "my-window"; myWindow.innerHTML = popHtml; // 获取页面body元素 const body = document.getElementsByTagName("body")[0]; // 添加窗口和悬浮球到页面 body.appendChild(myWindow); // 绑定隐藏窗口按钮的click事件 const hideBtn = document.querySelector("#hide-btn"); hideBtn.addEventListener("click", hideWindow); // 获取头部元素 const header = myWindow.querySelector('.header'); // 获取调整大小元素 const resizer = myWindow.querySelector('.resizer'); // 处理调整大小事件 resizer.addEventListener('mousedown', function (e) { e.preventDefault(); const { left, top, width, height } = myWindow.getBoundingClientRect(); const startX = e.clientX; const startY = e.clientY; function onMouseMove(e) { const newWidth = Math.max(200, width + (e.clientX - startX)); const newHeight = Math.max(100, height + (e.clientY - startY)); myWindow.style.width = newWidth + 'px'; myWindow.style.height = newHeight + 'px'; } function onMouseUp() { window.removeEventListener('mousemove', onMouseMove); window.removeEventListener('mouseup', onMouseUp); } window.addEventListener('mousemove', onMouseMove); window.addEventListener('mouseup', onMouseUp); }); // 处理移动事件 let isDragging = false; let mouseX = 0; let mouseY = 0; header.addEventListener('mousedown', function (e) { e.preventDefault(); isDragging = true; mouseX = e.clientX; mouseY = e.clientY; }); document.addEventListener('mousemove', function (e) { if (isDragging) { const deltaX = e.clientX - mouseX; const deltaY = e.clientY - mouseY; const newLeft = myWindow.offsetLeft + deltaX; const newTop = myWindow.offsetTop + deltaY; myWindow.style.left = newLeft + 'px'; myWindow.style.top = newTop + 'px'; mouseX = e.clientX; mouseY = e.clientY; } }); document.addEventListener('mouseup', function (e) { isDragging = false; }); } // 隐藏窗口函数 function hideWindow() { var myWindowContent = document.getElementById("my-window-content"); var showPop = myWindowContent.style.display if (showPop == '' || showPop == 'block') { myWindowContent.style.display = "none"; } else { myWindowContent.style.display = "block"; } } // 获取当前页面章节小节的所有分栏 function getSubChapter() { try { if(location.pathname == '/mycourse/studentstudy') { var subChapter = window.top.document.querySelector('#prev_tab'); currentChapterTabArr = subChapter.querySelectorAll('li'); // console.log('currentChapterTabArr:::+ ', currentChapterTabArr) currentChapterTabArr.forEach(function(item) { if(item.className === 'active') { currentChapterTabName = item.innerText } }) // console.log('currentChapterTabName:::+ ', currentChapterTabName) } } catch (error) { console.error('An error occurred:', error); location.reload(); // 刷新页面 } } // 获取课程所有章节节点数据 function getChapterCodeInfo() { // console.log('location.pathname:::+ ', location.pathname) if(location.pathname === '/mooc-ans/knowledge/cards') { var chapter = window.top.document.querySelectorAll('.posCatalog_select') chapterInfo = chapter // console.log('chapterInfo:::+ ', chapterInfo) chapterInfo.forEach(function(item) { // console.log(item); allChapterName.push({ id: item.id, title: item.innerText, active: item.classList.contains('posCatalog_active') ? 1 : 0, ifTitle: item.classList.contains('firstLayer') ? 1 : 0, status: item.childNodes[3]?.className == 'icon_Completed prevTips' ? 1 : 0 }) if (item.classList.contains('posCatalog_active')) { currentChapterId = item.id currentChapterName = item.innerText } }); // console.log('currentChapterId:::+ ', currentChapterId) // console.log('currentChapterName:::+ ', currentChapterName) // console.log('allChapterName:::+ ', allChapterName) addlog('当前章节为' + currentChapterName, 'green') } } // 获取公告数据 function getBoard() { fetch('https://www.sweek.online/api/board') .then(response => response.json()) .then(data => { // 在这里处理接收到的数据 // console.log(data); var notice = document.querySelector('#content-notice'); notice.innerHTML = data.text }) .catch(error => { // 在这里处理错误 console.error('Error:', error); }); } // 设置播放进度 function setVideoProcess(val1, val2, val3) { var _process = window.top.document.querySelector('#content-process'); var _time = new Date().toLocaleTimeString() var newContent = '<p style="color: #000;">[' + _time + ']' + '</p><hr><p>' + '播放进度:' + val1 + '</p><hr><p>' + '视频长度:' + val2 + 's' + '/' +val3 + 's' + '</p>'; _process.innerHTML = newContent; } // 页面通知提示 // 页面通知提示 function notify(text, time) { // 创建通知元素 var notification = document.createElement('div'); notification.className = 'notification'; // 设置通知内容 notification.innerHTML = '<div class="notification-content"><h2 style="font-size: 16px;font-weight: bold;color: #307dff;font-family: fangsong;">' + '学习通助手提示' + '</h2><p style="font-family: fangsong;font-size: 13px;font-weight: bold;">' + text + '</p></div>'; // 将通知添加到页面中 document.body.appendChild(notification); // 设置通知样式 notification.style.position = 'fixed'; notification.style.top = '50px'; notification.style.left = '-400px'; // 从左边弹出 notification.style.transform = 'translateY(-50%)'; // 垂直居中 notification.style.transition = 'left 0.5s ease-in-out'; // 添加过渡效果 notification.style.zIndex = '999999'; notification.style.backgroundColor = '#fff'; notification.style.border = '1px solid #ccc'; notification.style.padding = '10px'; notification.style.borderRadius = '5px'; notification.style.lineHeight = '25px'; // 等待一小段时间后,移动通知到左边 setTimeout(function() { notification.style.left = '20px'; // 移动到左边 }, 100); // 设置定时器,在指定时间后移除通知 setTimeout(function() { // 移动通知到左边以外 notification.style.left = '-400px'; // 等待过渡效果完成后,移除通知元素 setTimeout(function() { notification.remove(); }, 500); }, time); } // 添加执行日志 function addlog(str, color) { var _time = new Date().toLocaleTimeString() var contentLog = window.top.document.querySelector('.content-log'); // console.log('contentLog:::+ ', contentLog) var newContent = '<p style="color: ' + color + ';">[' + _time + ']' + str + '</p><hr>'; contentLog.innerHTML += newContent; // 将滚动条滚动到底部 contentLog.scrollTop = contentLog.scrollHeight; } // 方法执行入口 (function () { // console.log('location.pathname:::+ ', location.pathname) // 进入学习通弹出提示 if(location.pathname == '/base') { notify('已进入学习通首页,请进入课程,选择需要学习的课程', 5000) } // 进入课程弹出提示 if(location.pathname == '/mooc2-ans/mycourse/stu') { courseName = window.top.document.querySelector('.classDl .colorDeep').getAttribute('title') notify('已进入课程:' + courseName + ',请选择需要学习的章节', 5000) } // 初始化显示页面弹窗 if(location.pathname == '/mycourse/studentstudy') { initPopup() // 获取公告数据 getBoard() } // 获取页面章节节点数据 getChapterCodeInfo() // 获取当前页面章节小节的所有分栏 getSubChapter() // 获取页面url信息 getURLInfo() // 开始播放视频 startVideo() // 定时处理监听视频事件 setTimeout(() => { setIntervalStart() }, 2000); // 定时打印视频播放进度-定时监听页面内容进行下一步处理 videoProgressId = setInterval(() => { getVideoProgress() }, 5000); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址