// ==UserScript== // @name 学起Plus挂课自动连续播放 // @namespace http://tampermonkey.net/ // @version 0.15.1 // @description 一个网课挂机自动连续播放工具,仅适用于学起Plus sccchina.net chinaedu.net,反馈与交流QQ群:715307684,更新日期:2022年11月14日 // @author 哆哆啦啦梦 // @match *://*.chinaedu.net/* // @match *://*.sccchina.net/* // @match *://rspcourse.chinaedu.net/* // @match *://*.edu.cn/* // @icon https://www.google.com/s2/favicons?sz=64&domain=chinaedu.net // @grant unsafeWindow // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @license GPLv3 // @downloadURL none // ==/UserScript== const newSupport_20221106 = { lessionInfos: [], currLessionId: "", currLessionType: 0, isSupport: false, getLessions() { // 所有的播放节点并获取其课程名称和id document.querySelectorAll("#catalogDiv h3[onclick]").forEach((e) => this.lessionInfos.push({ ele: e, title: e.innerText, callStr: e.onclick.toString(), }) ); return this.lessionInfos.length; }, getCurr() { // 获取当前播放课程ID this.currLessionId = document.querySelector("#courseActivityId").value; // 查找当前课程ID对应的节点 const index = this.lessionInfos.findIndex( (e) => e.callStr.indexOf(this.currLessionId) > 0 ); // 正则提取类型 const res = this.lessionInfos[index].callStr.match(/\'(\d)\'/); if (res && res.length === 2) { this.currLessionType = res[1]; console.log( `当前播放课程:${this.lessionInfos[index].title},课程类型:${this.currLessionType}` ); return true; } }, playNext() { // 查找当前课程ID对应的节点 const index = this.lessionInfos.findIndex( (e) => e.callStr.indexOf(this.currLessionId) > 0 ); // 判断是否存在下一个课程 if (index + 1 < this.lessionInfos.length) { console.log("下一个播放的课程:", this.lessionInfos[index + 1].title); // 调用播放下一个 this.lessionInfos[index + 1].ele.onclick(); } else { console.log("课程播放结束"); alert("课程播放结束"); } }, playCheck() { // 设置支持 this.isSupport = true; // 挂课弹窗解除 const tips = document.querySelector(".win-content"); if (tips && tips.innerText.indexOf("继续学习") > 0) { const btn = document.querySelector(".win-content .close-win-bt"); btn && btn.click(); } if (this.currLessionType !== "1") { setTimeout(() => { this.playNext(); }, 5000); } else { // 获取视频元素 const video = document.querySelector("video"); // 设置静音 video.muted = true; // 播放速率,可自行修改0.5,1,1.25,1.5,2 video.playbackRate = 1; // 获取当前播放进度和视频长度 保留一位小数 const currentTime = video.currentTime.toFixed(1); const totalTime = video.duration.toFixed(1); console.log(`当前进度:${currentTime}/${totalTime}`); if (currentTime < totalTime - 5) { // 视频没有播放完 if (video.paused) { console.log("视频被暂停,继续播放!"); video.play(); } setTimeout(() => { this.playCheck(); }, 5000); } else { setTimeout(() => { this.playNext(); }, 5000); } } }, work() { setTimeout(() => { this.getLessions() && this.getCurr() && this.playCheck(); }, 5000); }, }; const newSupport_20221116 = { videoModuleInfo: null, lessionsInfo: null, currLessionId: "", stepOne() { setTimeout(() => { this.findLession(); this.checkStatus(); GM_deleteValue("newSupport_20221116.isVideoInPaly"); if (document.querySelector("video")) { GM_setValue("newSupport_20221116.isVideoInPaly", true); this.playCheck(); } }, 5000); }, async checkStatus() { await this.getCurr(); const isGoto = await this.gotoNext(); if (isGoto && GM_getValue("newSupport_20221116.isVideoInPaly")) { this.playCheck(); } setTimeout(() => { this.checkStatus(); }, 5000); }, getLessionsInfo(arr, path = []) { const infos = []; arr.forEach((e) => { if (e.child) { infos.push(...this.getLessionsInfo(e.child, [...path, e.id])); } else { // 添加到数组 infos.push({ ...e, path: [...path, e.id] }); } }); return infos; }, getLessions() { // 处理弹窗 const pop = document.querySelector("#pop"); // 存在就点击关闭按钮 pop && pop.querySelector(".pop_close").click(); // 处理课程信息 if (!courseInfo) { return false; } // 提取课程信息 const lessionInfo = { id: courseInfo.id, name: courseInfo.name, }; console.log(`当前课程:${lessionInfo.name},ID:${lessionInfo.id}`); // 提取课程模块 const module = courseInfo.child.$model; console.log("模块信息:", module); // 查找视频模块索引 const index = module.findIndex( (e) => e.name === "视频学习" || (e.code && e.code === "course") ); // 提取视频模块信息 this.videoModuleInfo = { id: module[index].id, name: module[index].name, }; console.log("视频模块信息:", this.videoModuleInfo); this.lessionsInfo = this.getLessionsInfo(module[index].child); // 提取课程Res console.log("课程章节信息:", this.lessionsInfo); GM_setValue("newSupport_20221116_lessionsInfo", this.lessionsInfo); return true; }, checkCoursePage() { if (this.lessionsInfo && this.lessionsInfo.length) { // 取出第一个 const firstInfo = this.lessionsInfo[0]; // 查询是否元素存在 if (document.querySelector(`li[nid='${firstInfo.id}']`) === null) { // 不存在,代表非视频页 // 获取当前选中的模块 const active = document.querySelector("li.fl.cur"); if (!active || active.getAttribute("nid") !== this.videoModuleInfo.id) { console.log( `当前课程模块不是视频模块!即将转到视频模块,ID:${this.videoModuleInfo.id}` ); // 查找视频模块标签并点击 document .querySelector(`li[nid='${this.videoModuleInfo.id}']`) .click(); } return false; } return true; } return false; }, findLession() { if (this.getLessions()) { if (!this.checkCoursePage()) { // 延迟执行 setTimeout(() => this.findLession, 5000); } else { return true; } } return false; }, stepTwo() { setTimeout(() => { this.playCheck(); }, 10000); }, async getCurr() { return new Promise((reslove) => { // 获取课程内容容器 const courseCon = document.querySelector(".courseCon iframe"); if (courseCon) { // 获取加载的地址 const iframeSrc = courseCon.getAttribute("src"); // 根据src获取对应课程信息 let currInfo = null; this.lessionsInfo.find((item) => item.res.find((e) => { if (decodeURI(iframeSrc).indexOf(decodeURI(e.url)) >= 0) { currInfo = e; } return currInfo; }) ); GM_setValue("newSupport_20221116_currInfo", currInfo); } reslove(); }); }, randomRange(min, max) { return Math.floor(Math.random() * (max - min)) + min; }, clickAutomatic(element) { var _offset = $(element).offset(); var x = 0, y = 0; if (typeof _offset == "undefined") { return; } x = this.randomRange(_offset.left, _offset.left + $(element).width()); y = this.randomRange(_offset.top, _offset.top + $(element).height()); if (x <= 0 || y <= 0 || x >= $(window).width() || y >= $(window).height()) { return; } document.elementFromPoint(x, y).click(); }, async sleep(time = 3) { return new Promise((reslove) => { setTimeout(() => { reslove(); }, time * 1000); }); }, async openMenu(path) { return new Promise(async (reslove) => { for (let i = 0; i < path.length; i++) { const ele = document.querySelector(`li[nid='${path[i]}']`); if (ele && ele.className.indexOf("open") === -1) { document.querySelector(".ps-container").scrollTo(0, ele.offsetTop); await this.sleep(1); this.clickAutomatic(ele); } await this.sleep(3); } reslove(); }); }, async gotoNext() { return new Promise(async (reslove) => { const nextData = GM_getValue("newSupport_20221116_next"); if (nextData) { const { info, pos } = nextData; const nextEle = document.querySelector(`li[nid='${info.id}']`); if (nextEle && nextEle.className.indexOf("open active") === -1) { await this.openMenu(info.path); await this.sleep(3); const subEle = document.querySelector( `.pcCourseList li[nid='${info.res[pos].id}']` ); subEle && subEle.getAttribute("ms-id") === null && this.clickAutomatic(subEle); } await this.sleep(5); await this.getCurr(); GM_deleteValue("newSupport_20221116_next"); return reslove(true); } reslove(false); }); }, playNext() { if (GM_getValue("newSupport_20221116_next")) { return; } const currInfo = GM_getValue("newSupport_20221116_currInfo"); // 查找当前课程ID对应的节点 let index = this.lessionsInfo.findIndex((item) => item.res.find((e) => e.id === currInfo.id) ); // 获取当前index所指向 const currIndexInfo = this.lessionsInfo[index]; // 获取当前信息在index所指向中的位置 let pos = currIndexInfo.res.findIndex((e) => e.id === currInfo.id); let nextId = null; // 判断是否为最后一个 if (pos === currIndexInfo.res.length - 1) { // 那就index + 1,pos 归零 index = index + 1; pos = 0; } else { // 那就pos + 1, index 不变 pos = pos + 1; } // 判断是否存在下一个课程 if (index < this.lessionsInfo.length) { console.log( `下一个播放的课程信息:`, this.lessionsInfo[index], `pos: ${pos}` ); // 设置播放下一个ID GM_setValue("newSupport_20221116_next", { info: this.lessionsInfo[index], pos, }); } else { console.log("课程播放结束"); alert("课程播放结束"); } }, playCheck() { const info = GM_getValue("newSupport_20221116_currInfo"); // 挂课弹窗解除 const tips = document.querySelector(".win-content"); if (tips && tips.innerText.indexOf("继续学习") > 0) { const btn = document.querySelector(".win-content .close-win-bt"); btn && btn.click(); } if (info) { if (info.type === "sfp" || info.type === "video") { // 获取视频元素 const video = document.querySelector("video"); if (video) { // 设置静音 video.muted = true; // 播放速率,可自行修改0.5,1,1.25,1.5,2 video.playbackRate = 1; // 获取当前播放进度和视频长度 保留一位小数 const currentTime = video.currentTime.toFixed(1); const totalTime = video.duration.toFixed(1); console.log(`当前进度:${currentTime}/${totalTime}`); if (currentTime < totalTime - 5) { // 视频没有播放完 if (video.paused) { console.log("视频被暂停,继续播放!"); video.play(); } setTimeout(() => { this.playCheck(); }, 10000); return true; } } setTimeout(() => { this.playNext(); }, 100); } else { console.log("未知内容类型:", info.type); } } else { console.log("无法获取内容类型"); } }, }; (function () { "use strict"; const url = document.URL; if ( url.indexOf("//rspcourse.chinaedu.net/") !== -1 || url.indexOf(".sccchina.net/") !== -1 || url.indexOf("study.do?userCourseId") !== -1 ) { if (url.indexOf("/play.html") >= 0) { // 删除之前的信息 GM_deleteValue("newSupport_20221116_lessionsInfo"); GM_deleteValue("newSupport_20221116_currInfo"); // 课件页面,查找课程 newSupport_20221116.stepOne(); } else { setTimeout(() => { newSupport_20221116.lessionsInfo = GM_getValue( "newSupport_20221116_lessionsInfo" ); if ( newSupport_20221116.lessionsInfo && !GM_getValue("newSupport_20221116.isVideoInPaly") ) { newSupport_20221116.stepTwo(); } else { // 新支持 newSupport_20221106.work(); } }, 8000); } } else { console.log("未知页面"); } })();