// ==UserScript== // @name 视频嗅探、下载、录屏 // @namespace http://tampermonkey.net/ // @version 1.50 // @description 功能包含:1、录屏;2、自动嗅探页面上的视频资源,将链接展示出来,并提供复制和下载方法(除部分加密的m3u8不能下载,解密方法目前还没空研究)。 // @author geigei717 // @license MIT // @antifeature ads // @match https://*/* // @match http://*/* // @icon https://greasyfork.s3.us-east-2.amazonaws.com/fc67t00gsk98w7pbhs97xr94g1hl // @require https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js // @require http://cdn.staticfile.org/layer/3.5.1/layer.min.js // @require https://cdn.bootcdn.net/ajax/libs/dplayer/1.27.1/DPlayer.min.js // @require https://cdn.bootcdn.net/ajax/libs/hls.js/1.4.12/hls.js // @resource layerCss https://cdn.staticfile.org/layer/3.5.1/theme/default/layer.css?v=3.5.1 // @resource DplayerCss https://cdn.jsdelivr.net/npm/dplayer/dist/DPlayer.min.css // @noframes // @grant unsafeWindow // @grant GM_download // @grant GM_setClipboard // @grant GM_xmlhttpRequest // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // @grant GM_addElement // @grant GM_getResourceText // @connect * // ==/UserScript== (function() { needJs() var userAgent = navigator.userAgent.toLowerCase(); var platform,weight,weight1,offset; if(userAgent == null || userAgent == ''){ platform = 'pc' ; }else{ if(userAgent.indexOf("android") != -1 ){ platform = 'phone'; }else if(userAgent.indexOf("ios") != -1 || userAgent.indexOf("iphone") != -1 || userAgent.indexOf("ipad") != -1){ platform = 'phone'; }else if(userAgent.indexOf("windows phone") != -1 ){ platform = 'phone'; }else{ platform = 'pc' ; } } var w = window.innerWidth; var h = window.innerHeight; if(platform == 'pc'&& w > 800 && h >600){ weight = ['800px', '600px']; weight1 = ['500px', '600px']; offset = (h-600)/2+"px" }else{ if(w < 490){ var z = w/490; GM_addStyle( '#MyUpDown{zoom: '+z+';-moz-transform: scale('+z+');-moz-transform-origin:right top;;} '+ '#MyUrls{zoom: '+z+';-moz-transform: scale('+z+');-moz-transform-origin:right top;;} '+ '#Allurl{zoom: '+z+';-moz-transform: scale('+z+');-moz-transform-origin: right top;;}; ') } if(platform == 'pc'){ offset = w < h ? (h-w)/2+"px" : 0.1*h+"px"; weight = w < h ? [0.8*w+"px", 0.8*w+"px"] : [0.8*h+"px", 0.8*h+"px"]; weight1 = w < h ? [0.8*w+"px",0.8*w+94+"px"] : [0.8*h+"px",0.8*h+94+"px"]; }else{ offset = w < h ? (h-w)/2+"px" : 0.01*h+"px"; weight = w < h ? [0.98*w+"px", 0.98*w+"px"] : [0.98*h+"px", 0.98*h+"px"]; weight1 = w < h ? [0.98*w+"px",0.98*w+94+"px"] : [0.98*h+"px",0.98*h+94+"px"]; } } if(platform == 'pc'){ var info = ['✅ 已启用', '❌ 已禁用'] mkMenu("嗅探到新资源时自动打开窗口:","auto_n") mkMenu("是否转码(需满足先决条件):","ffmpeg_n") GM_registerMenuCommand('✅支持作者,你的支持就是作者的动力', function() {me()}) } let URLs = [],videos=[],play = 0,hzh = false;; unsafeWindow.GM_D = []; var mn = -1 $("body").append("") .append("
" + ""+ "
"+ "
") .append("") .append("") GM_addStyle( '#Allurl>i{margin: 0 1px!important;display: inline-block;}'+ '.MyUrls hr{ background: #837b7b; border-color: #837b7b; border-width: 0;height: 1px; }'); $(".MyUrls").append("
0、
下载
播放
") //") var ad = 0,angle = 0; $("#MyUpDown").click(function () { angle += 45 $("#MyUpDown #downIcon").css( 'transform', 'rotate('+angle+'deg)') if (mn=="1"||mn==1){ //$("#Allurl").css("display","none") }else { $("#redPoint").css("display","none") //$("#Allurl").css("display","block") } mn = -mn; $("#Allurl").slideToggle("slow"); $("#MyUrls").slideToggle("slow"); if(ad==0){ FirstOpen() ad = 99; } }) $("body>[id!=MyUpDown][id!=MyUrls][id!=Allurl]").click(function () { if($("#MyUrls").css("display")!="none"){ $("#MyUpDown").click() } }) $("#Alldownload").click(function (){ $('.MyUrls .isUrl').each(function(){ $(this).find("[class^=SaveUrl]").click() }) layer.msg("开始下载") }) $("#Allcopy").click(function (){ var urls =""; $('.MyUrls .isUrl').each(function(){ urls = urls + $(this).find("[class^=downUrl]").attr('title')+ " \n " }) GM_setClipboard(urls); //var aux = document.createElement("input"); //aux.setAttribute("value", urls); //document.body.appendChild(aux); //aux.select(); //document.execCommand("copy"); //document.body.removeChild(aux); layer.msg("已复制") }) $("#Alldel").click(function (){ $('.MyUrls .isUrl').remove() //URLs = [] GM_D.forEach(function(item){ item.forEach(function(i){ i.abort() }) }) layer.msg("已清除") }) $("#LupinStart").click( function (){ var constraints ={ //audio: true, audio:{ echoCancellation: true, autoGainControl: true, noiseSuppression:true }, surfaceSwitching: "include", video: { frameRate: { ideal: 30}, width: { ideal: 1920 }, height: { ideal: 1080 }, } }; var time = 0; var opts = { onstart: function onStart() { // Use named function. time = new Date().getTime() console.log('Recorder is started'+"\n"+'开始录屏'); $("#LupinStart").css('display','none') $("#LupinStop").css('display','inline-block') }, onstop: function onStop(blob) { time = new Date().getTime() - time; console.log('Recorder is stop'+"\n"+'录屏结束'+'\n'+'时长:'+time); stream.getTracks().forEach((track) => track.stop()); var link = document.createElement("a"); link.href = window.URL.createObjectURL(new Blob([blob])) link.download = "录屏 "+ new Date().toLocaleString().replaceAll("/",'-').replaceAll(":",'-') +".mp4"; link.click(); link.remove(); $("#LupinStop").css('display','none') $("#LupinStart").css('display','inline-block') }, mimeType: "video/webm; codecs=h264" }; window.rec = new QBMediaRecorder(opts); navigator.mediaDevices.getDisplayMedia(constraints).then((stream) => { window.stream = stream rec.start(stream); }); }) $("#LupinStop").click(function (){ rec.stop() }) $(".downUrl").on( 'input' ,function (){ //console.log($(this).val()) $(this).attr("title",$(this).val()) }) GoTop() window.onscroll = function(){ GoTop()} $("#GoTop").on('click',function(){ var timer = setInterval(function () { // 判断是否已经滚动到了顶部 if (window.pageYOffset != 0) { // 如果没到顶部就再移动一点距离(我这里是一次移动了50像素) window.scroll(0, Math.max(window.pageYOffset - 100, 0)); } else { // 如果到顶部了就停止计时器 clearInterval(timer); $("#GoTop").css("display","none") } }, 10); }) function GoTop(){ var t = document.documentElement.scrollTop || document.body.scrollTop; if( t >= 100 ) { $("#GoTop").css("display","block") } else { $("#GoTop").css("display","none") } } functionAll("") function functionAll(u){ //跳转链接 $(".GoUrl"+u).click(function (){ var url = $(this).prevAll(".downUrl"+u).attr("title") var link = document.createElement('a'); link.href = url; link.target="_blank"; link.click(); link.remove(); }) //复制链接 $(".CopyUrl"+u).click(function (){ var url = $(this).prevAll(".downUrl"+u).attr("title") GM_setClipboard(url); var aux = document.createElement("input"); aux.setAttribute("value", url); document.body.appendChild(aux); aux.select(); document.execCommand("copy"); document.body.removeChild(aux); $(this).text("已复制") }) //播放链接 $(".playUrl"+u).click(function (){ var url = $(this).prevAll(".downUrl"+u).attr("title") if(url == undefined || url.trim()=="" || url.trim().length == 0 || url.trim().split(".").filter(function(item){return item.trim() != "";}).length < 2){ layer.msg("无有效链接") }else{ dplayerUrl(url) } }) //删除此条 $(".rmUrl"+u).click(function (){ var num = $(this).prevAll('.StopSaveUrl'+u).data('num') if(num != undefined){ GM_D[num].forEach(function(item){ item.abort() }) } $(this).parent(".isUrl").remove() var list = $('.isUrl') list.each(function(i){ $(this).children("#No-isUrl").text(i+1+'、') }) }) //下载链接 $(".SaveUrl"+u).click(function (){ //$(obj).attr("disabled","disabled") var that = $(this) var url = $(that).prevAll(".downUrl"+u).val() if(url==undefined||url.trim()==''){ url = $(that).prevAll(".downUrl"+u).attr('title') if(url==undefined||url.trim()==''){return;} } var name = $(that).prevAll(".downName"+u).val() if(name==undefined||name.trim()==""){ name = $('title').text() if(name==undefined||name.trim()==""){ name = url.split("/").pop().split("?")[0] if(name==undefined||name.trim()==""){ name = "video.mp4" } } } //if(! /\.[\w]+$/.test(name)&& ! /(\.com$ | \.cn)/.test(name)){ name = name + ".mp4"} name = name.replaceAll(/\s+/ig," ").trim().replace(/(\.mp4)*$/igm,"")+".mp4" //console.log(name,url) $(that).css("display","none").next('.StopSaveUrl'+u).css("display","inline-block").text("解析中"); var request = []; var blob = []; var loadSize = []; var xhrs = 0 var num = -1 var href = location.href; GM_xmlhttpRequest({ method: "HEAD", fetch: true, url: url, headers: {'Referer': href}, onerror: function(x) { console.log("HEAD出错onerror") $(that).text("错误").css("display","inline-block").attr("title","下载出错。").next(".StopSaveUrl"+u).css("display","none").text("0%"); }, onload: function(response) { if( response.status /100 >=4){ $(that).text("错误").css("display","inline-block").attr("title","下载出错。").next(".StopSaveUrl"+u).css("display","none").text("0%"); return; } var Length =response.responseHeaders.match(/content-length:\s*[\d]+\s/im) if( Length==null||Length==undefined||Length=="" ){ if( !/\.m3u8(\?[^'"\s]*)+|(\.m3u8$)/img.test(url) ){ console.log("mp4视频下载中ing(直接下)。") mp4Download(url) return; }else{ Length = 0 } }else{ Length = parseInt(Length[0].match(/\d+/)[0]); } var Type =response.responseHeaders.match(/content-type:\s*[\S]+\s/im)[0].split(':')[1].trim().toLowerCase(); if( (Type.split('/')[0] != "video" && !/\.mp4(\?[^'"\s]*)+|(\.mp4$)/img.test(url)) && ( /\.m3u8(\?[^'"\s]*)+|(\.m3u8$)/img.test(url) || Type =="Application/vnd.apple.mpegurl" || Length <= 1024*100) ){ m3u8Download(url) }else{ //console.log("video") console.log("mp4视频多线程下载中ing。") var RangeSize = parseInt((Length/15).toFixed(0)) for(var i=0,z=0;i=Length) {range_end = Length} //console.log(range_start,range_end) eval('function onprogress'+z+' (event){'+ 'loadSize['+z+'] = event.loaded;'+ 'var x =0;'+ 'loadSize.forEach( function(item){'+ ' x = x + item'+ '});'+ 'var loaded = ( parseFloat(x / Length * 100)).toFixed(1);'+ 'if(loaded <= 100){'+ ' $(that).next(".StopSaveUrl'+u+'").text(loaded+"%"); '+ ' console.log("线程'+z+': 已下载"+event.loaded+" 总"+event.total);'+ '}'+ '}'+ 'request['+ z +'] = GM_xmlhttpRequest({'+ 'method: "GET",'+ 'url: url,'+ 'fetch: false,'+ 'responseType: "arraybuffer",'+ 'headers: { "Range":"bytes="+range_start+"-"+range_end},'+ 'onprogress: onprogress'+ z +','+ 'onload: function(response) {'+ ' blob[' + z + '] = new Blob([response.response]);' + //' console.log(blob);' + ' var x=0;y=0;' + //所有下载中线程的文件大小 ' loadSize.forEach(function(item){' + ' x = x + item' + ' });' + //所有已下载完成线程的文件大小 ' blob.forEach(function(item){'+ ' y = y +item.size'+ ' });'+ ' console.log("下完线程的文件大小:"+y +" 已下载的文件大小:"+ x +" 总:"+ Length);'+ ' if (y >= Length) {' + ' var link = document.createElement("a");' + ' link.href = window.URL.createObjectURL(new Blob(blob));' + ' link.download = name;' + ' link.click();' + ' link.remove();' + ' $(that).text("下载").css("display","inline-block").attr("title","下载").next(".StopSaveUrl'+u+'").css("display","none").text("0%");console.warn("文件下载完成:"+name)'+ ' }' + '},'+ 'onabort: function(){'+ //'$(that).text("继续").css("display","inline-block").next(".StopSaveUrl1").css("display","none").text("0%");'+ ' console.log("error!");'+ '},'+ 'onerror: function(x) {'+ //'$(that).text("错误").css("display","inline-block").next(".StopSaveUrl'+u+'").css("display","none").text("0%");'+ 'console.log("error!更换线路ing");'+ 'request.forEach(function(item){'+ ' item.abort()'+ '});'+ 'request['+z+'] = GM_download({'+ ' url: url,'+ ' name: name,'+ ' headers: {"Referer": href},'+ ' onprogress : function (event) {'+ ' if (event.lengthComputable) {'+ ' var loaded = parseFloat( event.loaded / event.total * 100 ).toFixed(2);'+ ' if(loaded >= 100){'+ ' $(that).text("下载").css("display","inline-block").attr("title","下载").next(".StopSaveUrl'+u+'").css("display","none");'+ ' }else{'+ ' $(that).next(".StopSaveUrl'+u+'").text(loaded+"%"); '+ ' }'+ ' }'+ ' },'+ ' onload : function () {'+ ' $(that).text("下载").css("display","inline-block").attr("title","下载").next(".StopSaveUrl'+u+'").css("display","none").text("0%");console.warn("文件下载完成:"+name)'+ ' },'+ ' onerror : function (x) {'+ ' console.log(x); '+ ' $(that).text("错误").css("display","inline-block").attr("title","下载出错。").next(".StopSaveUrl'+u+'").css("display","none").text("0%");'+ ' }'+ '});'+ 'var numi = parseInt( $(that).next(".StopSaveUrl'+u+'").data("num") );'+ 'GM_D[numi] = request;'+ '} '+ '});') } //console.log(request) num =GM_D.push(request) $(that).next('.StopSaveUrl'+u).data('num',num-1) } } }); function mp4Download(url){ console.log("mp4视频单线程下载中ing。") request.push(GM_download({ url: url, name: name, headers: {'Referer': href}, onprogress : function (event) { if (event.lengthComputable) { var loaded = parseFloat(event.loaded / event.total * 100).toFixed(2); if(loaded >= 100){ $(that).text("下载").css("display","inline-block").attr("title","下载").next(".StopSaveUrl"+u).css("display","none"); }else{ $(that).next(".StopSaveUrl"+u).text(loaded+".0%"); } } }, onload : function () { $(that).text("下载").css("display","inline-block").attr("title","下载").next(".StopSaveUrl"+u).css("display","none").text("0%"); console.warn("文件下载完成:"+name) }, onerror : function (x) { console.log(x) $(that).text("错误").css("display","inline-block").attr("title","下载出错。").next(".StopSaveUrl"+u).css("display","none").text("0%"); } })) num =GM_D.push(request) $(that).next('.StopSaveUrl'+u).data('num',num-1); } function m3u8Download(url){ console.log("m3u8解析下载中ing。") GM_xmlhttpRequest({ method: "GET", url: url, headers: {'Referer': href}, onerror: function(x) { console.log("m3u8 GET出错onerror") $(that).text("错误").css("display","inline-block").attr("title","下载出错。").next(".StopSaveUrl"+u).css("display","none").text("0%"); }, onload: function(response) { var err = [] var tsNum=0 var tsS = 0 var tsLength function downTs(list,tsUrl,i){ //console.log(i) request[i] = GM_xmlhttpRequest({ method: "GET", url: tsUrl, fetch: false, headers: {'Referer': href}, responseType: "arraybuffer", onloadstart: function(){ }, onload: function(response) { blob[i] = ( new Blob([response.response]) ) list0.splice(list0.indexOf(tsUrl),1) if (list0.length>0) { tsNum = parseFloat(tsNum) + 1 / tsS * 100; tsNum = tsNum >100 ? 100 : parseFloat(tsNum).toFixed(2); $(that).next(".StopSaveUrl"+u).text(tsNum+"%"); if(list.length > 0 ){ downTs(list,list.shift(),i+1) } }else { var is = true; try { var sab = new SharedArrayBuffer(1); } catch(err) { console.log( err.message +"\n 浏览器不支持SharedArrayBuffer") is = false } var link = document.createElement("a"); if(GM_getValue("ffmpeg_n", 1) == 0 && is){ (async () => { try { FFmpeg; } catch(err) { console.log( err.message +"\n 没有加载FFmpeg"); await $.ajax({ async: false, url: "https://unpkg.com/@ffmpeg/ffmpeg@0.10.0/dist/ffmpeg.min.js", dataType: "script" }); } $(that).next(".StopSaveUrl"+u).text("转码中"); const { createFFmpeg, fetchFile } = FFmpeg; const ffmpeg = createFFmpeg({ //corePath: 'https://unpkg.com/@ffmpeg/core@0.10.0/dist/ffmpeg-core.js', log: true, progress: ({ ratio }) => { tsNum = (ratio * 100.0).toFixed(2) $(that).next(".StopSaveUrl"+u).text(tsNum+"%").attr("title",'转码中'); }, }); console.log( '正在加载 ffmpeg-core.js'); await ffmpeg.load(); console.log('开始转码'); ffmpeg.FS('writeFile', 'video.ts', await fetchFile(new Blob(blob)) ); await ffmpeg.run('-i', 'video.ts' ,'output.mp4'); console.log('转码完成'); const data = ffmpeg.FS('readFile', 'output.mp4'); $(that).text("下载").css("display","inline-block").attr("title","下载").next(".StopSaveUrl"+u).css("display","none").attr("title","下载中"); link.href = window.URL.createObjectURL(new Blob([data.buffer])); link.download = name; link.click(); link.remove(); ffmpeg.exit() })(); }else{ $(that).text("下载").css("display","inline-block").attr("title","下载").next(".StopSaveUrl"+u).css("display","none").attr("title","下载中"); link.href = window.URL.createObjectURL(new Blob(blob)); link.download = name; link.click(); link.remove(); } } }, onabort: function(){ console.log("abort!"); }, onerror: function(x) { console.log("ts GET出错onerror!") if (err<10){ err = err+1 downTs(list,tsUrl,i) }else{ err = 0 $(that).text("错误").css("display","inline-block").attr("title","下载出错").next(".StopSaveUrl"+u).css("display","none").text("0%"); var num = $(that).next(".StopSaveUrl"+u).data("num") GM_D[num].forEach(function(item){ item.abort() }) } } }); } var Ts = response.responseText.trim() //console.log(Ts) var TsStart = Ts.split(/(#EXTINF[^\n]*|#EXT-X-STREAM-INF[^\n]*)/)[0]; //console.log(TsStart ) if(/^#EXTM3U/.test(TsStart)){ console.log("m3u8解析中") //layer.msg("m3u8解析中", {icon: 0}); //console.log(Ts) Ts = Ts.replaceAll(/^#(?!(EXTINF[^\n]*|EXT-X-STREAM-INF[^\n]*))[^\n]*/img,"").trim().replaceAll(/\n#/img,'??#').split('??') //console.log(Ts) Ts = Ts.filter(function(item){ return item.trim() != ""; }); //console.log(Ts); var status = "",bool ="false"; TsStart.split("\n").forEach(function(item){ if(/#EXT-X-KEY/.test(item.trim())){ status = "key" return; } if(/#EXT-X-TARGETDURATION/.test(item.trim())){ bool = "true" return; } }) if(status == "key"){ $(that).text("错误").css("display","inline-block").attr("title","m3u8加密,暂时无法解决。").next(".StopSaveUrl"+u).css("display","none").text("0%"); console.log("m3u8加密,暂时无法解决。") layer.msg("m3u8加密,暂时无法解决。", {icon: 2}); return; } //console.log(Ts) var tsUrl,tsUrl1; Ts.forEach(function(item,i){ if(/^(#EXTINF[^\n]*|#EXT-X-STREAM-INF[^\n]*)/.test(item.trim())){ tsUrl = item.trim().match(/\n.*/img)[0] //console.log(tsUrl) if(/^(\shttp:|\shttps:)/.test(tsUrl)){ //"完整链接" tsUrl = item.trim() }else{ //"不完整,需要拼接" tsUrl1 = url.split("?")[0].split("/"); tsUrl1.pop(); tsUrl1 = tsUrl1.join("/")+"/"+tsUrl.replaceAll(/\s*/img,"") tsUrl = item.trim().replaceAll(tsUrl.trim(),tsUrl1) } Ts[i] = tsUrl //console.log(tsUrl) } }) //console.log(Ts) if(bool == "true"){ console.log("m3u8没有嵌套,直接解析。") Ts.forEach(function(item,i){ Ts[i] = item.trim().match(/\n.*/img)[0].trim(); }); //console.log(Ts) tsLength = Ts.length; tsS = tsLength; var TssSize = parseInt( ( tsLength/8).toFixed(0) ) TssSize = TssSize < 1 ? 1 : TssSize; //console.log(TssSize) var list0 = Ts.slice(); for(var i=0,z=0;i < tsLength; i = i+TssSize, z++){ var range_start = i,range_end = i+TssSize; if (range_end > tsLength) {range_end = tsLength} //console.log(range_start+" __ "+range_end) var tslist = Ts.slice(range_start,range_end); //console.log(tslist) downTs(tslist, tslist.shift(),i) } num =GM_D.push(request) $(that).next('.StopSaveUrl'+u).data('num',num-1); }else{ console.log("这下边嵌套了m3u8。") var maxP='0x0',maxUrl=''; Ts.forEach(function(item,i){ tsUrl = item.split("\n",2) if( /RESOLUTION=\d+\D\d+/igm.test( tsUrl[0] )){ var P = tsUrl[0].match(/RESOLUTION=\d+\D\d+/igm)[0].match(/\d+\D\d+/igm)[0] if( maxP.split(/\D/).reduce(function(val1,val2){return val1*val2}) < P.split(/\D/).reduce(function(val1,val2){return val1*val2}) ){ maxUrl = tsUrl[1] ; maxP = P } }else{ maxUrl = tsUrl[1] return; } }) //console.log(maxP,maxUrl) //name = name.replace(/(\.mp4)*$/igm,"")+"_"+m3u8Url.split("?")[0].split("/").pop().replace(/(\.m3u8)*$/igm,"")+".mp4" GM_xmlhttpRequest({ method: "GET", url: maxUrl, headers: {'Referer': href}, onerror: function(x) { $(that).text("错误").css("display","inline-block").attr("title","下载出错。").next(".StopSaveUrl"+u).css("display","none").text("0%"); }, onload: function(response) { var Ts = response.responseText.trim() //console.log(Ts) var TsStart = Ts.split(/(#EXTINF[^\n]*)/)[0]; //console.log(TsStart ) if(/^#EXTM3U/.test(TsStart)){ console.log("嵌套m3u8解析中") layer.msg("嵌套m3u8解析中", {icon: 2}); //console.log(Ts) Ts = Ts.replaceAll(/^#(?!(EXTINF[^\n]*))[^\n]*/img,"").trim().replaceAll(/\n#/img,'??#').split('??') //console.log(Ts) Ts = Ts.filter(function(item){ return item.trim() != ""; }); //console.log(Ts); var status = "",bool ="false"; TsStart.split("\n").forEach(function(item){ if(/#EXT-X-KEY/.test(item.trim())){ status = "key" return; } }) if(status == "key"){ $(that).text("错误").css("display","inline-block").attr("title","m3u8加密,暂时无法解决。").next(".StopSaveUrl"+u).css("display","none").text("0%"); console.log("m3u8加密,暂时无法解决。") layer.msg("m3u8加密,暂时无法解决。", {icon: 2}); return; } //console.log(Ts) var tsUrl,tsUrl1; Ts.forEach(function(item,i){ if(/^(#EXTINF[^\n]*|#EXT-X-STREAM-INF[^\n]*)/.test(item.trim())){ tsUrl = item.trim().match(/\n.*/img)[0] if(/^(\shttp:|\shttps:)/.test(tsUrl)){ //"完整链接" tsUrl = item.trim() }else{ //"不完整,需要拼接" tsUrl1 = maxUrl.split("?")[0].split("/"); tsUrl1.pop(); tsUrl1 = tsUrl1.join("/")+"/"+tsUrl.replaceAll(/\s*/img,"") tsUrl = item.trim().replaceAll(tsUrl.trim(),tsUrl1) } Ts[i] = tsUrl //console.log(tsUrl) } }) //console.log(Ts) Ts.forEach(function(item,i){ Ts[i] = item.trim().match(/\n.*/img)[0].trim(); }); //console.log(Ts) tsLength = Ts.length; tsS = tsLength; var TssSize = parseInt( ( tsLength/8).toFixed(0) ) for(var i=0,z=0;i < tsLength; i = i+TssSize, z++){ var range_start = i,range_end = i+TssSize; if (range_end + 1 >= tsLength) {range_end = tsLength} //console.log(range_start+" __ "+range_end) var tslist = Ts.slice(range_start,range_end); downTs(tslist, tslist.shift(),i) } num =GM_D.push(request) $(that).next('.StopSaveUrl'+u).data('num',num-1); }else{ var link = document.createElement("a"); link.href = window.URL.createObjectURL(new Blob([response.response])); link.download = name; link.click(); link.remove(); $(that).text("下载").css("display","inline-block").attr("title","下载").next(".StopSaveUrl"+u).css("display","none").text("0%"); } } }) } }else{ var link = document.createElement("a"); link.href = window.URL.createObjectURL(new Blob([response.response])); link.download = name; link.click(); link.remove(); $(that).text("下载").css("display","inline-block").attr("title","下载").next(".StopSaveUrl"+u).css("display","none").text("0%"); } } }) } }) //停止 $(".StopSaveUrl"+u).click(function (){ var num = $(this).data("num") GM_D[num].forEach(function(item){ item.abort() }) $(this).data("num","").css("display","none").text("0%").prev(".SaveUrl"+u).text("继续").attr("title","下载中断").css("display","inline-block"); }) } function getNetworkRequsts(){ return performance.getEntriesByType("resource").filter((entry) => { return entry.initiatorType === "xmlhttprequest"||entry.initiatorType === "video"||entry.initiatorType === "iframe"; }); } var observer = new PerformanceObserver(perf_observer); observer.observe({entryTypes: ["resource"]}) function perf_observer(list,observer){ var z,m,length= 0; length = $('.MyUrls .isUrl').length var scripts =getNetworkRequsts() //console.log(scripts) scripts.forEach(function (x,i) { if (x.initiatorType === "xmlhttprequest" || (x.initiatorType === "video" && !/\.jpg/.test(x.name))) { z = x.name.trim() if(/m3u8/.test(x.name) && !/\.ts/.test(x.name) || /\.mp4$/.test(z.split('?')[0]) ){ //console.log("m3u8") //console.log(x) if(! URLs.includes(z.split("?")[0] ) ){ m = URLs.push(z.split("?")[0])-1 //console.log('type: m3u8 , url: ' + x.name) addUrl(m , z) //$(".urlnone").remove() //$(".MyUrls").append("
"+ (m+1) +"、
"+z+"
访问
复制
下载
0%
播放
  
x
") //

"+z+"

") functionAll(m) } } } if (x.initiatorType == "iframe"){ z = x.name.trim() //console.log("iframe") //console.log(x) //return GM_xmlhttpRequest({ method: "GET", fetch: false, url: z, onload: function(response) { //alert(response.responseText) var body = response.responseText.match(/\s]*(\.mp4|\.m3u8)+\?+[^"'<>\s]*)|((http:|https:)?\/{2}[^"'<>\s]*(\.mp4|\.m3u8)+(?![^'"\s]))/img) //console.log(video) if(video !=null && video !=undefined && video !=""){ video.forEach(function (str,x){ z = str.trim(); //console.log(z) if(z !=undefined&& z!= ''){ if(!/^(http:|https:)/.test(z)){ z = location.href.split("://")[0] +':'+ z.trim() } if( !URLs.includes(z.trim().split("?")[0]) && URLs.indexOf(z.trim().split("?")[0])==-1){ m =URLs.push(z.trim().split("?")[0])-1 //console.log('type: src , url: ' + z) addUrl(m , z) //$(".urlnone").remove() //$(".MyUrls").append("
"+ (m+1) +"、
"+z+"
访问
复制
下载
播放
  
x
") // $(".MyUrls").append("
"+ (m+1) +"、

"+z+"

") functionAll(m) } } }) } } } }) } //console.log(URLs) }) $("video").each(function () { //console.log("video") if(!/^blob:/.test($(this).attr('src')) ){ z = $(this).attr('src') if(z !=undefined && z.trim()!="" && ! URLs.includes(z.trim().split("?")[0])){ m =URLs.push(z.trim().split("?")[0])-1 //console.log('type: video , url: ' + $(this).attr('src')) addUrl(m , z) //$(".urlnone").remove() //$(".MyUrls").append("
"+ (m+1) +"、
"+z+"
访问
复制
下载
播放
  
x
") // $(".MyUrls").append("
"+ (m+1) +"、

"+z+"

") functionAll(m) } } }) $("source").each(function () { //console.log("source") if($(this).attr('src')!=undefined && $(this).attr('src').trim()!=''){ if(!/^(http:|https:)/.test($(this).attr('src'))){ z = location.href.split("://")[0] +':'+ $(this).attr('src') }else{ z = $(this).attr('src') } if(! URLs.includes(z.trim().split("?")[0])){ m =URLs.push(z.trim().split("?")[0])-1 //console.log('type: src , url: ' + z) addUrl(m , z) //$(".urlnone").remove() // $(".MyUrls").append("
"+ (m+1) +"、
"+z+"
访问
复制
下载
播放
  
x
") // $(".MyUrls").append("
"+ (m+1) +"、

"+z+"

") functionAll(m) } } }) if($('.MyUrls .isUrl').length > length){ if($("#MyUrls").css("display")=="none"){ $("#redPoint").css("display","block") if(GM_getValue("auto_n", 1)==0){ $("#MyUpDown").click() } } } } function addUrl(num ,url ){ $(".urlnone").remove() var no = $('.isUrl').length $(".MyUrls").append("

"+ (no+1) +"、
"+url+"
访问
复制
下载
播放
  
x
") } function mkMenu(str,keyName){ var key = GM_getValue(keyName, 1) var id = GM_registerMenuCommand(str+info[key], function() { GM_setValue(keyName, key==1? 0:1); rmMenu(id) mkMenu(str,keyName) }); } function rmMenu(id){ GM_unregisterMenuCommand(id); } function dplayerUrl(url){ var index = layer.load(2); var conf = { type: 1, //formType: 0, title: url, shadeClose: true, //点击遮罩关闭 offset: offset, // 垂直位置 fixed: true, //层固定,不随页面滚动 maxmin: true, //最大小化 resize: true, //拉伸 move: '.layui-layer-title', // 是否允许拖动 moveOut:false, //是否允许拖拽到窗口外 btn: [], area: weight, content: "
" ,success: function(layero, index){ //var unsafeWindow.dp = new DPlayer({ element: document.getElementById("dplayerUrl"), preload: 'auto', //视频预加载 hotkey: true, //键盘热键 volume: 1, //默认音量 mutex: true, //互斥 同时只有一个播放器能播放 loop: false, //循环播放 airplay: true, //在 Safari 中开启 AirPlay playbackSpeed: [0.1,0.5, 1, 1.25, 1.5, 2], //可选的播放速率 screenshot: true, //开启截图 autoplay: true, //自动播放 preventClickToggle: false, //阻止点击播放器时候自动切换播放/暂停 contextmenu: [ { text: '刷新视频', click: (player) => { //console.log(player); player.switchVideo( { url: url, type: 'auto', }, ); player.play() }, }, { text: '复制链接', click: (player) => { GM_setClipboard(url); var aux = document.createElement("input"); aux.setAttribute("value", url); document.body.appendChild(aux); aux.select(); document.execCommand("copy"); document.body.removeChild(aux); layer.msg("已复制") } } ], video: { url: url, type: 'auto', }, }); dp.video.crossOrigin=null; //dp.video.crossOrigin="anonymous"; //$("#dplayerUrl video").attr("crossOrigin","anonymous") var set = setInterval(function(){ if($('#dplayerUrl>.dplayer-video-wrap>video').length>0){ var video = $('#dplayerUrl>.dplayer-video-wrap> video[class^=dplayer-video]')[0] stopSet() //双击全屏 $('#dplayerUrl>.dplayer-video-wrap> video[class^=dplayer-video]').on("dblclick",function () { if (document.fullscreenElement == null) { dp.fullScreen.request(); } else { dp.fullScreen.cancel(); } }) //画中画 $('#dplayerUrl .dplayer-icons-right').prepend('
'+ ''+ ''+ ''+ '
') $('#dplayerUrl .dplayer-icons-right>.dplayer-hzh-icon').on('click',function(){ var that = this; if(hzh == false && !document.pictureInPictureElement){ video.requestPictureInPicture(); video.addEventListener('enterpictureinpicture', function() { // 已进入画中画模式 hzh = true; }); }else{ document.exitPictureInPicture(); video.addEventListener('leavepictureinpicture', function() { // 已退出画中画模式 hzh = false; }); } }) //刷新按钮 $('#dplayerUrl .dplayer-icons-right').prepend('
'+ ''+ ''+ ''+ '
') $('#dplayerUrl .dplayer-icons-right>.dplayer-reload-icon').on('click',function(){ dp.switchVideo( { url: url, type: 'auto', }, ); dp.play() }) } },50); function stopSet(){ clearInterval(set); } window.onresize = function () { w = window.innerWidth; h = window.innerHeight; $("#dplayerUrl").parents("div[id^=layui-layer]").css({"max-width": w,"max-height": h } ) } } } layer.close(index); layer.open(conf) } function needJs(){ GM_addStyle(GM_getResourceText("layerCss")); $("head").append(' ') GM_addElement('script', { src: 'https://quickblox.github.io/javascript-media-recorder/qbMediaRecorder.js',type: 'text/javascript' }); GM_addStyle(GM_getResourceText("DplayerCss")); $("head").append(' ') GM_addElement('script', { src: 'https://cdn.bootcdn.net/ajax/libs/hls.js/1.4.12/hls.js',type: 'text/javascript' }); GM_addElement('script', { src: 'https://cdn.bootcdn.net/ajax/libs/flv.js/1.6.2/flv.min.js',type: 'text/javascript' }); GM_addElement('script', { src: 'https://cdn.bootcdn.net/ajax/libs/shaka-player/4.3.5/shaka-player.compiled.min.js',type: 'text/javascript' }); GM_addElement('script', { src: 'https://cdn.bootcdn.net/ajax/libs/dashjs/4.6.0/dash.all.min.js',type: 'text/javascript' }); //GM_addStyle(GM_getResourceText("iconCss")); //$("head").append(' ') var x; try { x = $; } catch(err) { console.log( err.message +"\n没有加载jquery") GM_addElement('script', { src: 'https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js',type: 'text/javascript' }); } try { x = layer; } catch(err) { console.log( err.message +"\n没有加载layer") GM_addElement('script', { src: 'https://cdn.staticfile.org/layer/3.5.1/layer.min.js',type: 'text/javascript' }); } try { x = DPlayer; } catch(err) { console.log( err.message +"\n没有加载DPlayer") GM_addElement('script', { src: 'https://cdn.jsdelivr.net/npm/dplayer/dist/DPlayer.min.js',type: 'text/javascript' }); } } function me(){ var conf1 = { formType: 0, title: "支持作者,你的支持就是作者的动力!", move: false, //禁止拖动 shadeClose: true, //点击遮罩关闭 offset: '100px', // 垂直位置 resize: false, btn: ['点击关闭(点此关闭后以后不再自动弹出)'], area: weight1, content: "
" ,success: function(layero, index){ $('layui-layer-btn .layui-layer-btn0').css({'border-color': '#1e9fff !important','background-color': '#1e9fff !important','color': '#fff !important'}) } ,yes: function(index, layero){ GM_setValue("first1",99); layer.close(index) } } layer.open(conf1) return } function FirstOpen(){ var one = GM_getValue("first1", 0) if(one==0){ me(); }; } })();