// ==UserScript==
// @name 学起Plus挂课自动连续播放
// @namespace http://tampermonkey.net/
// @version 0.15
// @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
// ==/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();
}
// 挂课弹窗解除
const tips = document.querySelector(".win-content");
if (tips && tips.innerText.indexOf("继续学习") > 0) {
const btn = document.querySelector(".win-content .close-win-bt");
btn && btn.click();
}
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;
}
// 提取课程信息
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");
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("未知页面");
}
})();