Greasy Fork

Greasy Fork is available in English.

优学院自动静音播放、自动做练习题、自动翻页、修改播放速率

自动静音播放每页视频、自动作答、修改播放速率!

当前为 2020-02-22 提交的版本,查看 最新版本

// ==UserScript==
// @name         优学院自动静音播放、自动做练习题、自动翻页、修改播放速率
// @namespace    [url=mailto:[email protected]][email protected][/url]
// @version      1.4.0
// @description  自动静音播放每页视频、自动作答、修改播放速率!
// @author       EliotZhang、Brush-JIM
// @match        *://*.ulearning.cn/learnCourse/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';
    /*  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     *  优学院自动静音播放、自动做练习题、自动翻页、修改播放速率脚本v1.4.0由EliotZhang发起,由Brush-JIM @ 2020/02/22 最后更新
     *  特别感谢Brush-JIM (Mail:[email protected]) 提供的脚本改进支持!
     *  使用修改播放速率功能请谨慎!!!产生的不良后果恕某概不承担!!!
     *  如果您不需要自动静音功能,请将EnableAutoMute赋值为false
     *  如果您不需要自动修改播放速率,请将EnableAutoChangeRate赋值为false
     *  如果你需要改变自动修改的播放速率,请更改本注释下第一行N的赋值(别改的太大,否则可能产生不良后果!!!默认是1.5倍速,这是正常的!!!最大为15.0,否则可能失效!!!)
     *  自动作答功能由于精力有限目前只支持单/多项选择、判断题、部分填空问答题,如果出现问题请尝试禁用这个功能:将EnableAutoFillAnswer赋值为false
     *  如果脚本无效请查看脚本最后的解决方案,如果还是不行请反馈给本人,本人将会尽快修复
     *  如果在使用中还有什么问题请通过邮箱联系EliotZhang:[email protected]
     *  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     */

    // 自动修改的倍率
    var N = 1.50;
    // 将下面AutoFillAnswer赋值为false可以禁用自动作答功能!
    var EnableAutoFillAnswer = true;
    // 将下面EnableAutoMuted赋值为false可以禁用自动静音功能!
    var EnableAutoMute = true;
    // 将下面EnableAutoChangeRate赋值为false可以禁用自动修改速率功能!
    var EnableAutoChangeRate = true;

    // 新增函数 By Brush-JIM
    function Video() {
        var A = $('video'); // 获取所有视频元素
        // 如果 A 长度为0,则没有视频,直接下一页
        if (A.length === 0) {
            GotoNextPage();
            return;
        }

        // 获取所有视频进度
        /*
            方法1. 用“已看完”来判断
            方法2. 获取data-bind属性的值,
            “text: $root.i18nMessageText().finished”:看完
            “text: $root.i18nMessageText().viewed”:未看完
            “text: $root.i18nMessageText().unviewed”:未开始
        */
        // 注意,这两种方法都不是万能的,优学院的视频在 95.0% 后直接显示 已看完,然后脚本开始点击下一页,导致视频不是真的看完
        // 最简单的解决方法是 setTimeout 的时间长一点,让视频播放久一点,再点击下一页
        var B = []; // 存放视频进度
        var tmp = $('div[class="video-bottom"]');
        for (let b = 0; b < tmp.length; b++) {
            // 获取span,一般都是第一个,如果没有,那就是视频没有显示进度。
            // 极小情况下,视频是没有进度
            let span = tmp[b].getElementsByTagName("span")[0];
            let data_bind = span.getAttribute('data-bind'); // 使用方法2
            B.push(data_bind); // 将进度放到B中
        }
        // 遍历完成后,正常情况下 A 和 B 的长度应该一样

        // 遍历A,判断进度,播放是否暂停,速率是否正确
        for (let c = 0; c < A.length; c++) {
            if (B[c] == 'text: $root.i18nMessageText().viewed' || B[c] == 'text: $root.i18nMessageText().unviewed') { // 视频未看完或未开始
                if (A[c].paused === true) { // 判断视频是否在播放
                    A[c].play(); // 开始播放
                }
                if (EnableAutoMute && A[c].muted === false) { // 判断视频是否静音
                    A[c].muted = true;
                }
                if (EnableAutoChangeRate && A[c].playbackRate != N) { // 判断视频速率
                    A[c].playbackRate = N;
                }
                break; // 跳出循环,因为优学院一个页面只能播放一个视频,不能同时播放多个,所以以免上一个正在播放,下一个又点击播放
            }
        }

        // 判断最后一个视频是否完成,完成后下一页
        if (B[B.length - 1] === 'text: $root.i18nMessageText().finished') { // 最后一个视频看完
            GotoNextPage();
        } else {
            setTimeout(Video, "2000"); // 未完成,则延时,重新运行函数
        }
    }

    function GotoNextPage() {
        var nextPageBtn = $('.mobile-next-page-btn, .next-page-btn next-page-btn cursor');
        if (nextPageBtn.length === 0)
            return;
        autoAnswer = false;
        nextPageBtn.each((k, n) => {
            n.click();
        });
        setTimeout(Video, "2000"); // 重新运行函数
    }

    function CheckModal() {
        var alertModal = document.getElementById("alertModal");
        if (alertModal === undefined)
            return;
        if (alertModal.className.match(/\sin/)) {
            var op = alertModal.children[0].children[0].children[2].children[1].children[1].children[0];
            if (!EnableAutoFillAnswer)
                op = alertModal.children[0].children[0].children[2].children[1].children[1].children[1];
            if (op === undefined)
                return;
            op.click();
            if (EnableAutoFillAnswer)
                ShowAndFillAnswer();
        }
    }

    function RemoveDuplicatedItem(arr) {
        for (var i = 0; i < arr.length - 1; i++) {
            for (var j = i + 1; j < arr.length; j++) {
                if (arr[i] == arr[j]) {
                    arr.splice(j, 1);
                    j--;
                }
            }
        }
        return arr;
    }

    function FillAnswers() {
        var ansarr = [];
        var idList = [];
        var re = [];
        var txtAreas = $('textarea, .blank-input');
        $(txtAreas).each((k, v) => {
            var id = $(v).attr('class') == 'blank-input' ? $(v).parent().parent().parent().parent().parent().parent().parent().attr('id') : $(v).parent().parent().parent().parent().attr('id');
            id = id.replace('question', '');
            idList.push(id);
        });
        idList = RemoveDuplicatedItem(idList);
        $(idList).each((k, id) => {
            $.ajax({
                async: false,
                type: "get",
                url: 'https://api.ulearning.cn/questionAnswer/' + id,
                datatype: 'json',
                success: function (result) {
                    re.push(result.correctAnswerList);
                }
            });
        });

        $(re).each((k1, v1) => {
            if (v1.length == 1) {
                ansarr.push(v1[0]);
            } else {
                $(v1).each(function (k2, v2) {
                    ansarr.push(v2);
                });
            }
        });
        $(txtAreas).each((k, v) => {
            $(v).trigger('click');
            v.value = ansarr.shift();
            $(v).trigger('change');
        });
    }

    function ShowAndFillAnswer() {
        if (autoAnswer)
            return;
        autoAnswer = true;
        var sqList = [];
        var qw = $('.question-wrapper');
        var an = [];
        qw.each(function (k, v) {
            var id = $(v).attr('id');
            sqList.push(id.replace('question', ''));
        });
        if (sqList.length <= 0)
            return;
        $(sqList).each(function (k, id) {
            $.ajax({
                async: false,
                type: "get",
                url: 'https://api.ulearning.cn/questionAnswer/' + id,
                datatype: 'json',
                success: function (result) {
                    an.push(result.correctAnswerList);
                }
            });
        });
        var t = qw.find('.question-title-html');
        t.each(function (k, v) {
            var ans = an.shift();
            $(v).after('<span style="color:red;">答案:' + ans + '</span>');
            an.push(ans);
        });
        var checkBox = qw.find('.checkbox');
        var choiceBox = qw.find('.choice-btn');
        var checkList = [];
        var choiceList = [];
        let lasOffsetP = '';
        checkBox.each((k, cb) => {
            if (lasOffsetP == $(cb).offsetParent().attr('id')) {
                checkList[checkList.length - 1].push(cb);
            } else {
                var l = [];
                l.push(cb);
                checkList.push(l);
                lasOffsetP = $(cb).offsetParent().attr('id');
            }
        });
        lasOffsetP = '';
        choiceBox.each((k, cb) => {
            if (lasOffsetP == $(cb).offsetParent().attr('id')) {
                choiceList[choiceList.length - 1].push(cb);
            } else {
                var l = [];
                l.push(cb);
                choiceList.push(l);
                lasOffsetP = $(cb).offsetParent().attr('id');
            }
        });
        an.forEach(a => {
            if (a[0].match(/[A-Z]/) && a[0].length == 1) {
                var cb = checkList.shift();
                a.forEach(aa => {
                    $(cb[aa.charCodeAt() - 65]).click();
                });
            } else if (a[0].match(/(true|false)/)) {
                var ccb = choiceList.shift();
                a.forEach(aa => {
                    if (aa == 'true')
                        ccb[0].click();
                    else
                        ccb[1].click();
                });
            }
            return;

        });
        FillAnswers();
        $('.btn-submit').click();
        autoAnswer = false;
        GotoNextPage();
    }

    function Main() {
        Video();
        setInterval(CheckModal, "200");
    }

    var autoAnswer = false;

    // 如果脚本报错则有可能是你的网络太慢,请尝试修改下面的3000为更大数值!
    setTimeout(Main, "5000");

})();