华中农业大学网课脚本

华中农业大学网课 自动刷课软件

  1. // ==UserScript==
  2. // @name 华中农业大学网课脚本
  3. // @namespace http://hzau.sccchina.net/
  4. // @version 0.1
  5. // @description 华中农业大学网课 自动刷课软件
  6. // @author Doom
  7. // @license MIT
  8. // @match *://*.sccchina.net/*
  9. // @match *://*.chinaedu.net/*
  10. // @run-at document-idle
  11. // @grant unsafeWindow
  12. // @require http://code.jquery.com/jquery-migrate-1.2.1.min.js
  13. /* globals jQuery, $, waitForKeyElements */
  14.  
  15. // ==/UserScript==
  16. (function() {
  17. 'use strict';
  18. $(document).ready(function() {
  19. if(window.self == window.top){
  20. console.log('当前不在iframe中');
  21. return ;
  22. }
  23.  
  24. console.log('当前在iframe中');
  25. window.onload =()=>{
  26. if(isleftIframe(window)){
  27. console.log('预期自动刷课');
  28. console.log('課程加载完成');
  29.  
  30. popClose();
  31.  
  32. const all_videos = videos();
  33. if(all_videos == undefined || all_videos.length <= 0){
  34. console.log('未加载到课程');
  35. return;
  36. }
  37.  
  38.  
  39. console.log("所有课程:",all_videos);
  40. let video_index = 0;
  41. console.log("play:", video_index);
  42. play(all_videos[video_index]);
  43.  
  44.  
  45. window.addEventListener("message", function(event){
  46. console.log("iframe接受到消息:", event.data);
  47. if(event.data == 'playCompleted'){
  48. if(video_index == all_videos.length-1) {
  49. console.log("所有video已经全部播放完成");
  50. } else {
  51. console.log("play:", ++video_index);
  52. play(all_videos[video_index]);
  53. }
  54. }
  55. });
  56. }
  57.  
  58. if(isVideoFrame(window)){
  59. window.addEventListener("message", function(event) {
  60. console.log("videoFrame接受到消息:", event.data);
  61. if(event.data == 'playVideo'){
  62. playVideo();
  63. }
  64. });
  65. }
  66. };
  67.  
  68. function isleftIframe(window){
  69. // 判断当期是否是 'iframe': 通过判断 iframe:'frameVideo'是否存在来确认的
  70. if(undefined != window.frames['frameVideo'] && null !=window.frames['frameVideo'] ){
  71. return true;
  72. }
  73.  
  74. return false;
  75. }
  76. function isVideoFrame(window){
  77. // 有个一个div: 'videoFrame'
  78. const video = document.getElementById('videoFrame');
  79. if(video && video.tagName == 'DIV'){
  80. return true;
  81. }
  82.  
  83. return false;
  84. }
  85.  
  86. function popClose(){
  87. const pop_close = document.querySelector('#pop > h2 > em');
  88. const clickEvent = new MouseEvent('click', {
  89. bubbles: true,
  90. cancelable: true
  91. });
  92.  
  93. console.log('关闭pop遮罩');
  94. pop_close.dispatchEvent(clickEvent);
  95. }
  96.  
  97. function videos(){
  98. // 获取所有的课件列表
  99. let videos = [];
  100. const topLevelItems = document.querySelectorAll('li.leftOneLevel');
  101. topLevelItems.forEach(item => {
  102. // 查找该 li 元素下的所有 a 标签
  103. const allAnchors = item.querySelectorAll('a');
  104.  
  105.  
  106. // 遍历每个 a 标签,排除含有 <span class="arrow"></span> 的标签
  107. return Array.from(allAnchors).filter(anchor=>{
  108. let isVideo = !anchor.querySelector('span.arrow');
  109. if(isVideo){
  110. console.log(anchor.title);
  111. videos.push(anchor);
  112. }
  113. });
  114.  
  115. return allAnchors;
  116. });
  117.  
  118. return videos;
  119. }
  120.  
  121.  
  122.  
  123. function isActive(video){
  124. const activeLi = anchor.closest('li.active.activeState');
  125. console.log('课件:', anchor.title || anchor.href );
  126. if(activeLi){
  127. console.log("正在播放中");
  128. }
  129.  
  130. return activeLi;
  131. }
  132.  
  133.  
  134.  
  135. function getFirst(videos){
  136. // 已经在播放中,从当前播放中开始
  137. for(let i=0;i<videos.length;i++){
  138. if(isActive(video)){
  139. return i;
  140. }
  141. }
  142.  
  143. // 如果没有开始,则从第一个开始
  144. return 0;
  145. }
  146.  
  147.  
  148.  
  149. function playVideo(){
  150. console.log('start正式播放');
  151. // 自动播放前尝试先静音
  152. const video = document.querySelector('video');
  153. video.muted = true; // 静音
  154. video.autoplay = true;
  155.  
  156. // 静音之后好像play没啥问题了??
  157. video.play();
  158.  
  159. // // 模拟点击事件: 播放
  160. // const clickEvent = new MouseEvent('click', {
  161. // bubbles: true,
  162. // cancelable: true
  163. // });
  164.  
  165. // // videoFrame_video :div上有个play按钮
  166. // const bigPlay = document.querySelector('div.vjs-big-play-button');
  167. // bigPlay.dispatchEvent(clickEvent);
  168.  
  169.  
  170. // // video上的play按钮
  171. // const videoPlay = document.querySelector('div.vjs-play-control.vjs-control');
  172. // videoPlay.dispatchEvent(clickEvent);
  173. console.log('end正式播放');
  174.  
  175.  
  176. // 2s后检查是否播放完成
  177. setTimeout(()=>{
  178. if(playCompleted()){
  179. window.parent.postMessage( 'playCompleted','*');
  180. return ;
  181. }
  182.  
  183. // 如果还没结束,则/2s定时检查一次
  184. const intervalId = setInterval(()=>{
  185. if(playCompleted()){
  186. window.parent.postMessage( 'playCompleted','*');
  187. clearInterval(intervalId);
  188. }
  189.  
  190. }, 5000);
  191.  
  192. }, 2000);
  193. }
  194.  
  195.  
  196. function play(video){
  197. console.log('start播放课件:', video.title || video.href );
  198. // video.click();
  199.  
  200. const clickEvent = new MouseEvent('click', {
  201. bubbles: true, // 事件是否冒泡
  202. cancelable: true // 事件是否可取消
  203. });
  204.  
  205. video.dispatchEvent(clickEvent);
  206. // 因为跨域了所以这里的clickEvent并不能传导到 iframe: 'frameVideo'中
  207. // 需要用到跨iframe通讯
  208. const videoFrame = window.frames['frameVideo']
  209. if(undefined == videoFrame || null == videoFrame){
  210. console.log('iframe: frameVideo找不到');
  211. }
  212. videoFrame.onload = ()=>{
  213. // 未加载完成的话,消息发出去也接受不到
  214. console.log('videoFrame加载完成,then playVideo');
  215. videoFrame.contentWindow.postMessage('playVideo', '*');
  216. };
  217. console.log('end播放课件:', video.title || video.href );
  218. }
  219.  
  220. function wait(ms) {
  221. return new Promise(resolve => setTimeout(resolve, ms));
  222. }
  223.  
  224.  
  225. function timeToSeconds(timeStr) {
  226. const timeParts = timeStr.split(':'); // 分割分钟和秒
  227. const minutes = parseInt(timeParts[0], 10); // 获取分钟
  228. const seconds = parseInt(timeParts[1], 10); // 获取秒数
  229. return (minutes * 60) + seconds; // 转换为秒
  230. }
  231.  
  232.  
  233. function playCompleted(){
  234. const currentTimeDiv = document.querySelector('div.vjs-current-time-display');
  235. const durationDiplay = document.querySelector('div.vjs-duration-display');
  236.  
  237. // 检查是否成功找到元素
  238. if (currentTimeDiv) {
  239. // 获取时间值
  240. const currentTimeValue = currentTimeDiv.textContent.trim().replace('当前时间', '').trim(); // 包含 "当前时间 3:21"
  241. const durationValue = durationDiplay.textContent.trim().replace('时长', '').trim();; // 包含 "时长 3:21"
  242.  
  243.  
  244. console.log('当前时间的值:', currentTimeValue); // 输出 "3:21"
  245. console.log('时长:', durationValue); // 输出 "3:21"
  246.  
  247. if(currentTimeValue == durationValue){
  248. console.log("播放完成");
  249. return true;
  250. }
  251. if(currentTimeValue =='0:00'){
  252. console.log("未播放");
  253. }
  254. if(timeToSeconds(currentTimeValue) > 0 && timeToSeconds(currentTimeValue) < timeToSeconds(durationValue) ){
  255. console.log("已播放部分");
  256. }
  257. } else {
  258. console.log('未找到目标 div');
  259. }
  260. return false;
  261. }
  262.  
  263.  
  264. });
  265. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址