分析网络流量,发现是通过隔一段时间向服务器汇报一下进度来实现进度跟踪的。所以我们想要快速刷完课程,就要把这个数据包拦下来,修改其中的进度信息,再给服务器就好啦,服务器就会认为我们已经看完视频了。
1 var sendLog_ = function (player, isdrag, currentTimeSec, callback) { 2 if (!params.reportUrl) { 3 return 4 } 5 var format = '[{0}][{1}][{2}][{3}][{4}][{5}][{6}][{7}]', 6 clipTime = (params.startTime || '0') + '_' + (params.endTime || params.duration); 7 var enc = Ext.String.format(format, params.clazzId, params.userid, params.jobid, params.objectId, currentTimeSec * 1000, '**********', params.duration * 1000, clipTime); 8 var rurl = [ 9 params.reportUrl, 10 '/', 11 params.dtoken, 12 '?clazzId=', 13 params.clazzId, 14 '&playingTime=', 15 currentTimeSec, 16 '&duration=', 17 params.duration, 18 '&clipTime=', 19 clipTime, 20 '&objectId=', 21 params.objectId, 22 '&otherInfo=', 23 params.otherInfo, 24 '&jobid=', 25 params.jobid, 26 '&userid=', 27 params.userid, 28 '&isdrag=', 29 isdrag, 30 '&view=pc', 31 '&enc=', 32 md5(enc), 33 '&rt=', 34 params.rt, 35 '&dtype=Video', 36 '&_t=', 37 new Date().getTime() 38 ].join(''); 39 logFunc(player, rurl, callback) 40 };
以上是汇报进度的js代码,可以看到是通过组装参数形成url,用get方式给服务器发消息。需要注意的是其中有一个字段是enc,是通过把一些参数按照指定格式形成一个字符串,然后md5得到的,要修改参数的话一定要把这个md5也给改了。代码中的******是服务器随机生成的一个salt。
我用firefox写了个插件,作用就是拦住进度报告数据包并修改然后发给服务器。其中background js里的关键代码如下:
1 function getenc(para){ 2 a = [] 3 b = [para.clazzId,para.userid,para.jobid,para.objectId,para.playingTime*1000,'*******',para.duration*1000,para.clipTime]; 4 for(var i=0;i<8;i++) 5 a [i] = '['+b[i]+']'; 6 } 7 a = a.join(''); 8 console.log(a); 9 console.log(md5(a)); 10 return md5(a); 11 } 12 console.log('i am bg, i am do nothing'); 13 pattern = "https://*.chaoxing.com/*" 14 function redirect(detail){ 15 url = detail.url; 16 parameters = url.split('?'); 17 if(parameters.length!=2) 18 return; 19 parameters = parameters[1]; 20 parameters = parameters.split('&'); 21 parameter = {}; 22 for(let item of parameters){ 23 item = item.split('='); 24 parameter[item[0]] = item[1]; 25 } 26 clipTime = parameter['clipTime'] 27 if(!clipTime) 28 return; 29 clipTime = clipTime.split('_') 30 if(clipTime.length!=2) 31 return; 32 start = Number(clipTime[0]) 33 end = Number(clipTime[1]) 34 if(start!=end){ 35 oldenc = getenc(parameter); 36 parameter.clipTime = clipTime[1]+'_'+clipTime[1]; 37 newenc = getenc(parameter); 38 url = url.replace('clipTime='+clipTime[0],'clipTime='+clipTime[1]); 39 url = url.replace('enc='+oldenc,'enc='+newenc); 40 console.log(parameter); 41 //getenc(parameter); 42 return {redirectUrl:url}; 43 } 44 45 } 46 browser.webRequest.onBeforeRequest.addListener( 47 redirect, 48 {urls:[pattern]}, 49 ["blocking"] 50 );
clip_time字段就是保存目前播放进度的字段。
写成插件以后就很方便了,直接点一下播放这个视频就自动被服务器视为已经看完了,左上角也会出现“任务点已完成”字样