湖南开放大学刷课

支持自动播放,自动换集,结束完自动关闭等功能

当前为 2023-09-01 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name        湖南开放大学刷课
// @namespace   Violentmonkey Scripts
// @match       *://www.hnsydwpx.cn/center.html*
// @match       *://www.hnsydwpx.cn/getcourseDetails.html*
// @match       *://www.hnsydwpx.cn/play.html*
// @version     1.0
// @author      n1nja88888
// @description 支持自动播放,自动换集,结束完自动关闭等功能
// @license     AGPL License
// ==/UserScript==
'use strict'
console.log('n1nja88888 creates this world!')
// http://www.hnsydwpx.cn/center.html 课程
// http://www.hnsydwpx.cn/play.html 课程概览
// http://www.hnsydwpx.cn/getcourseDetails.html 视频
// 轮询获取网页元素
async function getEleAsync(selector, timeout) {
    return new Promise(res => {
        const start = Date.now()
        const interval = setInterval(() => {
            const ele = $(selector)
            if (ele) {
                clearInterval(interval)
                res(ele)
            }
            if (Date.now() - start >= timeout)
                res(null)
        }, 0.5e3)
    })
}
async function main() {
    if (location.href.includes('www.hnsydwpx.cn/center.html')) {
        // 获取iframe的上下文
        const iframe = await getEleAsync('#iframe2')
        const context = iframe[0].contentWindow
        // 获取课程列表
        const list = context.$('#LearnInCompleteArr li')
        // 先检查是否有未完成的课程 没有的话就关闭当前网页
        if (list.length === 0)
            window.close()
        else {
            // 记录要学习的点位 默认从0 即第一个视频开始
            let index = 0
            // 获取第一个未学习课
            let curLesson = list.eq(index)
            // 检查视频学习进度
            let text = curLesson.find('.percent').text()
            // 定位到未学状态的视频
            while (text === '进度:100%') {
                curLesson = list.eq(++index)
                text = curLesson.find('.classItemInfo p').eq(2).text()
            }
            curLesson.find('button').click()
        }
    }
    else if (location.href.includes('www.hnsydwpx.cn/play.html'))
        getEleAsync('.classItem').then(course => course.eq(0).find('a')[0].click())
    else if (location.href.includes('www.hnsydwpx.cn/getcourseDetails.html')) {
        // 记录上次进度
        let lastProgressInTime = '0'
        // 获取正在学习课的所有视频
        const videoBox = await getEleAsync('.list-item')
        const videos = videoBox.children()
        // 获取到最后一个视频的序号
        const lastIndex = videos.length - 1
        // 退出
        const exit = $('.list-header').find('button')
        setInterval(async () => {
            // 获得当前正在播放的视频序号
            const curVideoIndex = $('.item-list-redClass').children().eq(0)
                .text().match(/[0-9]/)[0]
            // 每次开始前先轮询一遍当前视频列表是否有还没看完的视频
            let index = 1
            let videoItem = videos.eq(1)
            for (; videoItem.find('.item-list-progress').text() === '100%';) {
                ++index
                videoItem = videos.eq(index)
            }
            // 判断一下是否一直没找到非100%的 说明当前列表全部看完了
            if (index === videos.length) {
                exit.click()
            }
            // 定位到该视频列表中第一个没看完的视频
            // 检查是否第一个没看的视频就是当前在看的视频 是的话就不要点击了
            if (curVideoIndex != index) {
                videoItem.click()
            }
            // 从1开始,因为第0个是标题
            const video = $('video').eq(1)[0]
            if (!video.muted) {
                video.muted = true
            }
            if (video.paused)
                video.play()
            // 是否视频一直在加载
            const progressInTime = $('.xgplayer-time-current').text()
            if (progressInTime === lastProgressInTime)
                location.reload()
            lastProgressInTime = progressInTime
            // 获取视频的百分比进度
            const progressInPercent = videos.eq(curVideoIndex).find('.item-list-progress').text()
            // 剩余时间
            const leftTime = videos.eq(curVideoIndex).find('.redborder').text()
            // 检查当前视频是否已经看完 但是数据没上传成功 剩余时间显示00;00 但进度不是100% 的时候肯定是出现了数据未上传成功
            if (progressInPercent != '100%' && leftTime === '剩余00:00') {
                // 出现这种情况直接退出 先等一下再做判断 再决定
                lastProgressInTime = '0'
                setTimeout(() => {
                    if (progressInPercent != '100%' && leftTime === '剩余00:00')
                        exit.click()
                }, 5e3)
            }
            // 是否看完
            if (progressInPercent === '100%') {
                if (curVideoIndex == lastIndex)
                    exit.click()
                else
                    video.eq(++curVideoIndex).click()
            }
        }, 5e3)
    }
}
main()