驼人云学堂自动刷视频-新版-V2.0

云学堂视频自动播放-2024-08-05新增自动2倍速

05.08.2024 itibariyledir. En son verisyonu görün.

  1. // ==UserScript==
  2. // @name 驼人云学堂自动刷视频-新版-V2.0
  3. // @namespace czy
  4. // @version 2.6.3
  5. // @description 云学堂视频自动播放-2024-08-05新增自动2倍速
  6. // @author czy
  7. // @icon https://picobd.yxt.com/orgs/yxt_malladmin/mvcpic/image/201811/71672740d9524c53ac3d60b6a4123bca.png
  8. // @match http://*.yunxuetang.cn/plan/*.html
  9. // @match http://*.yunxuetang.cn/kng/plan/document/*
  10. // @match http://*.yunxuetang.cn/kng/view/document/*
  11. // @match http://*.yunxuetang.cn/kng/plan/video/*
  12. // @match http://*.yunxuetang.cn/kng/view/video/*
  13. // @match http://*.yunxuetang.cn/kng/view/package/*
  14. // @match http://*.yunxuetang.cn/kng/plan/package/*
  15. // @match http://*.yunxuetang.cn/kng/o2ostudy/video/*
  16. // @match http://*.yunxuetang.cn/mit/myhomeworkexprience*
  17. // @match http://*.yunxuetang.cn/kng/course/package/video/*
  18. // @match http://*.yunxuetang.cn/kng/course/package/document/*
  19. // @match http://*.yunxuetang.cn/sty/index.htm/*
  20. // @match http://*.yunxuetang.cn/kng/o2ostudy/document/*
  21. // @match https://*.yunxuetang.cn/plan/*.html
  22. // @match https://*.yunxuetang.cn/kng/plan/document/*
  23. // @match https://*.yunxuetang.cn/kng/view/document/*
  24. // @match https://*.yunxuetang.cn/kng/plan/video/*
  25. // @match https://*.yunxuetang.cn/kng/view/video/*
  26. // @match https://*.yunxuetang.cn/kng/view/package/*
  27. // @match https://*.yunxuetang.cn/kng/plan/package/*
  28. // @match https://*.yunxuetang.cn/kng/o2ostudy/video/*
  29. // @match https://*.yunxuetang.cn/mit/myhomeworkexprience*
  30. // @match https://*.yunxuetang.cn/kng/course/package/video/*
  31. // @match https://*.yunxuetang.cn/kng/course/package/document/*
  32. // @match https://*.yunxuetang.cn/sty/index.htm/*
  33. // @match https://*.yunxuetang.cn/kng/o2ostudy/document/*
  34. // @match https://*.yunxuetang.cn/kng/*
  35. // @match https://*.yunxuetang.cn/mit/*
  36. // @match https://*.yunxuetang.cn/sty/*
  37. // @match https://*.yunxuetang.cn/plan/*
  38. // @match https://*.yunxuetang.cn/*
  39.  
  40. // @grant GM_xmlhttpRequest
  41. // @grant unsafeWindow
  42. // @license MIT
  43. // @connect none
  44. // @require http://code.jquery.com/jquery-1.11.0.min.js
  45. // ==/UserScript==
  46.  
  47. (function () {
  48. function Toast(msg, duration) {
  49. duration = isNaN(duration) ? 3000 : duration;
  50. var m = document.createElement('div');
  51. m.innerHTML = msg;
  52. m.style.cssText = "font-family:siyuan;max-width:60%;min-width: 150px;padding:0 14px;height: 40px;color: rgb(255, 255, 255);line-height: 40px;text-align: center;border-radius: 4px;position: fixed;top: 2%;left: 50%;transform: translate(-50%, -50%);z-index: 999999;background: rgba(0, 0, 0,.7);font-size: 16px;";
  53. document.body.appendChild(m);
  54. setTimeout(function () {
  55. var d = 0.5;
  56. m.style.webkitTransition = '-webkit-transform ' + d + 's ease-in, opacity ' + d + 's ease-in';
  57. m.style.opacity = '0';
  58. setTimeout(function () {
  59. document.body.removeChild(m)
  60. }, d * 1000);
  61. }, duration);
  62. }
  63.  
  64. //新版本
  65. let currentTime = ""; //当前播放到的时间
  66. let playTopTxt = "";//还需 ****可完成本课程学习,加油
  67. if (document.getElementsByClassName('jw-text-elapsed')[0]) {
  68. currentTime = document.getElementsByClassName('jw-text-elapsed')[0].innerText;
  69. }
  70. if (document.getElementsByClassName('play-area-title')[0] && document.getElementsByClassName('play-area-title')[0].innerText) {
  71. playTopTxt = document.getElementsByClassName('play-area-title')[0].innerText;
  72. }
  73. //新版本
  74. Element.prototype.trigger = function (eventName) {
  75. this.dispatchEvent(new Event(eventName));
  76. }
  77.  
  78.  
  79. setInterval(() => {//定时器,5秒处理一次
  80. //触发看视频中的弹框
  81. Element.prototype.trigger = function (eventName) {
  82. this.dispatchEvent(new Event(eventName));
  83. }
  84.  
  85.  
  86. //新版本新版本新版本新版本新版本新版本新版本新版本新版本
  87. let myDocumentSpanArrayNew = "";
  88. if (document.getElementsByClassName('play-right-li')[0]) {
  89. myDocumentSpanArrayNew = document.getElementsByClassName('play-right-li')[0].getElementsByClassName('kng-chapter-title');//新的章节列表
  90. }
  91.  
  92.  
  93. //开始学习按钮
  94. if (document.getElementsByClassName('kngpc-playbutton ')[0]) {
  95. document.getElementsByClassName('kngpc-playbutton ')[0].trigger('click')
  96. }
  97.  
  98. //继续学习按钮
  99. for (let i = 0; i < document.getElementsByClassName('yxtf-button').length; i++) {
  100. if (document.getElementsByClassName('yxtf-button')[i].innerText.indexOf('继续学习') > -1) {
  101. document.getElementsByClassName('yxtf-button')[i].trigger('click');
  102. }
  103. }
  104. //下一个任务
  105. if (document.getElementsByClassName('play-area-title')[0] && document.getElementsByClassName('play-area-title')[0].innerText.indexOf('可完成本课程学习') >= 0) {//当前没看完
  106.  
  107. } else if (document.getElementsByClassName('yxtulcdsdk-uexam-preview-container').length > 0 && !document.getElementsByClassName('yxtulcdsdk-uexam-preview-container')[0].innerText.includes('考试')) {//当前不是考试界面且看完了
  108. if (document.getElementsByClassName('yxtf-button')[1]) {
  109. document.getElementsByClassName('yxtf-button')[1].trigger('click')
  110. }
  111.  
  112. }
  113.  
  114. //防治挂机的继续学习校验
  115. for (let i = 0; i < document.getElementsByClassName('yxt-button').length; i++) {
  116. if (document.getElementsByClassName('yxt-button')[i].innerText.indexOf('继续学习') > -1 && document.getElementsByClassName('yxt-button')[i].innerText != ('继续学习 (0s)')) {
  117. document.getElementsByClassName('yxt-button')[i].trigger('click');
  118. }
  119. }
  120. if (document.getElementsByClassName('play-area-title')[0] && document.getElementsByClassName('play-area-title')[0].innerText) {
  121. if (playTopTxt != "") {
  122. if (playTopTxt != document.getElementsByClassName('play-area-title')[0].innerText) {//不相同说明正在正常看
  123. playTopTxt = document.getElementsByClassName('play-area-title')[0].innerText;
  124. } else {//相同说明放挂机出现了,刷新一下
  125. location.reload();
  126. }
  127. }
  128. }
  129. //暂停处理
  130. if (document.getElementsByClassName('jw-text-elapsed')[0]) {
  131. if (currentTime == document.getElementsByClassName('jw-text-elapsed')[0].innerText) {//上一次的时间和当前时间一样,说明暂停了
  132. for (let i = 0; i < myDocumentSpanArrayNew.length; i++) {
  133. if (myDocumentSpanArrayNew[i].classList.contains('color-primary-6')) {
  134. currentTime = ""
  135. myDocumentSpanArrayNew[i].parentNode.parentNode.trigger('click');
  136. }
  137. }
  138. }
  139. } else {
  140. for (let i = 0; i < myDocumentSpanArrayNew.length; i++) {
  141. if (myDocumentSpanArrayNew[i].classList.contains('color-primary-6')) {
  142. currentTime = ""
  143. myDocumentSpanArrayNew[i].parentNode.parentNode.trigger('click');
  144. }
  145. }
  146. }
  147.  
  148. //当前节播放完了吗
  149. if (myDocumentSpanArrayNew != "" && myDocumentSpanArrayNew.length > 0) {//有章节列表
  150. if (document.getElementsByClassName('play-area-title')[0].innerText.indexOf('可完成本课程学习') >= 0) {//当前没看完
  151. for (let i = 0; i < myDocumentSpanArrayNew.length; i++) {
  152. if (myDocumentSpanArrayNew[i].classList.contains('color-primary-6')) {
  153. if (i < myDocumentSpanArrayNew.length - 2) {
  154. let toastTxt = '当前课程:' + myDocumentSpanArrayNew[i].innerText + "\n,下节课:" + myDocumentSpanArrayNew[i + 1].innerText;
  155. //console.log('当前课程:'+myDocumentSpanArrayNew[i].innerText + ",下节课:"+myDocumentSpanArrayNew[i+1].innerText)
  156. Toast(toastTxt, 3000)
  157. }
  158. }
  159. }
  160. } else {//看完了
  161. for (let i = 0; i < myDocumentSpanArrayNew.length; i++) {
  162. if (myDocumentSpanArrayNew[i].classList.contains('color-primary-6')) {
  163. console.log('当前课程:' + myDocumentSpanArrayNew[i].innerText)
  164. if (i < myDocumentSpanArrayNew.length - 2) {
  165. currentTime = ""
  166. myDocumentSpanArrayNew[i + 1].parentNode.parentNode.trigger('click');
  167. }
  168. }
  169. }
  170. }
  171.  
  172. } else {//无章节列表
  173. //document.getElementsByClassName('yxtf-button')[1].trigger('click')
  174.  
  175. }
  176.  
  177. //重新给播放的时间赋值
  178. if (document.getElementsByClassName('jw-text-elapsed')[0]) {
  179. currentTime = document.getElementsByClassName('jw-text-elapsed')[0].innerText;
  180. }
  181.  
  182.  
  183.  
  184.  
  185. //新的内容添加
  186. let buttons = document.getElementsByTagName('button')
  187. for (let i = 0; i < buttons.length; i++) {
  188. if (buttons[i].innerText == '继续学习' || buttons[i].innerText == '开始学习') {
  189. buttons[i].trigger('click');
  190. }
  191. }
  192. let videos = document.getElementsByTagName('video');
  193. if (videos.length > 0) {//如果已经加载video了就防治暂停
  194. let mVideo = videos[0];
  195. if (mVideo.paused) {
  196. mVideo.play();
  197. }
  198. }
  199. //下一任务
  200. if (document.getElementsByClassName('yxtulcdsdk-main')) {
  201. if (videos.length > 0 && !(document.getElementsByClassName('yxtulcdsdk-main')[0].innerText.indexOf('可完成本课程学习') > -1)) {
  202. let page__chapter = document.querySelectorAll('.yxtulcdsdk-course-page__info .yxtulcdsdk-course-page__chapter .yxtulcdsdk-course-page__chapter-lock svg');
  203. if (page__chapter.length <= 0) {//下一任务
  204. for (let i = 0; i < buttons.length; i++) {
  205. if (buttons[i].innerText.indexOf("下一任务") > -1) {
  206. buttons[i].trigger('click');
  207. }
  208. }
  209.  
  210. setTimeout(() => {
  211. if (document.querySelectorAll('.yxtf-dialog__body button')) {
  212. for (let j = 0; j < buttons.length; j++) {
  213. if (buttons[j].innerText.indexOf("确定") > -1) {
  214. buttons[j].trigger('click');
  215. }
  216. }
  217. }
  218.  
  219. }, 1000)
  220. } else {//下一小节
  221. let ellipsis = document.querySelectorAll('.yxtulcdsdk-course-page__info .yxtulcdsdk-course-page__chapter .ellipsis');
  222. if (ellipsis.length > 0) {
  223. let numEllipsis = 0;
  224. for (let i = 0; i < ellipsis.length; i++) {
  225. if (ellipsis[i].classList.contains('color-primary-6')) {
  226. numEllipsis = i;
  227. }
  228. }
  229. if (numEllipsis < (ellipsis.length - 1)) {
  230. numEllipsis = numEllipsis + 1;
  231. ellipsis[numEllipsis].parentElement.trigger('click')
  232. } else {
  233. for (let i = 0; i < buttons.length; i++) {
  234. if (buttons[i].innerText.indexOf("下一任务") > -1) {
  235. buttons[i].trigger('click');
  236. }
  237. }
  238.  
  239. setTimeout(() => {
  240. if (document.querySelectorAll('.yxtf-dialog__body button')) {
  241. for (let j = 0; j < buttons.length; j++) {
  242. if (buttons[j].innerText.indexOf("确定") > -1) {
  243. buttons[j].trigger('click');
  244. }
  245. }
  246. }
  247.  
  248. }, 1000)
  249. }
  250. }
  251. }
  252.  
  253. }
  254. }
  255.  
  256. //开启倍速
  257. if (document.querySelectorAll('.jw-overlay ul li')) {
  258. let overlayX = document.querySelectorAll('.jw-overlay ul li');
  259. for (let i = 0; i < overlayX.length; i++) {
  260. if (overlayX[i].innerText.indexOf("×2") > -1) {
  261. overlayX[i].trigger('click');
  262. }
  263. }
  264. }
  265. //2024-07-19新增---------------------------------------
  266. //用来判断当前元素是否显示了
  267. function isElementVisible(element) {
  268. return element.offsetParent !== null;
  269. }
  270. //根据按钮的文字判断是哪一个按钮
  271. function autoClick(element,str){
  272. if(element.innerText.indexOf(str) > -1){
  273. if(isElementVisible(element)){
  274. element.click();
  275. element.trigger('click');
  276. }
  277. }
  278. }
  279. let aButtons = document.querySelectorAll('button')
  280. for(let i = 0;i<aButtons.length;i++){
  281. autoClick(aButtons[i],"继续学习下一阶段");
  282. }
  283. //根据svg判断是否播放完了
  284. // 获取 class 为 "task-content-active" 的 div 元素
  285. var taskContentActiveDiv = document.querySelector('.task-content-active');
  286.  
  287. // 检查是否找到该元素
  288. if (taskContentActiveDiv) {
  289. // 获取 div 内的 svg 标签
  290. const svgElement = taskContentActiveDiv.querySelector('svg');
  291.  
  292. // 检查是否找到 svg 标签
  293. if (svgElement) {
  294. // 获取 svg 内的 path 标签
  295. const pathElement = svgElement.querySelector('path');
  296.  
  297. // 检查是否找到 path 标签
  298. if (pathElement) {
  299. // 获取 path 标签的 fill-rule 属性
  300. const fillRule = pathElement.getAttribute('fill-rule');
  301.  
  302. // 检查 fill-rule 属性是否等于 "nonzero"
  303. if (fillRule == 'nonzero') {
  304. console.log('没播放完.');
  305. } else {
  306. console.log('播放完了.');
  307. let nextButtons = document.querySelectorAll('button');
  308. for(let i = 0;i<nextButtons.length;i++){
  309. console.log(nextButtons[i].innerText)
  310. if(nextButtons[i].innerText.indexOf('下一个') > -1){
  311. nextButtons[i].click();
  312. //nextButtons[i].trigger('click');
  313. }
  314. }
  315. }
  316. } else {
  317. console.log('没找到svg里的path.');
  318. }
  319. } else {
  320. console.log('没找到svg.');
  321. }
  322. } else {
  323. console.log('没找到"task-content-active".');
  324. }
  325. //开启2倍速
  326. if(document.getElementsByClassName("jw-controlbar jw-background-color jw-reset").length != 0){
  327. //播放视频后设置2倍速
  328. if(document.querySelector(".yxtulcdsdk-fullsize").__vue__.$refs.player.getPlayer().getPlaybackRate() &&
  329. document.querySelector(".yxtulcdsdk-fullsize").__vue__.$refs.player.getPlayer().getPlaybackRate() != 2){
  330. document.querySelector(".yxtulcdsdk-fullsize").__vue__.$refs.player.getPlayer().setPlaybackRate(2)
  331. }
  332. }
  333. }, 5000)
  334. })();