优化课程加载逻辑,增加等待条件处理,修复视频播放逻辑

This commit is contained in:
竟康 2026-06-03 15:06:57 +08:00
parent 4aed339bfc
commit f37c6445d1
1 changed files with 116 additions and 103 deletions

View File

@ -1,24 +1,48 @@
// ==UserScript== // ==UserScript==
// @name 平顶山学院(青书学堂)自动学习脚本 // @name 平顶山学院(青书学堂)自动学习脚本
// @namespace http://tampermonkey.net/ // @namespace http://tampermonkey.net/
// @version 2026-06-03 // @version 2026-06-03
// @description try to take over the world! // @description try to take over the world!
// @author You // @author You
// @match https://degree.qingshuxuetang.com/pdsu/Student/Course/CourseStudy* // @match https://degree.qingshuxuetang.com/pdsu/Student/Course/CourseStudy*
// @match https://degree.qingshuxuetang.com/pdsu/Student/Course/CourseShow* // @match https://degree.qingshuxuetang.com/pdsu/Student/Course/CourseShow*
// @icon https://www.google.com/s2/favicons?sz=64&domain=qingshuxuetang.com // @icon https://www.google.com/s2/favicons?sz=64&domain=qingshuxuetang.com
// @grant none // @grant none
// ==/UserScript== // ==/UserScript==
(function () { (function () {
"use strict"; "use strict";
const url = window.location.href; const url = window.location.href;
const MIN_STUDY_SECONDS = 5 * 60; const MIN_STUDY_SECONDS = 5 * 60;
const COURSEWARE_DETECT_TIMEOUT_SECONDS = 60; const VIDEO_SELECTOR = "#vjs_video_3_html5_api";
const TEXT_COURSEWARE_SELECTOR = "#easyXDM_default2872_provider"; const TEXT_SELECTOR = "#easyXDM_default2872_provider";
console.log("插件加载完成,等待界面渲染"); 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 parseStudySeconds = (text) => {
const hourMatch = text.match(/(\d+)\s*小时/); const hourMatch = text.match(/(\d+)\s*小时/);
const minuteMatch = text.match(/(\d+)\s*分钟/); const minuteMatch = text.match(/(\d+)\s*分钟/);
@ -52,103 +76,92 @@
history.back(); history.back();
}; };
const onPageLoad = () => { const waitForCoursewareElement = () =>
console.log("页面加载完成,开始执行脚本"); waitForCondition(
() =>
if (url.includes("CourseStudy")) { document.querySelector(VIDEO_SELECTOR) ||
console.log("进入准备阶段"); document.querySelector(TEXT_SELECTOR)
// 等待3秒后点击下一个未播放的视频 );
setTimeout(() => {
// 准备阶段 const onPageLoad = async () => {
const list = document.querySelector("#list"); console.log("页面加载完成,开始执行脚本");
if (!list) {
console.error("课程列表未找到,结束脚本"); if (url.includes("CourseStudy")) {
return; console.log("进入准备阶段");
} const items = await waitForCondition(() => {
const items = list.querySelectorAll("li > a.node"); const list = document.querySelector("#list");
console.log("获取到课程数量:", items.length); const items = list ? list.querySelectorAll("li > a.node") : [];
if (items.length === 0) { return items.length > 0 ? items : null;
console.error("课程数量为空,结束脚本"); });
return;
} console.log("获取到课程数量:", items.length);
for (const item of items) {
if (shouldEnterCourseware(item)) { for (const item of items) {
const mark = item.querySelector(".study_being"); if (shouldEnterCourseware(item)) {
const studiedSeconds = mark ? parseStudySeconds(mark.innerText) : 0; const mark = item.querySelector(".study_being");
console.log( const studiedSeconds = mark ? parseStudySeconds(mark.innerText) : 0;
"点击未完成学习时长的视频:" + console.log(
item.querySelector(".title").innerText + "点击未完成学习时长的视频:" +
",已学习:" + item.querySelector(".title").innerText +
studiedSeconds + ",已学习:" +
"秒" studiedSeconds +
); "秒"
item.click(); );
return; item.click();
} return;
} }
console.log("所有视频均已播放完毕,结束脚本"); }
}, 3000); console.log("所有视频均已播放完毕,结束脚本");
} else if (url.includes("CourseShow")) { } else if (url.includes("CourseShow")) {
console.log("进入学习阶段"); 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 videoInterval = setInterval(() => {
const video = document.querySelector("#vjs_video_3_html5_api"); const video = document.querySelector(VIDEO_SELECTOR);
if (!video) { if (!video) {
const textCourseware = document.querySelector(TEXT_COURSEWARE_SELECTOR); console.log("视频元素暂时不可用,继续等待");
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("课件元素尚未渲染完成,继续等待");
return; return;
} }
if (video.paused && video.currentTime === 0) { if (video.paused && video.currentTime === 0) {
video.play(); video.play();
console.log("视频未播放,开始播放视频"); console.log("视频未播放,开始播放视频");
return; return;
} }
if (video.currentTime >= video.duration - 1) { if (video.currentTime >= video.duration - 1) {
console.log("视频播放结束,返回准备页面"); console.log("视频播放结束,返回准备页面");
clearInterval(videoInterval); clearInterval(videoInterval);
returnToStudyPage(); returnToStudyPage();
} }
if (video.playbackRate === 1) { if (video.playbackRate === 1) {
console.log("将视频倍速设置为2倍速"); console.log("将视频倍速设置为2倍速");
video.playbackRate = 2; video.playbackRate = 2;
} }
console.log("视频正在播放,当前时间:" + video.currentTime); console.log("视频正在播放,当前时间:" + video.currentTime);
}, 3000); }, 3000);
} }
}; };
// 等待页面加载完成后执行 // 等待页面加载完成后执行
if (document.readyState === "complete") { if (document.readyState === "complete") {
onPageLoad(); onPageLoad();
} else { } else {
window.addEventListener("load", onPageLoad); window.addEventListener("load", onPageLoad);
} }
})(); })();