From f37c6445d1df70313df3eff3590bef497d94402d Mon Sep 17 00:00:00 2001 From: jinglekang Date: Wed, 3 Jun 2026 15:06:57 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=AF=BE=E7=A8=8B=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=E9=80=BB=E8=BE=91=EF=BC=8C=E5=A2=9E=E5=8A=A0=E7=AD=89?= =?UTF-8?q?=E5=BE=85=E6=9D=A1=E4=BB=B6=E5=A4=84=E7=90=86=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E8=A7=86=E9=A2=91=E6=92=AD=E6=94=BE=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qingshuxuetang_auto_play.user.js | 219 ++++++++++++++++--------------- 1 file changed, 116 insertions(+), 103 deletions(-) diff --git a/qingshuxuetang_auto_play.user.js b/qingshuxuetang_auto_play.user.js index b288664..b7f4cdf 100644 --- a/qingshuxuetang_auto_play.user.js +++ b/qingshuxuetang_auto_play.user.js @@ -1,24 +1,48 @@ -// ==UserScript== -// @name 平顶山学院(青书学堂)自动学习脚本 -// @namespace http://tampermonkey.net/ +// ==UserScript== +// @name 平顶山学院(青书学堂)自动学习脚本 +// @namespace http://tampermonkey.net/ // @version 2026-06-03 -// @description try to take over the world! -// @author You -// @match https://degree.qingshuxuetang.com/pdsu/Student/Course/CourseStudy* -// @match https://degree.qingshuxuetang.com/pdsu/Student/Course/CourseShow* -// @icon https://www.google.com/s2/favicons?sz=64&domain=qingshuxuetang.com -// @grant none -// ==/UserScript== - -(function () { - "use strict"; - +// @description try to take over the world! +// @author You +// @match https://degree.qingshuxuetang.com/pdsu/Student/Course/CourseStudy* +// @match https://degree.qingshuxuetang.com/pdsu/Student/Course/CourseShow* +// @icon https://www.google.com/s2/favicons?sz=64&domain=qingshuxuetang.com +// @grant none +// ==/UserScript== + +(function () { + "use strict"; + const url = window.location.href; const MIN_STUDY_SECONDS = 5 * 60; - const COURSEWARE_DETECT_TIMEOUT_SECONDS = 60; - const TEXT_COURSEWARE_SELECTOR = "#easyXDM_default2872_provider"; + const VIDEO_SELECTOR = "#vjs_video_3_html5_api"; + const TEXT_SELECTOR = "#easyXDM_default2872_provider"; console.log("插件加载完成,等待界面渲染"); + const waitForCondition = (getResult) => { + const result = getResult(); + + if (result) { + return Promise.resolve(result); + } + + return new Promise((resolve) => { + const observer = new MutationObserver(() => { + const result = getResult(); + + if (result) { + observer.disconnect(); + resolve(result); + } + }); + + observer.observe(document.documentElement, { + childList: true, + subtree: true, + }); + }); + }; + const parseStudySeconds = (text) => { const hourMatch = text.match(/(\d+)\s*小时/); const minuteMatch = text.match(/(\d+)\s*分钟/); @@ -52,103 +76,92 @@ history.back(); }; - - const onPageLoad = () => { - console.log("页面加载完成,开始执行脚本"); - - if (url.includes("CourseStudy")) { - console.log("进入准备阶段"); - // 等待3秒后点击下一个未播放的视频 - setTimeout(() => { - // 准备阶段 - const list = document.querySelector("#list"); - if (!list) { - console.error("课程列表未找到,结束脚本"); - return; - } - const items = list.querySelectorAll("li > a.node"); - console.log("获取到课程数量:", items.length); - - if (items.length === 0) { - console.error("课程数量为空,结束脚本"); - return; - } - for (const item of items) { - if (shouldEnterCourseware(item)) { - const mark = item.querySelector(".study_being"); - const studiedSeconds = mark ? parseStudySeconds(mark.innerText) : 0; - console.log( - "点击未完成学习时长的视频:" + - item.querySelector(".title").innerText + - ",已学习:" + - studiedSeconds + - "秒" - ); - item.click(); - return; - } - } - console.log("所有视频均已播放完毕,结束脚本"); - }, 3000); + + const waitForCoursewareElement = () => + waitForCondition( + () => + document.querySelector(VIDEO_SELECTOR) || + document.querySelector(TEXT_SELECTOR) + ); + + const onPageLoad = async () => { + console.log("页面加载完成,开始执行脚本"); + + if (url.includes("CourseStudy")) { + console.log("进入准备阶段"); + const items = await waitForCondition(() => { + const list = document.querySelector("#list"); + const items = list ? list.querySelectorAll("li > a.node") : []; + + return items.length > 0 ? items : null; + }); + + console.log("获取到课程数量:", items.length); + + for (const item of items) { + if (shouldEnterCourseware(item)) { + const mark = item.querySelector(".study_being"); + const studiedSeconds = mark ? parseStudySeconds(mark.innerText) : 0; + console.log( + "点击未完成学习时长的视频:" + + item.querySelector(".title").innerText + + ",已学习:" + + studiedSeconds + + "秒" + ); + item.click(); + return; + } + } + console.log("所有视频均已播放完毕,结束脚本"); } else if (url.includes("CourseShow")) { console.log("进入学习阶段"); // 学习阶段 - const showPageStartedAt = Date.now(); + const coursewareElement = await waitForCoursewareElement(); + + if (coursewareElement.matches(TEXT_SELECTOR)) { + console.log("检测到文本课件,等待5分钟后返回准备页面"); + setTimeout(() => { + console.log("文本课件等待完成,返回准备页面"); + returnToStudyPage(); + }, MIN_STUDY_SECONDS * 1000); + return; + } + const videoInterval = setInterval(() => { - const video = document.querySelector("#vjs_video_3_html5_api"); + const video = document.querySelector(VIDEO_SELECTOR); if (!video) { - const textCourseware = document.querySelector(TEXT_COURSEWARE_SELECTOR); - - if (textCourseware) { - console.log("检测到文本课件,等待5分钟后返回准备页面"); - clearInterval(videoInterval); - setTimeout(() => { - console.log("文本课件等待完成,返回准备页面"); - returnToStudyPage(); - }, MIN_STUDY_SECONDS * 1000); - return; - } - - if ( - Date.now() - showPageStartedAt > - COURSEWARE_DETECT_TIMEOUT_SECONDS * 1000 - ) { - console.error("视频和文本课件元素均未找到,结束脚本"); - clearInterval(videoInterval); - return; - } - - console.log("课件元素尚未渲染完成,继续等待"); + console.log("视频元素暂时不可用,继续等待"); return; } - - if (video.paused && video.currentTime === 0) { - video.play(); - console.log("视频未播放,开始播放视频"); - return; - } - + + if (video.paused && video.currentTime === 0) { + video.play(); + console.log("视频未播放,开始播放视频"); + return; + } + if (video.currentTime >= video.duration - 1) { console.log("视频播放结束,返回准备页面"); clearInterval(videoInterval); returnToStudyPage(); } - - if (video.playbackRate === 1) { - console.log("将视频倍速设置为2倍速"); - video.playbackRate = 2; - } - - console.log("视频正在播放,当前时间:" + video.currentTime); - }, 3000); - } - }; - - // 等待页面加载完成后执行 - if (document.readyState === "complete") { - onPageLoad(); - } else { - window.addEventListener("load", onPageLoad); - } -})(); + + if (video.playbackRate === 1) { + console.log("将视频倍速设置为2倍速"); + video.playbackRate = 2; + } + + console.log("视频正在播放,当前时间:" + video.currentTime); + }, 3000); + } + }; + + // 等待页面加载完成后执行 + if (document.readyState === "complete") { + onPageLoad(); + } else { + window.addEventListener("load", onPageLoad); + } +})();