UOOC assistant

UOOC优课联盟小助手:视频自动连播,可选自动二倍速播放(因为超过二倍速可能无法记录任务点),可选是否静音,离开页面能够继续播放,能够自动回答视频中途弹出问题;如果视频一开始处于停止状态,可以手动点击播放;如果视频标题下面出现倍速/静音选项,说明脚本正常启动运行;【有问题可以进行反馈,如果觉得不错,欢迎在反馈留下好评】

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

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