您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
chinahrt自动刷课,只需将视频添加到播放列表,后续刷课由系统自动完成;基于https://github.com/yikuaibaiban/chinahrt修改。
当前为
// ==UserScript== // @name chinahrt全自动刷课 // @namespace https://github.com/jsgang/chinahrt // @version 1.3 // @description chinahrt自动刷课,只需将视频添加到播放列表,后续刷课由系统自动完成;基于https://github.com/yikuaibaiban/chinahrt修改。 // @author jsgang yikuaibaiban https://www.jsgang.top // @icon https://www.google.com/s2/favicons?sz=64&domain=jsgang.top // @match http://*.chinahrt.com/* // @match https://*.chinahrt.com/* // @match http://videoadmin.chinahrt.com.cn/videoPlay/play* // @match http://videoadmin.chinahrt.com/videoPlay/play* // @match https://videoadmin.chinahrt.com.cn/videoPlay/play* // @match https://videoadmin.chinahrt.com/videoPlay/play* // // @grant unsafeWindow // @grant GM_setValue // @grant GM_getValue // @grant GM_addValueChangeListener // @grant GM_notification // // @license GPL // ==/UserScript== /** * 课程预览页面 * @type {number} */ const COURSE_PREVIEW = 0; /** * 课程播放页面 * @type {number} */ const COURSE_PALY = 1; /** * 视频播放页面 * @type {number} */ const VIDEO_PALY = 2; /** * VUE课程预览页面 * @type {number} */ const VUE_COURSE_PREVIEW = 3; /** * 未知页面 * @type {number} */ const UNKOWN_PAGE = 9999; /** * 课程存储关键字 * @type {string} */ const COURSES = "courses"; /** * 自动播放 * @type {string} */ const AUTOPLAY = "autoPlay"; /** * 静音 * @type {string} */ const MUTE = "mute"; /** * 拖动 * @type {string} */ const DRAG = "drag"; /** * 播放速度 * @type {string} */ const SPEED = "speed"; /** * 播放模式 * @type {string} */ const PLAY_MODE = "play_mode"; /** * 重复次数 * @type {string} */ const REAPT_NUM = "reapt_num"; /** * 自刷切换 * @type {string} */ const REAPT_MODE = "reapt_mode"; /** * 获取自动播放 * @returns {*} */ function getAutoPlay() { return GM_getValue(AUTOPLAY, true); } /** * 获取静音 * @returns {*} */ function getMute() { return GM_getValue(MUTE, true); } /** * 获取拖动 * @returns {*} */ function getDrag() { return GM_getValue(DRAG, 5); } /** * 获取播放速度 * @returns {*} */ function getSpeed() { return GM_getValue(SPEED, 1); } /** * 获取播放列表 * @returns {*|*[]} */ function getCourses() { var value = GM_getValue(COURSES, []); if (Array.isArray(value)) { return value; } return []; } /** * 添加到播放列表 * @param element * @returns {boolean} */ function addCourse(element) { if (!element.title || !element.url) { console.error(element); alert("添加失败,缺少必要参数"); return false; } var oldValue = getCourses(); if (oldValue.findIndex(value => value.url == element.url) > -1) { alert("已经存在播放列表中"); return false; } oldValue.push({title: element.title, url: element.url}); GM_setValue(COURSES, oldValue); return true; } /** * 从播放列表移除 * @param index */ function removeCourse(index) { var courses = getCourses(); if (Number.isNaN(index)) { for (let i = courses.length; i >= 0; i--) { const element = courses[i]; // 正则提取 href 中 sectionId courseId trainplanId var jsonHref = element.url; var jsonSectionId = jsonHref.match(/sectionId=([^&]*)/)[1]; var jsonCourseId = jsonHref.match(/courseId=([^&]*)/)[1]; var jsonTrainplanId = jsonHref.match(/trainplanId=([^&]*)/)[1]; // 正则提取 window.location.href 中 sectionId courseId trainplanId var href = window.location.href; var sectionId = href.match(/sectionId=([^&]*)/)[1]; var courseId = href.match(/courseId=([^&]*)/)[1]; var trainplanId = href.match(/trainplanId=([^&]*)/)[1]; if (jsonCourseId == courseId && jsonSectionId == sectionId && jsonTrainplanId == trainplanId) { courses.splice(i, 1); } } } else { courses.splice(index, 1); } GM_setValue(COURSES, courses); } /** * 生成可以添加到播放列表的容器 * @returns {*|jQuery|HTMLElement} */ function createCanPlayList() { // 生成容器 var playListBox = $("<div>", { id: "canPlayBox", css: { width: "300px", height: "500px", position: "fixed", top: "100px", background: "rgba(255,255,255,1)", right: "20px", border: "1px solid #c1c1c1" } }); var status = $("<div></div>", { text: "获取中...", css: { height: "30px", "border-bottom": "1px solid", "text-align": "center", "line-height": "30px", "color": "#4bccf2", "font-weight": "bold" }, click: function () { playListBox.trigger("clear"); if (getPageNumber() == VUE_COURSE_PREVIEW) { vue_findCourses(playListBox); } else { findCourses(playListBox); } } }); status.appendTo(playListBox); var listBox = $("<div></div>", { css: { height: "470px", "overflow-y": "auto" } }).appendTo(playListBox); playListBox.on("clear", function () { status.text("获取中..."); listBox.empty(); }); // 添加绑定事件 playListBox.on("bind", function (e, data) { if (status.text() == "获取中...") { status.text("点击刷新"); } var box = $("<div>", { css: { "border-bottom": "1px solid #c1c1c1", "padding": "8px", "line-height": "150%", "border-bottom": "1px solid #c1c1c1", "margin-bottom": "3px" } }); var ptitle = $("<p>", { text: data.title, title: data.title, css: { "font-size": "13px", "white-space": "nowrap", "overflow": "hidden", "text-overflow": "ellipsis", } }); ptitle.appendTo(box); var pstatus = $("<p>", { text: "学习状态: " + data.status, title: "学习状态: " + data.status, css: { "font-size": "12px", "white-space": "nowrap", "overflow": "hidden", "text-overflow": "ellipsis", "color": "#c1c1c1" } }); pstatus.appendTo(box); var disabled = getCourses().findIndex(value => value.url == data.url) > -1; var button = $("<button>", { text: disabled ? "已在列表中" : "添加到播放列表", type: "button", disabled: disabled, css: { color: disabled ? "#000" : "#FFF", backgroundColor: disabled ? "#c3c3c3" : "#4bccf2", border: "none", padding: "5px 10px", "margin-top": "4px" }, click: function () { if (addCourse({title: data.title, url: data.url})) { $(this).attr("disabled", true); $(this).css({ color: "#000", backgroundColor: "#c3c3c3", }).text("已在列表中"); } } }); button.appendTo(box); box.appendTo(listBox); }); playListBox.appendTo('body'); return playListBox; } /** * 显示通知 * @param content */ function showNotification(content) { GM_notification({ text: content, title: "Chinahrt自动刷课", image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAArFJREFUWEftlttPE0EUxr+9ddtdYOXSSmmlFFoasSFemmg0qYkIMfGF/9J/wTeN0cSYGBHEBBIoLSIU0VrKpe1eagaySWVmutu+GJPO4+5cfvOdc745wkGl3sI/HEIf4L9ToHrqoHLi4LTRgmm1IAhAMCDgmi4ibEgQhe4SyncOFA9tFMoWaucO9wRJFDAZlpCeUKAq/kA8AY7PHKwWmqic+i8WRRaQTciIj8qeFB0Bjo4dvN9ooOX/7L8OnLshYybaWQouALn5m/XeD3dJ5qcCSEQkrhJcgLfrdabshV8mvtdsPEoEPeV1JzzOqhjSROZ8JsBO2cJa0WQueLFSQ6lqYWpYQT4ZQnSQfzt3g+iwhFw64B/g9VqDm+0uANlNkYB8UkMupnqqkc+qMBgqUAqQOiex5412AHdOJhzAUlqDpvBNIBOXMTtBJyQF0El+ciALgHwfUEUspjTMjrGzPmKIuJ+hlaIA1ksmtg+srhRon7wwE0IuTieoHhTwZJ7+TgGsbDexe2T3DJAdV/E8o1HriTMu3QlR3ymAz4UmSj96A1AkActzOqZH6DD4BtjYM7G5130IYkMynmV0jHHqfXRQxMObPnKg/NvGh81mVyG4HQ1gcVYH22out5oel3Fr0kcVOC3g5cdz2JxH72oVPE1ruDfh7QMPMirCBo3IdMIvRfPi6WUNF2BMl0Aynjii1yAGRIyINZgADRN4tVa/aDiujnfFOg5PbCykNAyp/roPYsPEjn0DkInfflr4tMV+D7xu3P4/eV1GNsFXqWM/sLVv4usuvyK8QGIjEu6m2I+Qu9azIyKt2OoOvyp4EF439w1AJpLmhHjDfoVvUO6GJOHSMZkb86vAngq0L6ieOSA+UalddsWWfZmkA0ERhi4iYkjMUusUqq4AvGLey/8+QF+BP0npcPDdfTv7AAAAAElFTkSuQmCC", }); } /** * 创建配置窗口 */ function createConfigBox() { var box = $("<div>", { css: { position: "fixed", right: 0, top: 0, width: "250px", height: "240px", "background-color": "#FFF", "z-index": 9999, border: "1px solid #ccc" } }); $("<div>", { text: "视频控制配置", css: { "border-bottom": "1px solid #ccc", padding: "5px", "font-weight": "bold" } }).appendTo(box); var configBox = $("<div>", { css: { padding: "5px", "padding-bottom": "5px", "font-size": "12px", "line-height": "150%" } }); // 自动播放 var autoPlayBox = $("<div>", {css: {"border-bottom": "1px dotted #ccc", "padding-bottom": "5px"}}); $("<p>", {text: "是否自动播放:"}).appendTo(autoPlayBox); $("<input>", { type: "radio", name: "autoPlay", value: true, checked: getAutoPlay(), click: function () { GM_setValue(AUTOPLAY, true); } }).appendTo(autoPlayBox); $("<label>", {text: "是"}).appendTo(autoPlayBox); $("<input>", { type: "radio", name: "autoPlay", value: false, checked: !getAutoPlay(), click: function () { GM_setValue(AUTOPLAY, false); } }).appendTo(autoPlayBox); $("<label>", {text: "否"}).appendTo(autoPlayBox); autoPlayBox.appendTo(configBox); // 是否静音 var mutePlayBox = $("<div>", {css: {"border-bottom": "1px dotted #ccc", "padding-bottom": "5px"}}); $("<p>", {text: "是否静音:"}).appendTo(mutePlayBox); $("<input>", { type: "radio", name: "mute", value: true, checked: getMute(), click: function () { GM_setValue(MUTE, true); } }).appendTo(mutePlayBox); $("<label>", {text: "是"}).appendTo(mutePlayBox); $("<input>", { type: "radio", name: "mute", value: false, checked: !getMute(), click: function () { GM_setValue(MUTE, false); } }).appendTo(mutePlayBox); $("<label>", {text: "否"}).appendTo(mutePlayBox); $("<p>", { text: "注意:不静音,视频可能会出现不会自动播放", css: {"font-size": "13px", "font-weight": "bold"} }).appendTo(mutePlayBox); mutePlayBox.appendTo(configBox); // 启用拖放 var dragPlayBox = $("<div>", {css: {"border-bottom": "1px dotted #ccc", "padding-bottom": "5px"}}); $("<p>", {text: "启用拖放(慎用):"}).appendTo(dragPlayBox); $("<input>", { type: "radio", name: "drag", value: 5, checked: getDrag() == 5, click: function () { GM_setValue(DRAG, 5); } }).appendTo(dragPlayBox); $("<label>", {text: "还原"}).appendTo(dragPlayBox); $("<input>", { type: "radio", name: "drag", value: 1, checked: getDrag() == 1, click: function () { GM_setValue(DRAG, 1); } }).appendTo(dragPlayBox); $("<label>", {text: "启用"}).appendTo(dragPlayBox); dragPlayBox.appendTo(configBox); var playModeBox = $("<div>", {css: {"border-bottom": "1px dotted #ccc", "padding-bottom": "5px"}}); playModeBox.appendTo(configBox); configBox.appendTo(box); box.appendTo("body"); } /** * 创建播放列表窗口 */ function createPlayListBox() { var box = $("<div>", { id: "playListBox", css: { position: "fixed", right: 0, top: 250, width: "250px", height: "450px", "background-color": "#FFF", "z-index": 9999, border: "1px solid #ccc", "overflow-y": "auto" } }); $("<div>", { text: "视频列表", css: { "border-bottom": "1px solid #ccc", padding: "5px", "font-weight": "bold" } }).appendTo(box); // 渲染课程列表 var courses = getCourses(); for (let index = 0; index < courses.length; index++) { const element = courses[index]; var ptitle = $("<p>", { text: element.title, title: element.title, css: { "font-size": "13px", "white-space": "nowrap", "overflow": "hidden", "text-overflow": "ellipsis", } }); ptitle.appendTo(box); var button = $("<button>", { text: "移除", type: "button", data: {index: index}, css: { color: "#FFF", backgroundColor: "#fd1952", border: "none", padding: "5px 10px", "margin": "4px 0 10px 0", }, click: function () { if (confirm("确定删除这个视频么?")) { removeCourse($(this).data("index")); } } }); button.appendTo(box); } box.appendTo("body"); } /** * 获取当前页面编号 * @returns {number} */ function getPageNumber() { var href = window.location.href; // 以下是Vue版的请求地址 if (href.indexOf("/index.html#/v_courseDetails") > -1) { return VUE_COURSE_PREVIEW; } // 默认课程详情地址 if (href.indexOf("/course/preview") > -1) { return COURSE_PREVIEW; } if (href.indexOf("/course/play_video") > -1) { return COURSE_PALY; } if (href.indexOf("/videoPlay/play") > -1) { return VIDEO_PALY; } return UNKOWN_PAGE; } /** * 获取课程信息 * @param playListBox */ function findCourses(playListBox) { // 提取所有链接 var allLinks = document.querySelectorAll("a"); // 提取所有可以播放的数据 for (let i = 0; i < allLinks.length; i++) { const element = allLinks[i]; if (element.href.indexOf("/course/play_video") > -1) { playListBox.trigger("bind", { title: element.innerText, url: element.href, status: $(element).prev().text() }); } } } /** * VUE版本获取课程信息 * @param playListBox */ function vue_findCourses(playListBox) { // 获取data var data = document.querySelector("article")?.__vue__?._data; if (!data) { return; } // 获取页面信息 var pageData = data?.pageData; if (!pageData) { return; } // 获取所有章节信息 var chapters = pageData?.course?.chapter_list; // 循环获取章节信息 if (chapters && chapters.length > 0) { for (let i = 0; i < chapters.length; i++) { const chapter = chapters[i]; // 循环分段(课时) var sections = chapter?.section_list; if (sections && sections.length > 0) { for (let j = 0; j < sections.length; j++) { const section = sections[j]; // 拼接课时网址 var url = window.location.protocol + "//" + window.location.host + window.location.pathname + "#/v_video?platformId=" + data.platformId + "&trainplanId=" + data.trainplanId + "&courseId=" + data.courseId + "§ionId=" + section.id; playListBox.trigger("bind", { title: section.name, url: url, status: section.study_status + "( " + section.studyTimeHHmmss + " )" }); } } } } } window.onload = function () { try { // 检测到是Vue if (Vue) { console.log("当前是Vue模式"); // 创建播放列表 var playListBox; // 循环检测 setInterval(() => { if (getPageNumber() == VUE_COURSE_PREVIEW) { if (!playListBox) { playListBox = createCanPlayList(); setTimeout(function () { vue_findCourses(playListBox); }, 1000); } } else { if (playListBox) { playListBox.remove(); playListBox = undefined; } } }, 1000); } } catch (error) { console.log("当前不是Vue模式"); } if (getPageNumber() == COURSE_PREVIEW) { $(document).ready(function () { // 创建播放列表 var playListBox = createCanPlayList(); findCourses(playListBox); }); } if (getPageNumber() == VIDEO_PALY) { $(document).ready(function () { // 增加提示信息 $('<div></div>', { html: "点课程详情页中的【添加到播放列表】按钮添加需要学习的课程。受到浏览器策略影响第一次可能无法自动播放,请手动点击播放。视频播放标签放置最前面。", css: { "font-size": "14px", "font-weight": "bold", color: "red", background: "#FFF", position: "absolute", "line-height": "30px", "z-index": "99999", "left": "30px", bottom: "10px" } }).prependTo("#body"); $("video").prop("muted", "muted"); // 移除讨厌的事件 removePauseBlur(); // 视频播放初始化 function run() { // 总是显示播放进度 player.changeControlBarShow(true); // 拖动开关 player.changeConfig('config', 'timeScheduleAdjust', getDrag()); // 静音 if (getMute()) { player.videoMute(); } else { + player.videoEscMute(); } // 播放速度 player.changePlaybackRate(getSpeed()); // 自动播放 if (getAutoPlay()) { player.videoPlay(); } } // 视频总长度 var videoDuration = 0; var startstaus=0; var actisok=0; var ctimes=0; var rtimes=0; var rtimess=0; var jumpas=0; var nonum=0; var tmp = setInterval(function () { if (player != undefined) { player.addListener('loadedmetadata', run); run(); clearInterval(tmp); // 移除本课程学习完毕 attrset.proxyUrl = ""; // 播放结束 player.addListener('ended', function () { removeCourse(window.location.href); var courses = getCourses(); if (courses.length == 0) { GM_setValue(REAPT_MODE, 0); GM_setValue(REAPT_NUM, 0); showNotification("所有视频已经播放完毕"); } else { GM_setValue(REAPT_MODE, 0); GM_setValue(REAPT_NUM, 0); showNotification("即将播放下一个视频:" + courses[0].title); window.top.location.href = courses[0].url; } }); player.addListener('time', function (t) { videoDuration = parseInt(player.getMetaDate().duration); //var tmpurl=$(location).attr("href"); //if(tmpurl.indexOf("ifDrag=0")==-1){ // if(ctimes==0){ // player.videoSeek(videoDuration-120); // ctimes=1; // } // }else{ //tmpurl=tmpurl.replace("ifPauseAd=1&ifPauseBlur=1","ifPauseAd=0&ifPauseBlur=0"); //tmpurl=tmpurl.replace("ifDrag=0","ifDrag=1"); //if(attrset.currentTime>120){ //self.location.href=tmpurl; // } // } // console.log(attrset.currentTime+"/"+videoDuration); }); } }, 1000); // 创建配置窗口 createConfigBox(); // 创建播放列表窗口 createPlayListBox(); // 检测播放列表 GM_addValueChangeListener(COURSES, function (name, oldValue, newValue, remote) { console.log("检测播放列表变动"); $("#playListBox").remove(); createPlayListBox(); }); // 监测自动播放 GM_addValueChangeListener(AUTOPLAY, function (name, oldValue, newValue, remote) { console.log("监测自动播放变动"); if (newValue) { player.videoPlay(); } }); // 检测静音 GM_addValueChangeListener(MUTE, function (name, oldValue, newValue, remote) { console.log("检测静音变动"); if (newValue) { player.videoMute(); } else { player.videoEscMute(); } }); // 检测拖动 GM_addValueChangeListener(DRAG, function (name, oldValue, newValue, remote) { console.log("检测拖动变动"); player.changeConfig('config', 'timeScheduleAdjust', newValue); }); // 检测速度 GM_addValueChangeListener(SPEED, function (name, oldValue, newValue, remote) { console.log("检测速度变动"); player.changePlaybackRate(newValue); }); }); } }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址