Greasy Fork

Greasy Fork is available in English.

芯位网课刷课助手

自动下一集,自动静音,播放80%以上自动下一集(节约时间)

目前为 2022-11-22 提交的版本。查看 最新版本

// ==UserScript==
// @name         芯位网课刷课助手
// @version      1.1.1
// @description  自动下一集,自动静音,播放80%以上自动下一集(节约时间)
// @match        https://teaching.51xinwei.com/*
// @icon         https://teaching.51xinwei.com/*
// @grant        none
// @author       CoderWyh
// @require      https://lib.baomitu.com/jquery/3.6.0/jquery.js
// @require      https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js
// @run-at document-end
// @license AGPL-3.0 license
// @namespace http://greasyfork.icu/users/797839
// ==/UserScript==



(function() {
    'use strict';
    const body = document.querySelector('body');
    let obServer = new MutationObserver(handler);
    const options = {
        childList: true
    }

    obServer.observe(body, options)
})();

let v,listenerInt,startInt,saveLearnInt
function videoMute() {
    v = document.querySelector("video")
    if (v!= null) {
        v.muted = true
        listenerInt = setInterval(function() {listener()},15000);
        clearInterval(startInt)
        saveLearnInt = setInterval(function() {saveLearnTime()},10000);
    }
}

function start(){
    stopFunction()
    startInt = setInterval(function() {videoMute()},1500)
}

function guard() {
    if (typeof(listenerInt) != 'number'||typeof(saveLearnInt) != 'number') {
        start()
    }
}

function handler(mutationRecordList) {
    for (let i = 0; i < mutationRecordList.length; i++) {
        let addedNodes = mutationRecordList[i].addedNodes
        if (addedNodes) {
            for (let i = 0; i < addedNodes.length; i++) {
                if ((addedNodes[i].id == 'root' && addedNodes[i].childNodes.length>0) || (typeof(addedNodes[i].id) == 'string' && addedNodes[i].id.indexOf('layui-layer')>=0)) {
                    start()
                }
                let innerText = addedNodes[i].innerText
                if (innerText && innerText.indexOf('学习下一课节') >= 0) {
                    obsClick('.layui-layer.layui-layer-dialog .layui-layer-btn0');
                    break;
                }
            }
        }
    }

    obsDocumentPage()
}

function obsDocumentPage() {
    obsText('#page_learn_courseware_document .transcode-file-area.text-center', '该文档类型不支持预览,请点击 这里 下载文档')
        .then((res) => {
        let coursewareMenuItem = document.querySelectorAll('#menu_tarr_content .courseware_menu_item.pull-left.ng-scope')
        if (coursewareMenuItem.length > 2) {
            let activeCoursewareMenuItem = document.querySelector('#menu_tarr_content .courseware_menu_item.pull-left.ng-scope.active')
            let activeCoursewareMenuItemText = activeCoursewareMenuItem.innerText
            for (let i = 0; i < coursewareMenuItem.length; i++) {
                if (activeCoursewareMenuItemText == coursewareMenuItem[i].innerText) {
                    let next = i + 1
                    coursewareMenuItem[next].click()
                    if (coursewareMenuItem.length > next+1) {
                        obsDocumentPage()
                        return
                    }
                    break;
                }
            }
        }

        let courseChapterItem = document.querySelectorAll('.course_chapter_item.user-no-select.ng-scope')
        let activeItem = document.querySelector('.course_chapter_item.user-no-select.ng-scope.active')

        let activeItemText = activeItem.innerText
        for (let i = 0; i < courseChapterItem.length; i++) {
            if (activeItemText == courseChapterItem[i].innerText) {
                courseChapterItem[i + 1].children[1].click()
                break;
            }
        }
    })

}

let obsClickTimer = null

function nextNode() {
    let courseChapterItem = document.querySelectorAll('.course_chapter_item.user-no-select.ng-scope')
    let activeItem = document.querySelector('.course_chapter_item.user-no-select.ng-scope.active')
    let activeItemText = activeItem.innerText
    for (let i = 0; i < courseChapterItem.length; i++) {
        if (activeItemText == courseChapterItem[i].innerText) {
            courseChapterItem[i + 1].children[1].click()
            break;
        }
    }
    start()
}


function obsClick(selector) {
    return new Promise((resolve, reject) => {
        let startExecutionTime = new Date().getTime()
        if (obsClickTimer) {
            clearInterval(obsClickTimer)
        }
        obsClickTimer = setInterval(() => {
            let target = document.querySelector(selector)
            if (target) {
                clearInterval(obsClickTimer)
                target.click()
                resolve({
                    element: selector,
                    operation: 'click'
                })
            } else {
                return
            }

            let executionTime = new Date().getTime()
            if (startExecutionTime - executionTime > 1000 * 10) {
                clearInterval(obsClickTimer)
                reject('超时')
            }
        }, 500)
    })
}

function activation() {
    const localStorage = window.localStorage;
    const activationCodeKey = 'xinwei_activation_code';
    let activationCode = localStorage.getItem(activationCodeKey)
    if (!activationCode) {
        const str ='%u8BF7%u8F93%u5165%u6FC0%u6D3B%u7801%uFF08%u6FC0%u6D3B%u7801%u4E24%u5143%u6C38%u4E45%uFF0C%u53EF%u8054%u7CFB%u5FAE%u4FE1%uFF1Awuwang1873%uFF09%uFF1A'
        let code = prompt(unescape(str), '');
        if (window.atob(code).indexOf('xinweijiaoyu') >= 0) {
            localStorage.setItem(activationCodeKey, code)
            alert(unescape('%u6FC0%u6D3B%u6210%u529F'))
        } else {
            alert(unescape('%u6FC0%u6D3B%u5931%u8D25'))
            return false
        }
    }
    return true
}

let obsTextTimer = null

function obsText(selector, text) {
    return new Promise((resolve, reject) => {
        let startExecutionTime = new Date().getTime()
        if (obsTextTimer) {
            clearInterval(obsTextTimer)
        }
        obsTextTimer = setInterval(() => {
            let target = document.querySelector(selector)
            if (target && target.textContent.trim() == text) {
                clearInterval(obsTextTimer)
                resolve(selector)
            } else {
                return
            }

            let executionTime = new Date().getTime()
            if (startExecutionTime - executionTime > 1000 * 10) {
                clearInterval(obsTextTimer)
                reject('超时')
            }
        }, 500)
    })
}



function stopFunction(){
    clearInterval(listenerInt)
    clearInterval(startInt)
    clearInterval(saveLearnInt)
}

let learn_time_old = ''

function listener() {
    if (document.querySelector(".time_text")==null) {
        return
    }
    if (learn_time_old=='') {
        learn_time_old = document.querySelectorAll(".time_text")[1].innerText
        return
    }
    let learn_time = document.querySelectorAll(".time_text")[1].innerText
    if (learn_time_old==learn_time) {
        stopFunction()
        location.reload(true)
    }
    // v.currentTime = v.duration
    learn_time_old = learn_time
    setTimeout(formatTime(learn_time),30000)
}

let timerIndex = 0
function formatTime(time) {
    if (timerIndex > 3) {
        location.reload(true)
    }
    let minute = parseInt(time.substring(0,2))
    let second = parseInt(time.substring(3,5))
    if ((minute*60 + second) < 60) {
        timerIndex ++
    }
}

const BASEURL = "https://teaching.51xinwei.com/learning/student/studentDataAPI.action?functionCode=sendVideoLearnRecord"

function saveLearnTime() {
    axios({
        method: 'post',
        url: BASEURL,
        data: {
            courseId: getUrlParams("courseId"),
            itemId: getUrlParams("itemId"),
            recordCount: 60,
            playPosition: parseInt(v.currentTime),
            playbackRate: 1,
            key: Date.now()
        },
        transformRequest: [
            function (data) {
                let ret = ''
                for (let it in data) {
                    ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
                }
                ret = ret.substring(0, ret.lastIndexOf('&'));
                return ret
            }
        ],
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        }
    }).then(function (res) {
        if (res.data.learnRecord.state==2) {
            nextNode()
        }
    })
}

function getUrlParams(name) { // 不传name返回所有值,否则返回对应值
    let url = window.location.hash;
    url = url.split("?")[1];
    url = url.split('&');
    let nameres;
    for(var i=0;i<url.length;i++) {
        var info = url[i].split('=');
        var obj = {};
        obj[info[0]] = decodeURI(info[1]);
        url[i] = obj;
    }
    if (name) {
        for(let i=0;i<url.length;i++) {
            for (const key in url[i]) {
                if (key == name) {
                    nameres = url[i][key];
                }
            }
        }
    } else {
        nameres = url;
    }
    return nameres;
}