雨课堂刷课脚本

只针对雨课堂视频进行自动播放,点击左侧边栏的开始刷课即可自动刷课,刷课期间请勿跳转页面!!!

当前为 2023-07-29 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         雨课堂刷课脚本
// @namespace    http://tampermonkey.net/
// @version      0.1.10
// @description  只针对雨课堂视频进行自动播放,点击左侧边栏的开始刷课即可自动刷课,刷课期间请勿跳转页面!!!
// @author       风之子
// @license      MIT
// @match        https://www.yuketang.cn/*
// @match        https://changjiang.yuketang.cn/*
// @icon         http://newqi.cn/images/logo128.ico
// @grant        GM_addStyle
// ==/UserScript==
// 雨课堂刷课脚本

let shuake = {};

// 视频播放速率,可选值 [1,1.25,1.5,2],默认为二倍速
const rate = 2;

function fun(className, selector) {
  var mousemove = document.createEvent("MouseEvent");
  mousemove.initMouseEvent("mousemove", true, true, unsafeWindow, 0, 10, 10, 10, 10, 0, 0, 0, 0, 0, null);
  console.log(document.getElementsByClassName(className)[0]);
  document.getElementsByClassName(className)[0].dispatchEvent(mousemove);
  document.querySelector(selector).click();
  console.log('已开始两倍速播放');
}

// 加速
function speed() {
  let keyt = '';
  if (rate === 2 || rate === 1) {
    keyt = "[keyt='" + rate + ".00']"
  } else {
    keyt = "[keyt='" + rate + "']"
  }
  fun('xt_video_player_speed', keyt);
}

shuake.shuake = function () {
  // 用于判断不同的课程
  let baseUrl = location.href;
  // 根据客户端记录的URL判别刷到那一集了,不影响第一批用户的刷课进度。
  if (localStorage.getItem('classIndex')) {
    localStorage.setItem(baseUrl, +localStorage.getItem('classIndex'));
    localStorage.removeItem('classIndex');
  }
  let count = +localStorage.getItem(baseUrl) || 0;
  let classList = [];
  // 用于标记视频是否播放完毕
  let play = true;

  try {
    main();
  } catch (error) {
    console.log(error);
  }


  function main() {
    autoSlide(count).then(() => {

      let list = document.querySelector('.logs-list').childNodes;
      console.log('刷课状态:第' + (count + 1) + '个/' + list.length + '个');
      classList[count] = list[count]?.querySelector('.content-box')?.querySelector('section');
      let classInfo = classList[count]?.querySelector('.tag')?.querySelector('use')?.getAttribute('xlink:href');
      // 视频处理
      if (classInfo?.includes('shipin') && play === true) {
        play = false;
        classList[count].click();
        setTimeout(() => {
          console.log('第' + (count + 1) + '个:进入了视频区');
          speed();
          let progress = document.querySelector('.progress-wrap').querySelector('.text');
          let timer1 = setInterval(() => {
            if (progress.innerHTML.includes('100%') || progress.innerHTML.includes('99%') || progress.innerHTML.includes('98%')) {
              count++;
              localStorage.setItem(baseUrl, count);
              play = true;
              history.back();
              main();
              clearInterval(timer1);
            }
          }, 10000);
        }, 3000)
        // 批量处理
      } else if (classInfo?.includes('piliang') && play === true) {
        let zhankai = classList[count].querySelector('.sub-info').querySelector('.gray').querySelector('span');
        sync();
        async function sync() {
          await zhankai.click();
          setTimeout(() => {
            console.log(list[count]);
            // 保存所有视频
            let a = list[count].querySelector('.leaf_list__wrap').querySelectorAll('.activity__wrap');
            console.log(a);
            let count1 = 0;
            bofang();
            function bofang() {
              let classInfo1 = a[count1]?.querySelector('.tag').querySelector('use').getAttribute('xlink:href');
              let play = true;
              console.log(count1);
              console.log(a.length);
              if (classInfo1?.includes('shipin') && play === true) {
                play = false;
                a[count1].click();
                console.log('开始播放视频');
                // 延迟3秒后加速
                setTimeout(() => {
                  speed();
                }, 3000);
                let timer = setInterval(() => {
                  let progress = document.querySelector('.progress-wrap').querySelector('.text');
                  if (progress.innerHTML.includes('100%') || progress.innerHTML.includes('99%') || progress.innerHTML.includes('98%')) {
                    count1++;
                    clearInterval(timer);
                    history.back();
                    setTimeout(() => {
                      bofang();
                    }, 2000);
                  }
                }, 3000)
              } else if (classInfo1 && !classInfo1.includes('shipin') && play === true) {
                console.log('不是视频');
                count1++;
                bofang();
              } else if (count1 === a.length && play === true) {
                console.log('合集播放完毕');
                count++;
                localStorage.setItem(baseUrl, count);
                main();
              }
            }
          }, 2000)
        }
      } else if (classInfo?.includes('ketang') && play === true) {
        console.log('课堂');
        play = false;
        classList[count].click();
        setTimeout(() => {
          let playBack = document.querySelector('.playback');
          if (playBack) { // 存在回放按钮时进入详情页
            playBack.click();
            setTimeout(() => {
              // 内容为视频的逻辑
              if (document.querySelector('video')) {
                function isComplate() {
                  let videoTime = document.querySelector('.video__time').innerHTML.toString();
                  let currentTime = videoTime.split('/')[0];
                  let totalTime = videoTime.split('/')[1];
                  console.log(currentTime, totalTime);
                  if (currentTime == totalTime || currentTime == '00:00' || currentTime == '00:00:00') {
                    count++;
                    localStorage.setItem(baseUrl, count);
                    play = true;
                    history.go(-2);
                    main();
                    clearInterval(timer);
                  }
                }
                let timer = setInterval(() => {
                  isComplate();
                }, 10000)
              }
              // 内容为音频的逻辑
              if (document.querySelector('audio')) {
                function isComplate() {
                  let mainArea = document.querySelector('.mainArea');
                  let currentTime = mainArea.querySelectorAll('span')[0].innerHTML.toString();
                  let totalTime = mainArea.querySelectorAll('span')[1].innerHTML.toString();
                  console.log(currentTime, totalTime);
                  if (currentTime == totalTime || currentTime == '00:00' || currentTime == '00:00:00') {
                    count++;
                    localStorage.setItem(baseUrl, count);
                    play = true;
                    history.go(-2);
                    main();
                    clearInterval(timer);
                  }
                }
                let timer = setInterval(() => {
                  isComplate();
                }, 10000)
              }
            }, 3000)
          } else {   // 不存在回放按钮时退出
            count++;
            localStorage.setItem(baseUrl, count);
            play = true;
            history.go(-1);
            main();
          }
        }, 3000)
      } else if (count === list.length && play === true) {
        console.log('课程刷完了');
        document.querySelector('.myli').innerHTML = '<span>刷完了~</span>';
        localStorage.setItem(baseUrl, 0);
        return;
      } else if (!(classInfo.includes('shipin') || classInfo.includes('piliang')) && play === true) {
        console.log('第' + (count + 1) + '个:不是视频,已跳过');
        count++;
        localStorage.setItem(baseUrl, count);
        main();
      }
    })
  }
  // 根据视频集数,自动下拉刷新集数
  async function autoSlide(count) {
    let frequency = parseInt((count + 1) / 20) + 1;
    for (let i = 0; i < frequency; i++) {
      await new Promise((resolve, reject) => {
        setTimeout(() => {
          document.querySelector('.viewContainer').scrollTop = document.querySelector('.el-tab-pane').scrollHeight;
          resolve();
        }, 1000)
      })
    }
  }
}



shuake.addButton = function () {
  let ul = document.querySelector('.left__menu').querySelector('.top').querySelector('ul');
  let li = document.createElement('li');
  li.classList.add('myli');
  li.innerHTML = '<span>开始刷课</span>';
  ul.appendChild(li);
  li.addEventListener('click', function () {
    shuake.shuake();
    li.innerHTML = '<span>刷课中~</span>';
    li.classList.add('active');
  })
}




// 主程序
shuake.main = function () {
  shuake.addButton();
};




// 添加css样式
function addStyle() {
  let css = `
    .myli{
      height:50px;
      line-height:50px;
    }
    .myli:hover{
      background:yellow;
      color:#000;
      cursor:pointer;
    }
    .active{
      background:#1c223b;
      color:#fff;
    }
  `;
  GM_addStyle(css);
}



(function () {
  'use strict';
  shuake.main();
  addStyle();
})()