//============自动挡处理逻辑、仅用于个人学习使用============ //========感谢@断念大佬======== //---=^_^=@帅√`人才=^_^=--- var SrcVersion = 6.23; //载入断插主控js eval(fetch('hiker://files/cache/Parse_Dn.js')); //------参数设置------ var defaultconfig = { "printlog": 1,//是否开启打印日志:0关闭/1开启 "x5timeout": 5,//设置X5嗅探解析超时时间:秒 "autoselect": 1,//是否开启智能优选解析接口:0关闭/1开启 "failcount": 3,//设置失败几次的片源剔除解析 "fromcount": 12,//当开启自动选择解析时,失败片源达多少个,提示删除 "multiline": 2,//设置解析多线程数 "testcheck": 0,//进入测试检测模式:0关闭/1开启 "disorder": 1,//是否开启乱序模式 "parsereserve": 0,//是否强制保留用户配置的解析口 "jstoweb": 0,//是否允许js解析中跳转x5或web "cachem3u8": 1,//m3u8是否使用缓存方式播放 "iscustom": 0,//是否开启远程关怀模式,自定义解析设置开关:0关闭/1开启 "remotepath": ""//远程在线文件地址 } eval(fetch('hiker://files/cache/SrcSet.js'));//加载用户参数 if(!userconfig){var config = defaultconfig}else{var config = userconfig}//没有取到用户参数时调用默认参数 if(getMyVar('Stitle','0').indexOf("帅助手") == -1){config.testcheck=0} //加载远程自定义设置 if(config.iscustom==1){ try{ let remotefile = fetchCache(config.remotepath, 24); if(remotefile.indexOf("ParseZ") != -1){ eval(remotefile); Object.assign(ParseS, ParseZ); }else{ if(config.printlog==1){log("√远程关怀自定义解析为空,走本地配置文件")}; config.iscustom = 0; } }catch(e){ if(config.printlog==1){log("√远程关怀自定义加载失败,走本地配置文件")}; config.iscustom = 0; } }else{var resetsort = 0}; var sortlist = []; //排序降权临时存放数组 var isresetsort = resetsort || 0; if (isresetsort==0){ var sortfile=fetch("hiker://files/cache/SrcSort.json"); if(sortfile != ""){ eval("var newsort=" + sortfile+ ";"); Object.assign(sortlist, newsort); } } //自动解析入口 var aytmParse = function (vipUrl,parseStr) { if(config.printlog==1){ log("√影片地址:"+vipUrl); if(config.iscustom==1){log("√已开启远程关怀模式")}; if(parseStr != undefined && parseStr != ""){ log("√指定解析:"); }else{ if(config.autoselect==1){log("√开启智能优选")}else{log("√关闭智能优选")}; if(config.disorder==1){log("√开启乱序模式")}else{log("√关闭乱序模式")}; if(config.parsereserve==1){log("√开启强制优先断插配置")}; } if(config.testcheck==1){log("√检测模式")}; }; var str = ""; var from = ""; try { var host = vipUrl.match(/\.(.*?)\//)[1]; from = host.split('.')[0]; } catch (e) { from = "切片源"; } if (from!=""&&from!="切片源"){ //其他网址域名格式的地址 switch (mySet.qju) { case "默认": case "智能优选": case "": switch (host) { case "qq.com": str = mySet.tx; break; case "iqiyi.com": str = mySet.qy; break; case "youku.com": str = mySet.yk; break; case "mgtv.com": str = mySet.mg; break; case "bilibili.com": str = mySet.bl; break; case "le.com": str = mySet.le; break; case "sohu.com": str = mySet.sh; break; case "pptv.com": str = mySet.pp; break; case "ixigua.com": str = mySet.xg; break; case "miguvideo.com": str = mySet.mi; break; case "1905.com": str = mySet.one; break; case "fun.tv": str = mySet.fun; break; default: str = mySet.oth; break; } break; default: str = mySet.qju; break; } } if (str == undefined || str == "") {if(mySet.qju==""||mySet.qju=="默认"){str = mySet.oth;}else{if(mySet.qju!="智能优选"){str = mySet.qju;}}} var strlist = [];//解析口载入临时数组 var prior = [];//处理用户手工配置项的临时数组 var isparse = 0; if (parseStr != undefined && parseStr != "") { strlist = parseStr.split(/,|,/); //字符分割 isparse = 1; //config.autoselect = 0; }else{ //自动列出所有接口 var excludeParse = ['defaultParse', 'maoss', 'CityIP', 'cacheM3u8', 'pcUA', 'parseLc', 'gparse', 'nparse', '道长仓库通免', 'defaultParseWeb', '智能优选', '默认']; if(mySet.qju=="智能优选"){config.autoselect=1} if(config.autoselect==1){ //全局排除的追加到排除列表 for(var j=0;j { return (Math.random() - 0.5); }); } randArr(parsetmplist); } strlist = strlist.concat(parsetmplist); parsetmplist=[];//清空临时 }else{ //关闭智能优选时 if(str!=""&&str!="默认"){ prior = str.split(/,|,/); //字符分割 for (var i in prior) { if(excludeParse.indexOf(prior[i]) == -1){ //配置项接口未被排除,加入候选列表 strlist.push(prior[i]); } } } } } if (strlist.length==0) {hideLoading();return 'toast://好像没有配置解析接口,解个寂寞吗';} if(config.printlog==1){ log("√选择的解析接口组:"+strlist); log("√影片来源标识:"+from) }; //定义排序函数 function sortData(a, b) { if(a.sort!=b.sort){ return a.sort - b.sort }else{ return a.id - b.id; } }; //将选择的解析接口,带上类型、排序 var parsename = ""; var parseurl = ""; var lx = ""; var Jparselist = []; var Uparselist = []; var x5jxlist = []; //x5嗅探接口存放数组 var x5nmlist = []; //x5嗅探接口存放数组 var dellist = []; var faillist = []; var issort = 0; for (var i in strlist) { if(strlist[i].includes("http")){ parsename = strlist[i]; parseurl = strlist[i]; lx = "U"; }else{ if(typeof ParseS[strlist[i]] == 'string'){ parsename = strlist[i]; parseurl = ParseS[strlist[i]]; lx = "U"; }else if(typeof ParseS[strlist[i]] == 'function'){ parsename = strlist[i]; parseurl = "0"; lx = "J"; }else{ dellist.push(strlist[i]); } } let sort = -2; let stopfrom = []; for(var j=0;j 0){ Object.assign(stopfrom, sortlist[j].stopfrom); }; } if(config.autoselect==1&&prior.includes(parsename)==true&&config.parsereserve==1){ //开启了强制优先并保留用户配置的解析 sort = 0; stopfrom = []; } break; } } //新的接口,加入到排序数组 if(sort==-2){ sort = 0; let arr = { "sort" : sort, "name" : parsename, "stopfrom" : [] }; if(parsename!=""){ sortlist.push(arr); issort = 1; } } if(parsename==""||parseurl==""){ //无效的解析,直接加入提示删除数组 if(dellist.indexOf(strlist[i])==-1){dellist.push(strlist[i])}; }else{ //解析接口存在 if(config.autoselect==1){ if(stopfrom.indexOf(from)==-1){ //自动筛选模式时,sort只做排序使用,不包含停用片源的解析,则加入解析接口组 if(lx=="J"){ let parsearr = { "id" : i,"sort" : sort, "name" : parsename }; Jparselist.push(parsearr); } if(lx=="U"){ let urlarr = { "id" : i,"sort" : sort, "name" : parsename, "url" : parseurl }; Uparselist.push(urlarr); } }else{ if(stopfrom.length>=config.fromcount&&stopfrom.indexOf(from)>-1){ //此解析接口大于多少片源失败,且已排除片源,加入提示删除数组 dellist.push(strlist[i]); } } }else{ if(sort>=config.failcount&&stopfrom.indexOf(from)>-1){ //此接口已失败大于设置的次数,且已排除片源,加入提示删除数组 dellist.push(strlist[i]); }else{ //非自动筛选解析时按失败次数,小于设置的次数、且解析接口名有效,加入解析接口组 if(lx=="J"){ let parsearr = { "id" : i,"sort" : sort, "name" : parsename }; Jparselist.push(parsearr); } if(lx=="U"){ let urlarr = { "id" : i,"sort" : sort, "name" : parsename, "url" : parseurl }; Uparselist.push(urlarr); } } } } } if(dellist.length > 0){ config['dellist'] = dellist; writeFile("hiker://files/cache/SrcSet.js", 'var userconfig = ' + JSON.stringify(config)) if(config.printlog == 1){log("√建议删除解析口:"+dellist);} } if(Jparselist.length == 0 && Uparselist.length == 0){ if(config.printlog==1){log("√没有可用的解析接口,需重新配置")}; hideLoading(); return 'toast://解析口全部无效了,重新配置吧'; } //解析接口排序,将之前失败的排在后面 if(Jparselist.length > 0){Jparselist.sort(sortData)}; if(Uparselist.length > 0){Uparselist.sort(sortData)}; if(config.printlog==1){log("√有效解析接口数:"+(Jparselist.length+Uparselist.length))}; var exclude = /404\.m3u8|xiajia\.mp4|余额不足\.m3u8/;//设置排除地址 var contain = /\.mp4|\.m3u8|\.flv|\.avi|\.mpeg|\.wmv|\.mov|\.rmvb|\.dat|qqBFdownload|mime=video%2F|video_mp4/;//设置符合条件的正确地址 var url = ""; var urls = [];//用于多线路地址存储 var names = [];//用于多线路名称存储 var headers = [];//用于多线路头信息存储 var ismulti = config.ismulti||0; var multiline = config.multiline||1; var adminuser = config.adminuser||0; var AppVer = getAppVersion(); if(AppVer>=2909){ if(ismulti==0&&adminuser==0){multiline=2}else{if(multiline>5){multiline=5}} }else{ if(ismulti==0&&adminuser==0){multiline=1}else{if(multiline>5){multiline=5}} } if(config.testcheck==1){multiline=10} if(Jparselist.length>0){ if(config.testcheck==1){showLoading('JS免嗅解析列表,检测中')}; if(config.printlog==1){log("√进入JS列表,接口数:"+Jparselist.length)}; for (var i=0;iJparselist.length){p=Jparselist.length} let JsList = []; for(let s=i;s{ return { func: task, param: { parsename: parse, vipUrl: vipUrl }, id: parse } }); be(Jsparses, { func: function(obj, id, error, taskResult) { obj.results.push(taskResult); obj.names.push(id); obj.errors.push(error); if (AppVer>=2909&&ismulti!=1&&config.testcheck!=1&&contain.test(taskResult)&&!exclude.test(taskResult)) { //toast("我主动中断了"); log("√线程中止"); return "break"; } }, param: { results: beurls, names: benames, errors: beerrors } }); for(let k in benames){ parsename = benames[k]; if(config.printlog==1){log("√正在调用js解析:" + parsename)}; if(beerrors[k]==null){ if(config.jstoweb==1&&beurls[k].search(/x5Rule|webRule/)>-1){ //js中跳转x5或web嗅探 if(config.printlog==1){log("√JS中跳转x5|web嗅探,帅助手逻辑被打断,结果自负")}; return beurls[k]; }else{ if (contain.test(beurls[k]) && !exclude.test(beurls[k])) { url = beurls[k]; if(config.printlog==1){log("√JS解析成功>" + url)}; if(config.testcheck==1){url=""}else{ if(ismulti==1&&multiline>1){ let rurl = url.replace(/;{.*}/,''); let head = format.urlJoinUa(rurl,1); urls.push(format.urlCacheM3u8(rurl,head,urls.length)+'#pre#'); names.push(parsename); headers.push(head); }else{ break; } } } else { //JS解析失败了,排序+1 let failsum =0 ; for(var j=0;j2)||(failsum>=config.failcount)){ //自动选择接口时此接口失败大于2时、失败次数大于限定,此片源排除此解析接口 sortlist[j].stopfrom[sortlist[j].stopfrom.length] = from }; } break; } } if(config.testcheck==1){faillist.push(parsename)}; if(config.printlog==1){log("√解析失败,已失败"+failsum+"次,更换下一个解析")}; } } }else{ if(config.testcheck==1){faillist.push(parsename)}; if(config.printlog==1){log(beerrors[k]+" √此接口有语法错误,更换下一个解析")}; for(var j=0;j0 && url==""){ if(config.testcheck==1){showLoading('URL直链解析列表,检测中')}; if(config.printlog==1){log("√进入URL列表,接口数:"+Uparselist.length)} for (var i=0;i=5){break;} if(contain.test(url)){break;} let UrlList = []; var behtmls = [];//用于存储多线程返回html var beparses = [];//用于存储多线程名称|url地址 var beerrors = [];//用于存储多线程是否有错误 var task = function(obj) { return request(obj.playUrl,{timeout:2000}); }; let p = i+multiline; if(p>Uparselist.length){p=Uparselist.length} for(let s=i;s{ return { func: task, param: { playUrl: parse.split('|')[1]+vipUrl }, id: parse } }); be(Urlparses, { func: function(obj, id, error, taskResult) { obj.results.push(taskResult); obj.parses.push(id); obj.errors.push(error); if (AppVer>=2909&&ismulti!=1&&config.testcheck!=1&&contain.test(taskResult)&&!exclude.test(taskResult)) { log("√线程中止"); return "break"; } }, param: { results: behtmls, parses: beparses, errors: beerrors } }); for(let k in beparses){ let gethtml = behtmls[k]; parsename = beparses[k].split('|')[0]; parseurl = beparses[k].split('|')[1]; if(beerrors[k]==null){ if (gethtml == undefined || gethtml == "" || gethtml == null){ //url直链网页打不开,排序+1 let failsum =0 ; for(let j=0;j2&&sortlist[j].stopfrom.indexOf(from)==-1){ //网站打不开的情况,失败次数>2,此片源排除此解析接口 sortlist[j].stopfrom[sortlist[j].stopfrom.length] = from }; break; } } if(config.testcheck==1){faillist.push(parsename)}; if(config.printlog==1){log(parsename+"-√网站疑似打不开,已失败"+failsum+"次,跳过")}; }else{ var rurl = ""; var rjxlx = ""; try { rurl = JSON.parse(gethtml).url||JSON.parse(gethtml).data.url||JSON.parse(gethtml).data; rjxlx = "O"; } catch (e) { //if(config.printlog==1){log(parsename+"-√URL直链-JSON解析失败,转网页明码偿试")}; if(/\.m3u8|\.mp4|\.flv/.test(gethtml)){ try { if(gethtml.indexOf('urls = "') != -1){ rurl = gethtml.match(/urls = "(.*?)"/)[1]; }else if(gethtml.indexOf('"url":"') != -1){ rurl = gethtml.match(/"url":"(.*?)"/)[1]; }else if(gethtml.indexOf('id="video" src="') != -1){ rurl = gethtml.match(/id="video" src="(.*?)"/)[1]; }else if(gethtml.indexOf('url: "') != -1){ rurl = gethtml.match(/url: "(.*?)"/)[1]; }else{ //log('√将日志提交给帅,帮助完善解析逻辑 '+gethtml); } } catch (e) { log('√明码获取错误:'+e.message); } } if(rurl !=""){ rjxlx = "U" }else{ if(config.printlog==1){log(parsename+"-√URL直链-明码解析失败,加入嗅探解析组偿试")}; x5jxlist.push(parseurl); x5nmlist.push(parsename); } } if (typeof(rurl)!="undefined" && contain.test(rurl) && !exclude.test(rurl)){ url = rurl; if(rjxlx=="O"){ for(var j=0;j=0){ sortlist[j].sort = -1; issort = 1; } break; } } if(config.printlog==1){log(parsename+"-√URL直链-JSON解析成功>" + url)}; }else if(rjxlx == "U"){ if(config.printlog==1){log(parsename+"-√URL直链-明码解析成功>" + url)}; } if(config.testcheck==1){url=""}else{ if(ismulti==1&&multiline>1){ let head = format.urlJoinUa(url,1); urls.push(format.urlCacheM3u8(url,head,urls.length)); names.push(parsename); headers.push(head); }else{ break; } } } else { let failsum = 0; for(var j=0;j'+faillist);refreshPage(false);}else{log('√JS免嗅和URL明码接口失败、网页嗅探未取到解析口,需重新配置插件')}}; if(config.testcheck==1){ if (parseStr == undefined) { if(faillist.length>0){ return $("检测结束,是否处理失败的解析?").confirm((faillist,helper)=>{ return $("#noHistory##noRecordHistory#hiker://empty").rule((faillist,helper)=>{ requireCache(helper, 48); faildeal(faillist) },faillist,helper); },faillist,getMyVar('helper','0')); }else{ return "toast://检测结束"; } }else{ initConfig({faillist:faillist}); refreshPage(false); return "toast://〖"+parseStr+"〗解析失败"; } }else{ return "toast://未找到可用的解析口" } } else { if(config.printlog==1){if(config.testcheck==1){log("√JS免嗅和URL明码检测结束,转网页嗅探检测接口数:"+x5jxlist.length)}else{log("√JS免嗅和URL明码失败,转网页嗅探解析接口数:"+x5jxlist.length)}}; if(config.printlog==1){log("√嗅探调用解析口:"+x5nmlist[0])}; if(config.testcheck==1){showLoading('嗅探解析列表,检测中')}else{showLoading('√嗅探解析中,请稍候')}; let parmset = {"issort":0,"printlog":config.printlog,"timeout":config.x5timeout,"autoselect":config.autoselect,"failcount":config.failcount,"from":from,"testcheck":config.testcheck,"parseStr":parseStr,"helper":getMyVar('helper','0'),"Sversion":parseInt(getMyVar('Sversion','0'))}; for(var i = 0; i < x5nmlist.length; i++) { faillist.push(x5nmlist[i]); } config['x5scslist'] = []; writeFile("hiker://files/cache/SrcSet.js", 'var userconfig = ' + JSON.stringify(config)); return x5Player(x5jxlist,x5nmlist,vipUrl,sortlist,parmset,faillist,format); } } else { if(urls.length>1){ return JSON.stringify({ urls: urls, names: names, //danmu: "hiker://files/cache/danmu.json", headers: headers }); }else{ return format.urlJoinUa(format.urlCacheM3u8(url,format.urlJoinUa(url,1))) + '#isVideo=true#'; } } } catch (e) { if(config.printlog==1){log("√语法错误")}; return 'toast://解析失败,语法错误'; } }; //x5嗅探通用免嗅函数、自动多层嵌套 function x5Player(x5jxlist, x5nmlist, vipUrl, sortlist, parmset, faillist, format) { return 'x5Rule://' + x5jxlist[0] + vipUrl + '@' + (typeof $$$ == 'undefined' ? $ : $$$).toString((x5jxlist, x5nmlist, vipUrl, sortlist, parmset, faillist, format, x5Player) => { if(typeof(request)=='undefined'||!request){ eval(fba.getInternalJs()); }; if (window.c == null) { window.c = 0; if(parmset.testcheck==1){fba.showLoading('嗅探解析列表,检测中')}else{fba.showLoading('√嗅探解析中,请稍候')}; }; window.c++; if (window.c * 250 >= parmset.timeout*1000) { if (x5jxlist.length == 1) { //最后一个X5解析失败了,排序+1 let failsum = 0; for(var j=0;j2)||(failsum>=parmset.failcount)){ //自动选择接口时此接口失败大于2时、失败次数大于限定,此片源排除此解析接口 sortlist[j].stopfrom[sortlist[j].stopfrom.length] = parmset.from; }; } break; } } fba.writeFile("hiker://files/cache/srcsort.json", JSON.stringify(sortlist)); fba.hideLoading(); eval(request("hiker://files/cache/SrcSet.js")); for(var i = 0; i < userconfig.x5scslist.length; i++) { faillist.splice(faillist.indexOf(userconfig.x5scslist[i]),1); } if(parmset.printlog==1){ if(parmset.testcheck==1){ fba.log("√检测结束"); fba.log('√解析失败的>'+faillist); }else{ fba.log("√超过"+window.c * 250+"毫秒还未成功,此接口已失败"+failsum+"次,全部嗅探解析口都失败了"); } }; if(parmset.testcheck==1){ if (parmset.parseStr == undefined) { if(faillist.length>0){ return $$$("检测结束,是否处理失败的解析?").confirm((faillist,helper) => $("hiker://empty#noHistory##noRecordHistory#").rule((faillist,helper) => { requireCache(helper, 48); faildeal(faillist); }, faillist, helper), faillist, parmset.helper) }else{ return "toast://检测结束"; } }else{ initConfig({faillist:faillist}); refreshPage(false); return "toast://〖"+parmset.parseStr+"〗解析失败"; } }else{ return "toast://所有解析接口失败了,请重新配置断插解析接口"; }; } else { //X5解析失败了,排序+1 let failsum = 0; for(var j=0;j2)||(failsum>=parmset.failcount)){ //自动选择接口时此接口失败大于2时、失败次数大于限定,此片源排除此解析接口 sortlist[j].stopfrom[sortlist[j].stopfrom.length] = parmset.from; }; } break; } } if(parmset.printlog==1){ if(parmset.testcheck==1){fba.log("√检测下一个嗅探接口:"+x5nmlist.slice(1)[0]);}else{fba.log("√超过"+window.c * 250+"毫秒还未成功,此接口已失败"+failsum+"次,跳转下一个嗅探接口:"+x5nmlist.slice(1)[0])}}; return x5Player(x5jxlist.slice(1), x5nmlist.slice(1), vipUrl, sortlist, parmset, faillist, format); } } //fba.log(fy_bridge_app.getUrls()); var urls = _getUrls(); var exclude = /playm3u8|m3u8\.tv|404\.m3u8|xiajia\.mp4|余额不足\.m3u8/; var contain = /\.mp4|\.m3u8|\.flv|\.avi|\.mpeg|\.wmv|\.mov|\.rmvb|\.dat|qqBFdownload|mime=video%2F|video_mp4/; for (var i in urls) { if (!exclude.test(urls[i]) && contain.test(urls[i])) { if(parmset.printlog==1){fy_bridge_app.log("√嗅探解析成功>"+urls[i])}; if(parmset.issort==1){fy_bridge_app.writeFile("hiker://files/cache/SrcSort.json", JSON.stringify(sortlist))}; if(parmset.testcheck==1){ eval(request("hiker://files/cache/SrcSet.js")); userconfig.x5scslist.push(x5nmlist[0]); fy_bridge_app.writeFile("hiker://files/cache/SrcSet.js", "var userconfig = " + JSON.stringify(userconfig)); window.c = 100; }else{ return $$$("#noLoading#").lazyRule((url,format)=>{ return format.urlJoinUa(format.urlCacheM3u8(url,format.urlJoinUa(url,1))) + '#isVideo=true#'; }, urls[i], format); /* let url = ""; if (/bilibili|bilivideo/.test(urls[i])) { url = urls[i] + ';{User-Agent@Mozilla/5.0&&Referer@https://www.bilibili.com/}'; } else if (/mgtv|sohu/.test(urls[i])) { url = urls[i] + ';{User-Agent@Mozilla/5.0 (Windows NT 10.0)}'; } else { url = urls[i]; } return url + '#isVideo=true#'; */ } } } }, x5jxlist, x5nmlist, vipUrl, sortlist, parmset, faillist, format, x5Player) }; //加载视频url地址处理函数 var format = { //定义url-UA处理函数 urlJoinUa: function (url,ismul) { try { if(ismul==1){//多线路ua头 if (/mgtv/.test(url)) { var header = {'User-Agent': 'Mozilla/5.0','Referer': 'www.mgtv.com'}; }else if(/bilibili|bilivideo/.test(url)) { var header = {'User-Agent': 'Mozilla/5.0','Referer': 'www.bilibili.com'}; }else if (/wkfile/.test(url)) { var header = {'User-Agent': 'Mozilla/5.0','Referer': 'fantuan.tv'}; }else{ var header = {'User-Agent': 'Mozilla/5.0'}; } return header; }else{ if (url[0] == '/') { url = 'https:' + url } if (/wkfile/.test(url)) { url = url + ';{User-Agent@Mozilla/5.0&&Referer@https://fantuan.tv/}'; }else if(/bilibili|bilivideo/.test(url)){ url = url + ";{User-Agent@Mozilla/5.0&&Referer@https://www.bilibili.com/}"; }else if(/mgtv/.test(url)){ url = url + ';{User-Agent@Mozilla/5.0}'; } return url; } } catch (e) { if(config.printlog==1){log("√错误:"+e.message)}; return url; } }, //定义url是否需要存本地处理函数 urlCacheM3u8: function (url,header,i) { try { if(i==undefined||i==""){ var name = 'video.m3u8'; }else{ var name = 'video'+parseInt(i)+'.m3u8'; } if(header==undefined||header==""){header = {}} if (config.cachem3u8==1) { url = cacheM3u8(url, header, name); } return url; } catch (e) { if(config.printlog==1){log("√错误:"+e.message)}; return url; } } };