[UoocOnline] 优课在线刷课辅助 2018.05.07

一个 UoocOnline 的刷课辅助脚本,非作弊。

【时隔一年的更新】因为我又要刷优课了,所以更新了,顺便将实现思路也写了一下,我毕业之后就不会再维护这个项目了,到时候靠你们自己了√

Head Pic from (C91) [予備学科 (米白粕)] ふりふりりぼん

uooconline-assistant

缘由

当初是因为想刷 uooc 一些想随便应付过去的课,但是有很多限制例如鼠标移开视频会自动暂停之类的很烦,于是看了下发现 uooc 用的是 html5 播放器,基本是由 js 脚本控制,于是便萌生了修改脚本的念头,然而我当时对 js 基本还是一窍不通,然后就开始各种看代码各种百度,经过一下午的努力于17年2月初完工。

功能

  1. 打开视频就自动开始播放(省的还得点一次播放)
  2. 自动静音
  3. 自动以1.99倍速播放(为啥不是2,请看后续说明)
  4. 在视频看完后自动切到下一个视频
  5. 所有视频放完会有 Chrome 桌面通知提醒以及提示音(需要 Chrome 内核浏览器,首次提醒需要允许通知,国产360貌似360浏览器无法显示通知,360极速则可以)
  6. 可以随意后台播放,鼠标移开不会暂停
  7. 会记住你调整的音量以及播放速度,适合想听课的同学使用(2017.03.23更新)

:目前作弊方法(直接发送 learnmark 的 post 请求或者拖动进度条)已经不可用,现在当记录视频进度的时候,服务器会对比视频进度时间差与现实时间差,若前者大于后者的2倍,则会判定为你拖动了进度条,不会记录你的视频进度。因为此辅助是从视频一开始就设置为倍速播放,所以如果设置2倍会有概率出现被服务器判定拖动进度条的情况,故调整为1.99倍。

TODO:自动答题(视频中的弹出问题)。由于目前我并没有碰到这种课程所以不能测试。

如何使用

这个实质上就是将原网页的脚本重定向到修改过的脚本上,理论上使用任何重定向插件均可。

推荐使用 Redirector(谷歌商店地址

之所以推荐,是因为 uooc 出现过脚本地址更换的情况,而 Redirector 支持通配符&正则表达式匹配而且使用简单容易上手。

在谷歌商店下载需要翻墙或者校园网 IPv6,不能翻墙就去 crx4chrome 找其他重定向插件代替,但是请注意,Chrome 浏览器会阻止安装从第三方网页下载的插件。

下面是 Redirect 插件的配置示例:
安装完毕后打开选项,点击"+"号添加重定向规则

  名称:随意
  匹配:^https?://assets.uooconline.com/.*/(learn/main|videoService|uoocVideo).js.*
被替换式:^https?://assets.uooconline.com/.*/
 替换式:https://res.lolicon.app/uooc/

匹配被替换式 都要选 正则表达式 !!!

如你所见,实际上就是把这几个 js 脚本的地址重定向为修改过的 js 脚本,达到神不知鬼不觉替换原有 js 的目的

配置完之后记得 Ctrl+F5 一下确保没有缓存旧的脚本!

如果 F12 Console 中出现以下字样就说明加载成功

Hack videoService.js successed!
Hack uoocVideo.js successed!
Hack main.js successed!

更新日志

2018.05.07 时隔一年,我又要刷 mooc 了,更新了下,顺便重构了自动跳下一节的函数
2017.03.23 会记住你调整的音量和播放速度,切换视频后自动调整至你修改的值,当然,是你没有关掉网页的前提下。
2017.09.14 更新脚本,增加自动切下一节功能。

主要实现思路

后记:
我都不知道我当初是怎么有毅力去读这些压缩了还混淆了的 js 代码的……
还好函数名没有混淆,不然我怕是死都读不懂了

干掉鼠标出界自动暂停功能

videoService.js中有一段r.setBlurPause=function(e){...},清空函数内容即可

使视频自动播放

uoocVideo.js的开头处有很明显的播放器参数初始化autoplay:!1,将1改为0即可

视频放完自动跳下一节

修改main.js,以下代码我尽力写了注释,看不懂我也不会再解释什么了(

新加入的部分代码:

//提示音
var au = document.createElement("audio");
au.preload = "auto";
au.src = "https://res.lolicon.app/uooc/msg.mp3";
//变量
var sId;                    //记录当前课程id,用于切课的时候还原视频速度与音量
var sVolume = 0;            //初始视频音量
var sPalybackRate = 1.99;   //初始视频速度
var runff = true;           //防止通知重复弹出的一个标志而已
//去下一节课
function gotonextcourse() {
    //首先检测是否有没看的视频
    var nowScopes = $(".basic.ng-scope:not(.complete)");
    //没有成员说明这是刚刚打开的章节
    if(nowScopes.length === 0){
        $($("ul.ng-scope").children("li")[0]).children(".basic").click();
        //展开列表后,余下操作可以递归完成,因此直接返回
        return false;
    }
    for(var i=0;i<nowScopes.length;i++){
        var scope = $(nowScopes[i]);
        var ngif = scope.children(".tag-source-ico").attr("ng-if");
        //如果当前小节内仍有没看过的视频
        if(ngif == "source.type == 10"){
            scope.click();
            return true;
        }
    }
    //否则应当跳到下一节
    var nextScopes = $(".basic.active").parents("li:not(.catalogItem)").next();
    if(nextScopes.length>0){
        nextScopes.children(".basic").click();
        //展开列表后,余下操作可以递归完成,因此直接返回
        return false;
    }
    //如果没有下一节,则说明应该跳到下一章
    nextScopes = $(".basic.active").parents("li.catalogItem").next();
    if(nextScopes.length>0){
        nextScopes.children(".basic").click();
        //展开列表后,余下操作可以递归完成,因此直接返回
        return false;
    }
    //如果连下一章都没了,那就没了,放个通知庆祝一下
    if (window.Notification && runff) {
        au.play();
        Notification.requestPermission(function(status) {
            var n = new Notification("那个~主人~", {
                body: "视频都放完了喵!该做测验了喵!",
                icon: "https://res.lolicon.app/uooc/nof.png"
            });
        });
    }
    return true;
}
//延迟递归调用,防止操作太快
function gotonextcoursen() {
    if (!gotonextcourse()) {
        setTimeout("gotonextcoursen()", 2000)
    }
};

接着将以下部分代码放在n.updateCurLearnMark=function(e,t,r){...}函数中的开头,以在更新学习进度标记的时候检测视频播放是否完成并跳下一节:

/*mod-start*/
//记住和还原视频播放速度和音量
if (sId != n.curSource.id) {
    e.volume(sVolume);
    e.playbackRate(sPalybackRate);
    sId = n.curSource.id;
}
if (sVolume != e.volume()) sVolume = e.volume();
if (sPalybackRate != e.playbackRate()) sPalybackRate = e.playbackRate();
//当视频结束的时候自动切下一课
if ((e.duration() - e.currentTime() < 5) && (e.currentTime() > 1)) {
    if (runff) {
        runff = false;
        setTimeout(function() {
            gotonextcoursen();
            runff = true;
        }, 2000);
    }
}
/*mod-end*/

搬瓦工VPS优惠套餐又又又补货啦,建站稳如狗,支持支付宝,循环出账94折优惠码BWH1ZBPVK
①年付仅需$18的中国直连的亚洲优化线路,1核/512M内存/10G硬盘/1000GB@1Gbps【点击购买
②年付$18的可换成CN2线路(流量会变为180G),1核/512M内存/10G硬盘/500GB@1Gbps【点击购买
③年付$28CN2线路,1核/512M内存/10G硬盘/500GB@1Gbps【点击购买

我的文章对您有帮助吗?
我很可爱 请给我钱
扫一扫拿红包 → 扫商家收款码 → 转账与红包相等的金额
即可免费赞赏,又可拿支付宝奖励金!
现在支付宝超抠门的,红包只给一两分钱了
Last modification:May 13th, 2018 at 01:03 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment

8 comments

  1. mr.Kang  GNU/Linux x64(GNU/Linux x64) / Google Chrome 66.0.3359.170(Google Chrome 66.0.3359.170)

    不会自动播放下一章节耶。。。。

    1. 神代綺凜  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 66.0.3359.139(Google Chrome 66.0.3359.139)
      @mr.Kang

      可能是你的课程的目录结构和我的不太一样……我也没有办法顾及到所有人了

  2. miemiedesu  Windows 10 x64 Edition(Windows 10 x64 Edition) / Microsoft Edge 17.17134(Microsoft Edge 17.17134)

    只有我一个人觉得封面被剪切的特别污吗?

    1. 神代綺凜  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 66.0.3359.139(Google Chrome 66.0.3359.139)
      @miemiedesu

      挺好的

  3. zephyru  Windows 7 x64 Edition(Windows 7 x64 Edition) / Google Chrome 64.0.3282.186(Google Chrome 64.0.3282.186)

    好好听课不可以么..

    1. 神代綺凜  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 66.0.3359.139(Google Chrome 66.0.3359.139)
      @zephyru

      因为都是很无聊的课

  4. Apophis  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 62.0.3202.94(Google Chrome 62.0.3202.94)

    凉了…刚才试了一下,无效

    1. 神代綺凜  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 62.0.3202.89(Google Chrome 62.0.3202.89)
      @Apophis

      那可能是uooc的JS脚本又改了什么的,由于这个是做来自用的所以我自己不需要了的话大概就不会再更新了……(这个学期的课已经刷完了)
      下次我更新的话会直接把思路和要修改的部分写出来,这样的话动手能力强的人大概就能自己改了