UOOC assistant

【使用前先看介绍/有问题可反馈】【欢迎一键三连(好评+打赏+收藏),你的支持是作者维护下去的最大动力!】UOOC优课联盟,视频自动连播,可选自动二倍速播放(因为超过二倍速可能无法记录任务点),可选是否静音,离开页面能够继续播放,能够自动回答视频中途弹出问题;如果视频一开始处于停止状态,可以手动点击播放;如果视频标题下面出现倍速/静音选项说明脚本正常启动运行。

当前为 2020-10-29 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name UOOC assistant
  3. // @name:en UOOC assistant
  4. // @namespace http://tampermonkey.net/
  5. // @version 0.7.3
  6. // @description 【使用前先看介绍/有问题可反馈】【欢迎一键三连(好评+打赏+收藏),你的支持是作者维护下去的最大动力!】UOOC优课联盟,视频自动连播,可选自动二倍速播放(因为超过二倍速可能无法记录任务点),可选是否静音,离开页面能够继续播放,能够自动回答视频中途弹出问题;如果视频一开始处于停止状态,可以手动点击播放;如果视频标题下面出现倍速/静音选项说明脚本正常启动运行。
  7. // @description:en 【使用前先看介绍/有问题可反馈】【欢迎一键三连(好评+打赏+收藏),你的支持是作者维护下去的最大动力!】UOOC优课联盟,视频自动连播,可选自动二倍速播放(因为超过二倍速可能无法记录任务点),可选是否静音,离开页面能够继续播放,能够自动回答视频中途弹出问题;如果视频一开始处于停止状态,可以手动点击播放;如果视频标题下面出现倍速/静音选项说明脚本正常启动运行。
  8. // @author cc
  9. // @include http://www.uooc.net.cn/*
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. 'use strict';
  15. const jsName = 'UOOCassistant.js';
  16. const host = window.location.host;
  17. if (host == 'www.uooc.net.cn') {
  18. console.log(`excute ${jsName}`);
  19. let recursive = () => {
  20. let extraTime = 0;
  21. try {
  22. let done = false;
  23. let video = document.querySelector('#player_html5_api');
  24. if (video) {
  25. if (document.getElementById('rate').checked)
  26. video.playbackRate = 2;
  27. else
  28. video.playbackRate = 1;
  29. if (document.getElementById('volume').checked)
  30. video.muted = true;
  31. else
  32. video.muted = false;
  33. video.autoplay = true;
  34. if (video.ended) {
  35. done = true;
  36. };
  37. let quizLayer = document.querySelector('#quizLayer');
  38. if (quizLayer && quizLayer.style.display != 'none') {
  39. if (done) {
  40. setTimeout(() => {
  41. document.querySelectorAll('.layui-layer-shade').forEach(e => e.style.display = 'none');
  42. }, 1000);
  43. };
  44. let source = JSON.parse(document.querySelector('div[uooc-video]').getAttribute('source'));
  45. let quizList = source.quiz;
  46. let quizIndex = 0;
  47. let currentTime = video.currentTime;
  48. let quizQuestion = document.querySelector('.smallTest-view .ti-q-c').innerHTML;
  49. for (let i = 0; i < quizList.length; i++) {
  50. if (quizList[i].question == quizQuestion) {
  51. quizIndex = i;
  52. break;
  53. };
  54. };
  55. let quizAnswer = eval(quizList[quizIndex].answer);
  56. let quizOptions = quizLayer.querySelector('div.ti-alist');
  57. for (let ans of quizAnswer) {
  58. let labelIndex = ans.charCodeAt() - 'A'.charCodeAt();
  59. quizOptions.children[labelIndex].click();
  60. }; // end for
  61. quizLayer.querySelector('button').click();
  62. extraTime = 1000;
  63. }; // end if
  64. if (!done) {
  65. if (video.paused) {
  66. video.play();
  67. } else {
  68. document.querySelectorAll('.layui-layer-shade, #quizLayer').forEach(e => e.style.display = 'none');
  69. };
  70. };
  71. }; // end if (video)
  72. if (!done) {
  73. console.log('continue recursive function...');
  74. setTimeout(recursive, 250 + extraTime);
  75. } else {
  76. console.log('done!');
  77. if (video) {
  78. console.log('found video exists.');
  79. let current_video = document.querySelector('.basic.active');
  80. let next_video = current_video.nextElementSibling;
  81. while (next_video && !next_video.querySelector('span.icon-video')) {
  82. next_video = next_video.nextElementSibling;
  83. };
  84. if (next_video && next_video.querySelector('span.icon-video')) {
  85. console.log('found next_video.');
  86. next_video.click();
  87. setTimeout(recursive, 500);
  88. } else {
  89. console.log('not found next_video.');
  90. let uncomplete_video = document.querySelector(`li[ng-repeat='pointItem in sectionItem.children'] div.uncomplete`);
  91. if (!uncomplete_video) {
  92. uncomplete_video = document.querySelector(`li[ng-repeat='sectionItem in chapterItem.children'] div.uncomplete`);
  93. };
  94. if (uncomplete_video) {
  95. console.log(uncomplete_video);
  96. console.log('found uncomplete video, ready to click...');
  97. uncomplete_video.click();
  98. setTimeout(() => {
  99. let ul = uncomplete_video.parentNode.querySelector('ul');
  100. if (ul && ul.querySelector('.basic')) {
  101. console.log('found useful ul.');
  102. let next_video = uncomplete_video.parentNode.querySelector('ul').querySelector('.basic');
  103. next_video.click();
  104. setTimeout(() => {
  105. next_video.nextElementSibling.querySelector('.basic').click();
  106. setTimeout(recursive, 1000);
  107. }, 500);
  108. } else {
  109. console.log('not found useful ul.');
  110. uncomplete_video.nextElementSibling.firstElementChild.click();
  111. setTimeout(recursive, 1000);
  112. }
  113. }, 500);
  114. } else {
  115. let next_section = document.querySelector('li div.basic.active').parentNode.parentNode.parentNode.parentNode.nextElementSibling.firstChild;
  116. console.log('next_section as follows:');
  117. console.log(next_section);
  118. if (next_section) {
  119. console.log('found uncomplete section, ready to click...');
  120. next_section.click();
  121. setTimeout(() => {
  122. let next_video = next_section.nextElementSibling.firstElementChild;
  123. if (next_video.firstElementChild) {
  124. console.log('found next video, ready to click...');
  125. next_video.firstElementChild.click();
  126. setTimeout(() => {
  127. next_video.querySelector('div:nth-child(2) > div.basic').click();
  128. setTimeout(recursive, 500);
  129. }, 500);
  130. } else {
  131. console.log('not found next video, end recursive function.');
  132. };
  133. }, 500);
  134. } else {
  135. let complete_items = document.querySelectorAll('.complete');
  136. let complete_video = complete_items.item(complete_items.length - 1);
  137. let uncomplete_video = complete_video.nextElementSibling;
  138. if (uncomplete_video) {
  139. console.log('found next video in the list.')
  140. uncomplete_video.click();
  141. setTimeout(recursive, 1000);
  142. } else {
  143. console.log('not found next video in the list.');
  144. complete_video = document.querySelector('.basic.active');
  145. let next_chapter = complete_video.parentNode.parentNode.nextElementSibling;
  146. if (next_chapter) {
  147. console.log('found next chapter of next chapter in the list.');
  148. next_chapter.firstElementChild.click();
  149. setTimeout(() => {
  150. let next_sub_chapter = next_chapter.querySelector('ul').querySelector('.basic.uncomplete');
  151. if (next_sub_chapter) {
  152. console.log('found next chapter of next sub chapter in the list.');
  153. next_sub_chapter.click();
  154. setTimeout(() => {
  155. let next_video = next_sub_chapter.nextElementSibling.querySelector('div');
  156. if (next_video) {
  157. console.log('found next video in next chapter of next sub chapter in the list.');
  158. next_video.click();
  159. setTimeout(recursive, 500);
  160. } else {
  161. console.log('not found next video in next chapter of next sub chapter in the list, end recursive function.');
  162. };
  163. }, 500);
  164. } else {
  165. console.log('not found next chapter of next sub chapter in the list, end recursive function.');
  166. };
  167. }, 500);
  168. } else {
  169. console.log('not found next video of next chapter in the list.');
  170. };
  171. };
  172. console.log('not found uncomplete video, end recursive function.');
  173. };
  174. };
  175. };
  176. } else {
  177. console.log('video not found.');
  178. };
  179. };
  180. } catch (e) {
  181. // do nothing
  182. };
  183. }; // end recursive
  184. let wait = () => {
  185. if (document.readyState == 'complete') {
  186. console.log('ready to set checkboxes.');
  187. let getCheckbox = (name, text) => {
  188. let p = document.createElement('p');
  189. p.style.color = '#cccccc';
  190. let checkbox = document.createElement('input');
  191. checkbox.id = name;
  192. checkbox.type = 'checkbox';
  193. checkbox.checked = true;
  194. checkbox.name = name;
  195. checkbox.value = name;
  196. checkbox.style.marginLeft = '25px';
  197. p.append(checkbox);
  198. let label = document.createElement('label');
  199. label.setAttribute('for', name);
  200. label.innerText = text;
  201. label.style.marginLeft = '15px';
  202. p.append(label);
  203. p.style.margin = '5px';
  204. return p;
  205. };
  206. let rateCheckbox = getCheckbox('rate', '倍速');
  207. let volumeCheckbox = getCheckbox('volume', '静音');
  208. let head = document.querySelector('.learn-head');
  209. let container = document.createElement('div');
  210. container.style.display = 'flex';
  211. container.style.flexDirection = 'row';
  212. container.append(rateCheckbox);
  213. container.append(volumeCheckbox);
  214. head.append(container);
  215. console.log('checkboxes have been set.');
  216. recursive();
  217. } else {
  218. setTimeout(wait, 200);
  219. };
  220. }; // end wait
  221. wait();
  222. }
  223. })();