Greasy Fork

Greasy Fork is available in English.

大橘の学习公社

学习公社自动看视频、自动刷新,自动跳过防疲劳、自动禁音和倍速播放

当前为 2025-04-25 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         大橘の学习公社
// @namespace    HugeOrange
// @version      1.0.0
// @description  学习公社自动看视频、自动刷新,自动跳过防疲劳、自动禁音和倍速播放
// @author       HugeOrange
// @match        https://study.enaea.edu.cn/viewerforccvideo.do*
// @match        https://study.enaea.edu.cn/circleIndexRedirect.do*
// @grant        none
// @license		 MIT
// ==/UserScript==

function getQueryVariable(variable) {
    var query = window.location.search.substring(1);
    var vars = query.split("&");
    for (var i = 0; i < vars.length; i++) {
        var pair = vars[i].split("=");
        if (pair[0] == variable) {
            return pair[1];
        }
    }
    return (false);
}

(function () {
    var url = window.location.pathname
    // 从localStorage读取保存的播放速度,如果没有则使用默认值4.0
    var playbackSpeed = parseFloat(localStorage.getItem('videoPlaybackSpeed') || '4.0');

    // 向页面中添加倍速输入框
    function addSpeedInput() {
        // 等待页面加载完成
        setTimeout(function() {
            // 找到"赞"按钮所在的位置
            var likeButton = document.getElementById('like');
            if (!likeButton) return;
            
            // 创建一个新的元素用于放置倍速控制
            var speedControlLi = document.createElement('li');
            // 使用自定义样式,不使用现有的类名
            speedControlLi.id = 'speed-control';
            
            // 自定义样式
            speedControlLi.style.marginRight = '10px';
            speedControlLi.style.display = 'flex';
            speedControlLi.style.alignItems = 'center';
            speedControlLi.style.height = '30px';
            speedControlLi.style.background = 'none'; // 移除背景
            speedControlLi.style.padding = '0 5px';
            speedControlLi.style.position = 'relative';
            
            // 创建自定义的倍速控制容器
            var speedControlContainer = document.createElement('div');
            speedControlContainer.style.display = 'flex';
            speedControlContainer.style.alignItems = 'center';
            speedControlContainer.style.height = '100%';
            speedControlContainer.style.padding = '0 5px';
            speedControlContainer.style.backgroundColor = '#f5f5f5';
            speedControlContainer.style.borderRadius = '4px';
            speedControlContainer.style.border = '1px solid #e0e0e0';
            
            // 创建标签
            var speedLabel = document.createElement('span');
            speedLabel.textContent = '倍速: ';
            speedLabel.style.color = '#666';
            speedLabel.style.fontSize = '12px';
            speedLabel.style.marginRight = '3px';
            
            // 创建输入框
            var speedInput = document.createElement('input');
            speedInput.type = 'number';
            speedInput.min = '0.5';
            speedInput.max = '16';  // 增加最大倍速至16
            speedInput.step = '0.25';
            speedInput.value = playbackSpeed;
            speedInput.style.width = '40px';
            speedInput.style.height = '22px';
            speedInput.style.textAlign = 'center';
            speedInput.style.border = '1px solid #ccc';
            speedInput.style.borderRadius = '3px';
            speedInput.style.padding = '0 5px';
            speedInput.style.backgroundColor = '#fff';
            speedInput.style.verticalAlign = 'middle';
            speedInput.style.fontSize = '12px';
            speedInput.style.outline = 'none';
            
            // 监听输入变化
            speedInput.addEventListener('change', function() {
                var speed = parseFloat(this.value);
                // 限制范围在0.5到16之间
                if (speed < 0.5) speed = 0.5;
                if (speed > 16) speed = 16;
                this.value = speed;
                playbackSpeed = speed;
                setVideoSpeed(speed);
            });
            
            // 组装元素
            speedControlContainer.appendChild(speedLabel);
            speedControlContainer.appendChild(speedInput);
            speedControlLi.appendChild(speedControlContainer);
            
            // 插入到"赞"按钮之前
            likeButton.parentNode.insertBefore(speedControlLi, likeButton);
        }, 2000); // 等待2秒确保页面元素加载完成
    }

    // 设置视频速度并保存到localStorage
    function setVideoSpeed(speed) {
        var video = document.getElementsByTagName('video')[0];
        if (video) {
            video.playbackRate = speed;
            console.log('设置播放速度为: ' + speed);
            // 保存到localStorage
            localStorage.setItem('videoPlaybackSpeed', speed);
        }
    }
    
    // 静音视频
    function muteVideo() {
        var video = document.getElementsByTagName('video')[0];
        if (video) {
            video.muted = true;
            console.log('视频已静音');
        }
    }

    //视频播放页
    if (url == '/viewerforccvideo.do') {
        //清理localStorage,以防不给加进度。
        localStorage.clear();
        localStorage.setItem('videoIsDone', false)

        // 添加倍速控制
        addSpeedInput();

        // 防疲劳
        setTimeout(() => {
            let video = document.getElementsByTagName('video')[0];
            console.log(video)
            
            // 设置播放速度
            if (video) {
                setVideoSpeed(playbackSpeed);
                // 自动静音
                muteVideo();
            }
            
            //pause:暂停监听
            video.addEventListener('pause', function (e) {
                console.log('暂停播放')
                //继续播放
                videoPlay()
                //删除弹窗
                let dialog = document.getElementById('rest_tip');
                if (dialog) {
                    dialog.remove()
                }
            })

            // 监听播放事件,确保每次播放都设置正确的速度和静音状态
            video.addEventListener('play', function() {
                setVideoSpeed(playbackSpeed);
                muteVideo(); // 确保始终保持静音
            });
        }, 5000)


        //五秒后关闭声音
        function Music_No() {
            setTimeout(function () {
                document.getElementsByClassName("xgplayer-icon-muted")[0].click()
            }, 5000)
        }

        //点击未完成的视频进行播放
        function rePlay() {
            setTimeout(function () {
                if (document.getElementsByClassName("cvtb-MCK-CsCt-studyProgress")[0].innerHTML == '100%') {
                    for (var i = 1; i < document.getElementsByClassName("cvtb-MCK-CsCt-studyProgress")
                        .length; i++) {
                        if (document.getElementsByClassName("cvtb-MCK-CsCt-studyProgress")[i].innerHTML !=
                            '100%') {
                            document.getElementsByClassName("cvtb-MCK-CsCt-studyProgress")[i].click()
                            break
                        }
                    }
                }
            }, 2000)
        }

        //隔五秒循环执行
        setInterval(function () {

            //最后一个视频的index
            index = document.getElementsByClassName("cvtb-MCK-CsCt-studyProgress").length - 1

            //查看当前课前是否完成
            if (document.getElementsByClassName('current')[1].children[0].childNodes[1].innerText ==
                '100%') {

                //如果最后一个视频完成了就代表全部视频都完成了
                if (document.getElementsByClassName("cvtb-MCK-CsCt-studyProgress")[index].innerHTML ==
                    '100%') {
                    //关闭网站
                    localStorage.setItem('videoIsDone', true)
                    window.close()
                } else {
                    //否则播放下一个未完成的视频
                    rePlay()
                }

            } else {
                console.log("正在观看:" + document.getElementsByClassName('current')[1].children[0]
                    .getElementsByClassName("cvtb-text-ellipsis")[0].innerHTML)
            }


            //如果出现异常就刷新网页
            if (document.getElementsByClassName("dialog-content")[0] != undefined) {
                if (document.getElementsByClassName("dialog-content")[0].innerText == '学时记录出现异常请检查网络') {
                    location.reload()
                }
            }

        }, 5000)


        setInterval(function () {
            //播放视频
            videoPlay()
            
            // 每隔一段时间检查并确保设置正确的播放速度和静音状态
            let video = document.getElementsByTagName('video')[0];
            if (video) {
                if (video.playbackRate !== playbackSpeed) {
                    setVideoSpeed(playbackSpeed);
                }
                if (!video.muted) {
                    muteVideo(); // 确保始终保持静音
                }
            }
        }, 1000)

        rePlay()
        Music_No()
    }

    //课程学习页
    if (url == '/circleIndexRedirect.do') {

        function playVideo_2() {
            //切换到未完成的课程tab
            document.getElementsByClassName('customcur-tab-text')[1].click()

            //检测是否完成视频
            if (localStorage.getItem('videoIsDone') == 'true') {
                location.reload()
            } else {
                console.log("观看视频:", document.getElementsByClassName('course-title')[0].innerText)
            }

        }

        //首次进入,只执行一次
        function playVideo_1() {
            //切换到未完成的课程tab
            document.getElementsByClassName('customcur-tab-text')[1].click()

            //检测是否完成视频
            if (localStorage.getItem('videoIsDone') == null) {
                alert('切换到课程学习页自动刷视频,请确保视频可以正常播放后在挂机,点击确定开始运行')
            }

            //循环
            setTimeout(function () {
                //点击第一个开始学习
                document.getElementsByClassName('golearn')[0].click()
            }, 1000)
        }

        //判断是否为试卷页面
        if (getQueryVariable('type') == 'exam') {
            var formDdata = {
                "circleId": cid,
                "syllabusId": sid,
            };
            $.ajax({
                type: "GET",
                url: 'circleIndex.do?action=getMyClass',
                data: formDdata,
                async: true,
                beforeSend: function () {
                    console.log('请等待...');
                },
                complete: function (XMLHttpRequest, status, errorThrown) {
                    console.log('获取完成...');
                },
                success: function (data) {
                    console.log('获取成功...');
                    console.log(data)
                    var dataJson = eval('(' + data + ')');
                    console.log(dataJson.result['list'][0].id)
                    setTimeout(function () {
                        var styleMap = {
                            "width": "100px",
                            display: "inline-block",
                            "background-color": "red",
                            cursor: "pointer",
                            "user-select": "none",
                            "border-radius": "4px",
                            color: "#fff",
                            "font-size": "10px",
                            "line-height": "30px",
                            "margin": "0px 30px",
                        };
                        var btn = document.createElement("a");
                        btn.innerHTML = "提前查看试卷";
                        for (let i in styleMap) {
                            btn.style[i] = styleMap[i];
                        }
                        btn.href =
                            '/myExamAndTestRedirect.do?action=toSeeExamResult&ct=&examId=' +
                            dataJson.result['list'][0].id
                        var toolbox = document.getElementsByClassName("item-title")[0]
                        toolbox.appendChild(btn);
                        alert('请点击试卷标题旁的按钮查看试卷')
                    }, 100)
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    console.log('获取失败...');
                }
            });
        } else {
            setTimeout(function () {
                playVideo_1()
            }, 2000)

            setInterval(function () {
                playVideo_2()
            }, 5000)

            setTimeout(function () {
                localStorage.setItem('videoIsDone', false)
                location.reload()
            }, 1000 * 60 * 10)
        }
    }
})();