学起Plus挂课自动连续播放

一个网课挂机自动连续播放工具,仅适用于学起Plus sccchina.net chinaedu.net,反馈与交流QQ群:715307684

目前為 2022-10-24 提交的版本,檢視 最新版本

// ==UserScript==
// @name         学起Plus挂课自动连续播放
// @namespace    http://tampermonkey.net/
// @version      0.121
// @description  一个网课挂机自动连续播放工具,仅适用于学起Plus sccchina.net chinaedu.net,反馈与交流QQ群:715307684
// @author       哆哆啦啦梦
// @match        *://*.sccchina.net/*
// @match        *://rspcourse.chinaedu.net/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=chinaedu.net
// @grant        none
// @license      GPLv3
// ==/UserScript==

const timeInterval = 5 * 1000;
let lessionInfo = {};
let videoModuleInfo = {};
let lessionResAll = [];
let currRes = undefined;
let courseEnd = false;
let nextRes = null;

function getLessionRes(arr) {
  arr.forEach((e) => {
    if (e.res) {
      for (let item of e.res) {
        item.name = e.name + ' - ' + item.name;
        // 添加到数组
        lessionResAll.push(item);
      }
    }

    if (e.child) {
      getLessionRes(e.child);
    }
  });
}

function checkCoursePage() {
  if (lessionResAll && lessionResAll.length) {
    // 取出第一个
    const firstRes = lessionResAll[0];
    // 查询是否元素存在
    if (document.querySelector(`li[nid='${firstRes.id}']`) === null) {
      // 不存在,代表非视频页
      // 获取当前选中的模块
      const active = document.querySelector("li.fl.cur");

      if (!active || active.getAttribute("nid") !== videoModuleInfo.id) {
        console.log(
          `当前课程模块不是视频模块!即将转到视频模块,ID:${videoModuleInfo.id}`
        );

        // 查找视频模块标签并点击
        document.querySelector(`li[nid='${videoModuleInfo.id}']`).click();
      }
    }
  }
}

function getNext() {
  // 获取当前res在全部res中的索引并加1指向下一个
  const index = lessionResAll.findIndex((e) => e.id === currRes.id) + 1;

  if (index < lessionResAll.length) {
    // 下一个res
    const nextRes = lessionResAll[index];

    console.log("即将播放下一个RES:", nextRes);

    // 生成新的src
    let nextSrc = undefined;

    if (nextRes.type === "video") {
      nextSrc = `com/video.html?url=${nextRes.url}&pos=0&cid=${nextRes.id}`;
    } else if (nextRes.type === "sfp") {
      nextSrc = `com/video.html?url=${nextRes.url}&pos=null&msg=null`;
    } else {
      console.log("未知RES类型:", nextRes);
    }

    return nextSrc;
  }

  return undefined;
}

function updateCurrRes() {
  // 获取课程内容容器
  const courseCon = document.querySelector(".courseCon iframe");

  if (courseCon === null) {
    // 检查是否课程页面
    return checkCoursePage();
  }

  // 获取加载的地址
  const iframeSrc = courseCon.getAttribute("src");

  // 根据src获取对应课程res信息
  // lessionResAll -> 元素 -> url 中的空格会被编码,所以需要 decodeURI
  const getRes = lessionResAll.find(
    (e) => decodeURI(iframeSrc).indexOf(decodeURI(e.url)) >= 0
  );

  // 检查是否匹配到视频res
  if (getRes === undefined) {
    // 检查是否课程页面
    return checkCoursePage();
  }

  if (currRes === undefined || currRes.id !== getRes.id) {
    // 设置currRes
    currRes = getRes;

    console.log("当前加载的课程URL:", iframeSrc);

    console.log("当前课程的RES:", currRes);

    // 查找导航条
    const breadcrumb = document.querySelector(".page-breadcrumb");
    // 设置标题
    breadcrumb &&
      (breadcrumb.innerHTML = `<b>当前正在播放:${currRes.name}</b>`);

    // 设置内容类型
    sessionStorage.setItem("contentType", currRes.type);
  }
}

function gotoNext() {
  // 获取视频状态
  const status = sessionStorage.getItem("play");

  if (status !== null && !courseEnd) {
    // 判断是否为end
    if (sessionStorage.getItem("play") === "end") {
      // 获取下一个地址
      const nextUrl = getNext();

      if (nextUrl) {
        // 获取课程内容容器
        const courseCon = document.querySelector(".courseCon iframe");

        // 设置新的src
        courseCon.setAttribute("src", nextUrl);
      } else {
        if (!courseEnd) {
          courseEnd = true;
          alert("播放结束,不存在下一个播放视频");
          console.log("播放结束,不存在下一个播放视频");
        }
      }
    }

    // 移除掉,避免再次错误判断
    sessionStorage.removeItem("play");
  }
}

function findLession() {
  // 延迟执行
  setTimeout(() => {
    // 处理弹窗
    const pop = document.querySelector("#pop");

    // 存在就点击关闭按钮
    pop && pop.querySelector(".pop_close").click();

    // 处理课程信息
    if (!courseInfo) {
      return alert("获取当前课程信息失败!");
    }

    // 提取课程信息
    lessionInfo = {
      id: courseInfo.id,
      name: courseInfo.name,
    };

    console.log(`当前课程:${lessionInfo.name},ID:${lessionInfo.id}`);

    // 提取课程模块
    const module = courseInfo.child.$model;

    console.log("模块信息:", module);

    // 查找视频模块索引
    const index = module.findIndex(
      (e) => e.name === "视频学习" || (e.code && e.code === "course")
    );

    // 提取视频模块信息
    videoModuleInfo = {
      id: module[index].id,
      name: module[index].name,
    };

    console.log("视频模块信息:", videoModuleInfo);

    // 提取课程Res
    getLessionRes(module[index].child);

    console.log("课程Res信息:", lessionResAll);
  }, timeInterval);

  // 定时执行
  setInterval(() => {
    // 更新currRes
    updateCurrRes();

    // 符合条件跳到下一个
    gotoNext();
  }, timeInterval);
}

function checkWorkTime() {
  // 不检查时间
  return true;
  const hour = new Date().getHours();
  if (hour < 9 || hour > 22) {
    return false;
  } else {
    return true;
  }
}

function courseLearn() {
  const getVideoProgress = () => {
    // 获取视频元素
    const video = document.querySelector("video");

    if (!checkWorkTime()) {
      const hour = new Date().getHours();
      const mins = new Date().getMinutes();
      // 非工作时间
      console.log("非工作时间:", hour, mins);
      // 暂停 情况下 播放视频
      !video.paused && video.pause();
      return;
    }

    // 设置静音
    video.muted = true;

    // 获取当前播放进度和视频长度 保留一位小数
    const currentTime = video.currentTime.toFixed(1);
    const totalTime = video.duration.toFixed(1);

    console.log(`当前进度:${currentTime}/${totalTime}`);

    if (currentTime < totalTime - 5) {
      // 视频没有播放完
      if (video.paused) {
        console.log("视频被暂停,继续播放!");
        video.play();
      } else {
        // 设置视频状态 播放
        sessionStorage.setItem("play", "start");
      }
    } else {
      // 视频播放完毕
      console.log("视频播放完毕!");
      // 设置标记 播放完毕
      sessionStorage.setItem("play", "end");
    }
  };

  // 定时执行
  setInterval(() => {
    // 获取内容类型
    const type = sessionStorage.getItem("contentType");

    if (type !== null) {
      if (type === "video") {
        getVideoProgress();
      } else if (type === "sfp") {
        // 设置标记 播放完毕
        sessionStorage.setItem("play", "end");
      } else {
        console.log("未知内容类型:", type);
      }
    }
  }, timeInterval);
}

(function () {
  "use strict";

  const url = document.URL;

  if (url.indexOf("//rspcourse.chinaedu.net/") !== -1) {
    if (url.indexOf("/play.html") >= 0) {
      // 课件页面,查找课程
      findLession();
    } else {
      // 课程学习
      courseLearn();
    }
  } else {
    console.log("未知页面");
  }
})();