diff --git a/bilibili-evolved.offline.user.js b/bilibili-evolved.offline.user.js
index 7ace60a3b..55fcd06e7 100644
--- a/bilibili-evolved.offline.user.js
+++ b/bilibili-evolved.offline.user.js
@@ -1,6 +1,6 @@
// ==UserScript==
// @name Bilibili Evolved (Offline)
-// @version 480.23
+// @version 480.30
// @description Bilibili Evolved 的离线版, 所有功能都已内置于脚本中.
// @author Grant Howard, Coulomb-G
// @copyright 2019, Grant Howard (https://github.com/the1812) & Coulomb-G (https://github.com/Coulomb-G)
@@ -1090,7 +1090,7 @@ offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/m
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video-package.min.js"] = (()=>{return(e,t)=>{class n{constructor(e={}){this.config=e;this.entries=[]}download(e,t){const a=document.createElement("a");const i=URL.createObjectURL(t);if(n.lastPackageUrl){URL.revokeObjectURL(n.lastPackageUrl)}n.lastPackageUrl=i;a.setAttribute("href",i);a.setAttribute("download",escapeFilename(e));document.body.appendChild(a);a.click();a.remove()}add(e,t){if(t===null||t===undefined){return}this.entries.push({name:escapeFilename(e),data:t})}async blob(){if(this.entries.length===0){return null}if(this.entries.length===1){const e=this.entries[0].data;return typeof e==="string"?new Blob([e]):e}const e=new JSZip;this.entries.forEach(({name:t,data:n})=>{e.file(t,n)});return await e.generateAsync({type:"blob"})}async emit(e){if(this.entries.length===0){return}if(!e||this.entries.length===1){e=this.entries[0].name}const t=await this.blob();if(!t){return}return this.download(e,t)}static async single(e,t,a={}){const i=new n(a);i.add(e,t);return await i.emit()}}n.lastPackageUrl="";return{export:{DownloadVideoPackage:n}}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.css"] = `.download-video{--download-video-background:white;--download-video-foreground:black;position:absolute;top:96px;left:50%;transform:translateX(-50%) scale(.95);background:var(--download-video-background);color:var(--download-video-foreground);box-shadow:rgba(0,0,0,.2) 0 4px 8px 0;z-index:10001;pointer-events:none;opacity:0;padding:16px;width:300px;display:flex;flex-direction:column;align-items:stretch;justify-content:space-between}.download-video,.download-video *{transition:.2s ease-out;-webkit-tap-highlight-color:transparent!important}.download-video.opened{pointer-events:initial;opacity:1;transform:translateX(-50%) scale(1)}body.dark .download-video{--download-video-background:#222;--download-video-foreground:#eee}.round-corner .download-video,.round-corner .download-video .episode-list .v-checkbox,.round-corner .download-video .rpc-settings{border-radius:var(--large-corner-radius)}.round-corner .download-video .button,.round-corner .download-video .cover,.round-corner .download-video .direct-download .progress .background,.round-corner .download-video .direct-download .progress .foreground,.round-corner .download-video .rpc-settings input[type=text],.round-corner .download-video .title,.round-corner .download-video button{border-radius:var(--corner-radius)}.download-video .cover{min-height:100px;max-height:120px;object-fit:contain}.download-video h1{font-size:13pt;font-weight:700;color:var(--download-video-foreground)}.download-video h2{font-size:11pt;font-weight:700;color:var(--download-video-foreground)}.download-video .header{display:flex;justify-content:space-between;align-items:center}.download-video .header .grow{flex-grow:1}.download-video .header .mdi-download{font-size:16pt;color:var(--download-video-foreground);margin-right:8px}.download-video .header .mdi-close{font-size:16pt;color:var(--download-video-foreground);cursor:pointer}.download-video .header .mdi-close:hover{color:var(--theme-color)}.download-video .info{display:flex;flex-direction:column;align-items:center;margin-top:12px}.download-video .title{display:flex;flex-direction:column;justify-content:space-between;align-items:stretch;margin-top:12px}.download-video .title .bold{width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center}.download-video .title .size{font-size:10pt;color:var(--download-video-foreground);align-self:center;display:flex;align-items:center;height:24px}.download-video .bold{color:var(--download-video-foreground);font-weight:700;font-size:12pt}.download-video .option-item{display:flex;justify-content:space-between;align-items:center;padding-top:12px;font-size:10pt}.download-video .tabs{display:flex;padding:12px 0;font-size:10pt}.download-video .tabs .tab{cursor:pointer;position:relative;opacity:.5}.download-video .tabs .tab.active{font-weight:700;opacity:1}.download-video .tabs .tab:not(:last-child){margin-right:16px}.download-video .tabs .tab::after{content:"";position:absolute;border-radius:2px;background-color:var(--theme-color);height:3px;width:80%;left:10%;bottom:-8px;transition:.2s ease-out;transform:scaleX(0)}.download-video .tabs .tab.active::after{transform:scaleX(1)}.download-video .separator{height:1px;background:#8884;width:100%;margin:12px 0;flex-shrink:0}.download-video .direct-download{display:flex;flex-direction:column;align-items:start;justify-content:space-between}.download-video .button,.download-video button{border:none;outline:0!important;padding:6px 16px;font-size:10pt;cursor:pointer;background:#8884;color:var(--download-video-foreground)}.download-video .button:hover,.download-video button:hover{background:#8886}.download-video .primary{background:var(--theme-color);color:var(--foreground-color);align-self:center}.download-video .primary:hover{background:var(--theme-color-90)}.download-video .busy .button,.download-video .busy .primary,.download-video .busy button,.download-video button:disabled{background-color:#0001;color:#8884;cursor:not-allowed}.download-video .busy .button,.download-video .busy button{cursor:wait!important}.download-video .direct-download .progress{align-self:stretch;display:flex;align-items:center;margin-top:8px}.download-video .direct-download .progress .background{flex-grow:1;height:4px;background:#8884;margin-right:4px;position:relative}.download-video .direct-download .progress .background .foreground{position:absolute;top:0;left:0;height:4px;background:linear-gradient(to right,var(--theme-color),var(--theme-color-60))}.download-video .direct-download .progress .percent{width:50px;text-align:right}.download-video .actions{display:flex;flex-wrap:wrap;justify-content:space-between;margin:8px -4px 0}.download-video .actions>*{margin:4px;flex-grow:1;flex-basis:calc(50% - 16px);display:flex;justify-content:center;align-items:center}.download-video i.mdi-alert-circle{font-size:14pt;color:#ff9800}.download-video .size-warning{position:relative;padding:0 8px}.download-video .size-warning-tip{position:absolute;bottom:100%;left:50%;transform:translateX(-50%);background:var(--download-video-background);color:var(--download-video-foreground);border:1px dashed var(--theme-color);z-index:2;font-size:10pt;width:200px;padding:8px;box-shadow:rgba(0,0,0,.2) 0 4px 8px 0;pointer-events:none;opacity:0}.download-video .size-warning:hover .size-warning-tip{opacity:1}.download-video .episode-list .v-checkbox{padding:4px 8px;margin:4px 0;position:relative;background-color:transparent}.download-video .episode-list .v-checkbox.checked{background-color:#8882}.download-video .episode-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}.download-video .episode-list{overflow:auto;max-height:320px}.download-video button.list-tool{padding:4px;line-height:1;font-size:12pt;margin:0 4px}.download-video .episode-header h2{flex-grow:1}.download-video .selected-count{width:64px;text-align:right}.download-video .aria2-rpc .mdi{margin-left:8px;font-size:14pt;line-height:1}.download-video .aria2-rpc{position:relative}.download-video .rpc-settings{position:absolute;display:flex;flex-direction:column;align-items:stretch;color:var(--download-video-foreground);background:#fff;bottom:120%;left:50%;cursor:initial;box-shadow:rgba(0,0,0,.2) 0 4px 8px 0;transform-origin:bottom;transform:translateX(-50%) scale(.9);opacity:0;pointer-events:none;padding:8px;z-index:3;transition:.3s cubic-bezier(.18,.89,.32,1.28);width:120%}body.dark .download-video .rpc-settings{background:#282828}.download-video .rpc-settings>*{margin:8px}.download-video .rpc-settings.show{opacity:1;transform:translateX(-50%) scale(1);pointer-events:initial}.download-video .rpc-settings input[type=text]{background:0 0;color:var(--download-video-foreground);border:1px solid #8884;padding:4px;margin-left:8px}.download-video .rpc-settings input[type=text]:focus{border-color:var(--theme-color)}.download-video .rpc-settings .operations{display:flex;align-items:center;justify-content:space-evenly}.download-video .final-dir{word-break:break-all}.download-video .rpc-settings-item{display:flex;align-items:center;justify-content:space-between;white-space:nowrap}.download-video .rpc-settings-item input[type=text]{flex-grow:1;margin-left:24px}.download-video button.cancel-download,.download-video button.start-download{margin-top:8px}.download-video .direct-download-header{align-self:stretch;display:flex;justify-content:space-between;align-items:center}body.dark .download-video .direct-download .progress .foreground{background:linear-gradient(to right,var(--theme-color-70),var(--theme-color))}`;
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.html"] = `
![]()
警告: 过大的视频大小会在直接下载时占用大量内存, 并可能导致浏览器标签页崩溃. 请考虑降低清晰度或使用导出选项.
预计大小: {{displaySize}}导出
`;
-offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.js"] = (()=>{return(t,e)=>{const{getFriendlyTitle:s}=e.import("title");const{VideoInfo:a,DanmakuInfo:i}=e.import("video-info");const{DownloadVideoPackage:n}=e.import("download-video-package");class o{async getDashUrl(t){if(t){return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&fnver=0&fnval=16`}else{return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&fnver=0&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&otype=json`}}}class r extends o{async getDashUrl(t){if(t){return`https://api.bilibili.com/pgc/player/web/playurl?avid=56995872&cid=99547543&qn=${t}&otype=json&fourk=1&fnval=16`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=56995872&cid=99547543&otype=json&fourk=1&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=&otype=json`}}}class l extends o{constructor(t){super();this.ep=t}async getDashUrl(t){if(t){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&ep_id=${this.ep}`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&ep_id=${this.ep}`}}}const c={entity:new o,aid:"",cid:""};let d=[];let p=null;class h{constructor(t,e,s){this.quality=t;this.internalName=e;this.displayName=s}async downloadInfo(t=false){const e=new u(this);await e.fetchVideoInfo(t);return e}static parseFormats(t){const e=t.accept_quality;const s=t.accept_format.split(",");const a=t.accept_description;const i=e.map((t,e)=>{return new h(t,s[e],a[e])});return i}static async getAvailableDashFormats(){const t=await c.entity.getDashUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}return h.parseFormats(e.data||e.result||e)}static async getAvailableFormats(){const t=await c.entity.getUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}const s=e.data||e.result||e;return h.parseFormats(s)}}class u{constructor(t,e){this.fragmentSplitFactor=6*2;this.workingXhr=null;this.progressMap=new Map;this.format=t;this.fragments=e||[];this.videoSpeed=new f(this)}get danmakuOption(){return t.downloadVideoDefaultDanmaku}get isDash(){return this.fragments.some(t=>t.url.includes(".m4s"))}get totalSize(){return this.fragments.map(t=>t.size).reduce((t,e)=>t+e)}async fetchVideoInfo(s=false){if(!s){const t=await c.entity.getUrl(this.format.quality);const e=await Ajax.getTextWithCredentials(t);const s=JSON.parse(e.replace(/http:/g,"https:"));const a=s.data||s.result||s;if(a.quality!==this.format.quality){throw new Error("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const i=a.durl;this.fragments=i.map(t=>{return{length:t.length,size:t.size,url:t.url,backupUrls:t.backup_url}})}else{const{dashToFragment:s,getDashInfo:a}=await e.importAsync("video-dash");const i=await a(await c.entity.getDashUrl(this.format.quality),this.format.quality);console.log(i.videoDashes);const n=(()=>{const e=e=>e.videoCodec===t.downloadVideoDashCodec;if(i.videoDashes.some(e)){return i.videoDashes.filter(e).sort(ascendingSort(t=>t.bandWidth))[0]}else{return i.videoDashes.sort(ascendingSort(t=>t.bandWidth))[0]}})();const o=i.audioDashes.sort(descendingSort(t=>t.bandWidth))[0];this.fragments=[s(n),s(o)]}return this.fragments}updateProgress(){const t=this.progressMap?[...this.progressMap.values()].reduce((t,e)=>t+e,0)/this.totalSize:0;if(t>1||t<0){console.error(`[下载视频] 进度异常: ${t}`,this.progressMap.values())}this.progress&&this.progress(t)}cancelDownload(){this.videoSpeed.stopMeasure();if(this.workingXhr!==null){this.workingXhr.forEach(t=>t.abort())}else{logError("Cancel Download Failed: forEach in this.workingXhr not found.")}}downloadFragment(t){const e=[];const s=this.isDash?4*1024*1024:16*1024*1024;let a;if(t.size<=s*6){a=t.size/this.fragmentSplitFactor}else{a=s}let i=0;const n=t=>[...this.progressMap.keys()].indexOf(t)+1;while(i{const a=new XMLHttpRequest;a.open("GET",t.url);a.responseType="arraybuffer";a.withCredentials=false;a.addEventListener("progress",t=>{console.log(`[下载视频] 视频片段${n(a)}下载进度: ${t.loaded}/${r} bytes loaded, ${o}`);this.progressMap.set(a,t.loaded);this.updateProgress()});a.addEventListener("load",()=>{if((""+a.status)[0]==="2"){console.log(`[下载视频] 视频片段${n(a)}下载完成`);e(a.response)}else{s(`视频片段${n(a)}请求失败, response = ${a.status}`)}});a.addEventListener("abort",()=>s("canceled"));a.addEventListener("error",()=>{console.error(`[下载视频] 视频片段${n(a)}下载失败: ${o}`);this.progressMap.set(a,0);this.updateProgress();a.open("GET",t.url);a.setRequestHeader("Range",o);a.send()});a.setRequestHeader("Range",o);this.progressMap.set(a,0);a.send();this.workingXhr.push(a)}));i=Math.round(i+a)+1}return Promise.all(e)}async copyUrl(){const t=this.fragments.map(t=>t.url).reduce((t,e)=>t+"\r\n"+e);GM.setClipboard(t,"text")}async showUrl(){const t=this.fragments.map(t=>`\n${t.url}\n`).reduce((t,e)=>t+"\r\n"+e);Toast.success(t+`复制全部`,"显示链接");const e=await SpinQuery.select("#copy-link");e.addEventListener("click",async()=>{await this.copyUrl()})}async exportData(t=false){const e=JSON.stringify([{fragments:this.fragments,title:s(),totalSize:this.fragments.map(t=>t.size).reduce((t,e)=>t+e),referer:document.URL.replace(window.location.search,"")}]);if(t){GM.setClipboard(e,"text")}else{const t=new Blob([e],{type:"text/json"});const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.json`,t);i.add(s()+"."+this.danmakuOption.toLowerCase(),a);await i.emit(`${s()}.zip`)}}async exportAria2(a=false){if(a){const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.${this.danmakuOption==="ASS"?"ass":"xml"}`,a);await i.emit();const o=t.aria2RpcOption;const r=this.fragments.map((t,e)=>{let a="";if(this.fragments.length>1){a=" - "+(e+1)}const i=[];if(o.secretKey!==""){i.push(`token:${o.secretKey}`)}i.push([t.url]);i.push({referer:document.URL.replace(window.location.search,""),"user-agent":UserAgent,out:`${s()}${a}${this.extension(t)}`,split:this.fragmentSplitFactor,dir:o.baseDir+o.dir||undefined,"max-download-limit":o.maxDownloadLimit||undefined});const n=encodeURIComponent(`${s()}${a}`);return{params:i,id:n}});const{sendRpc:l}=await e.importAsync("aria2-rpc");await l(r)}else{const t=`\n# Generated by Bilibili Evolved Video Export\n# https://github.com/the1812/Bilibili-Evolved/\n${this.fragments.map((t,e)=>{let a="";if(this.fragments.length>1){a=" - "+(e+1)}return`\n${t.url}\n referer=${document.URL.replace(window.location.search,"")}\n user-agent=${UserAgent}\n out=${s()}${a}${this.extension(t)}\n split=${this.fragmentSplitFactor}\n`.trim()}).join("\n")}\n`.trim();const e=new Blob([t],{type:"text/plain"});const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.txt`,e);i.add(s()+"."+this.danmakuOption.toLowerCase(),a);await i.emit(`${s()}.zip`)}}extension(t){const e=t||this.fragments[0];const s=[".flv",".mp4",".m4s"].find(t=>e.url.includes(t));if(s){return s}else{console.warn("No extension detected.");return".flv"}}async downloadDanmaku(){if(this.danmakuOption!=="无"){const t=new i(c.cid);await t.fetchInfo();if(this.danmakuOption==="XML"){return t.rawXML}else{const{convertToAss:s}=await e.importAsync("download-danmaku");return s(t.rawXML)}}else{return null}}async download(){this.workingXhr=[];this.progressMap=new Map;this.updateProgress();const t=[];this.videoSpeed.startMeasure();for(const e of this.fragments){const s=await this.downloadFragment(e);t.push(s)}if(t.length<1){throw new Error("下载失败.")}const e=s();const a=new n;t.forEach((s,i)=>{let n;const o=this.fragments[i];if(t.length>1){n=`${e} - ${i+1}${this.extension(o)}`}else{n=`${e}${this.extension(o)}`}a.add(n,new Blob(Array.isArray(s)?s:[s],{type:this.extension(o)===".flv"?"video/x-flv":"video/mp4"}))});const i=await this.downloadDanmaku();a.add(`${s()}.${this.danmakuOption==="ASS"?"ass":"xml"}`,i);await a.emit(e+".zip");this.progress&&this.progress(0);this.videoSpeed.stopMeasure()}}class f{constructor(t){this.lastProgress=0;this.measureInterval=1e3;this.workingDownloader=t}startMeasure(){this.intervalTimer=setInterval(()=>{const t=this.workingDownloader.progressMap?[...this.workingDownloader.progressMap.values()].reduce((t,e)=>t+e,0):0;const e=t-this.lastProgress;if(this.speedUpdate!==undefined){this.speedUpdate(formatFileSize(e)+"/s")}this.lastProgress=t},this.measureInterval)}stopMeasure(){clearInterval(this.intervalTimer)}}async function m(){const t=await SpinQuery.select(()=>(unsafeWindow||window).aid);const e=await SpinQuery.select(()=>(unsafeWindow||window).cid);if(!(t&&e)){return false}c.aid=t;c.cid=e;if(document.URL.includes("bangumi")){c.entity=new r}else if(document.URL.includes("cheese")){const t=document.URL.match(/cheese\/play\/ep([\d]+)/);c.entity=new l(t[1])}else{c.entity=new o}try{d=await h.getAvailableFormats()}catch(t){return false}return true}async function w(){p=d[0];e.applyStyle("downloadVideoStyle");const t=dq("#download-video");t.addEventListener("click",()=>{const t=dq(".download-video");t.classList.toggle("opened");window.scroll(0,0);dq(".gui-settings-mask").click()});t.addEventListener("mouseover",()=>{document.body.insertAdjacentHTML("beforeend",e.import("downloadVideoHtml"));g()},{once:true})}async function g(){let o;const r=new Vue({el:".download-video",components:{VDropdown:()=>e.importAsync("v-dropdown.vue"),VCheckbox:()=>e.importAsync("v-checkbox.vue"),RpcProfiles:()=>e.importAsync("aria2-rpc-profiles.vue")},data:{downloadSingle:true,coverUrl:EmptyImageUrl,aid:c.aid,cid:c.cid,dashModel:{value:t.downloadVideoFormat,items:["flv","dash"]},qualityModel:{value:p.displayName,items:d.map(t=>t.displayName)},danmakuModel:{value:t.downloadVideoDefaultDanmaku,items:["无","XML","ASS"]},codecModel:{value:t.downloadVideoDashCodec,items:["AVC/H.264","HEVC/H.265"]},progressPercent:0,size:"获取大小中",blobUrl:"",episodeList:[],downloading:false,speed:"",batch:false,rpcSettings:t.aria2RpcOption,showRpcSettings:false,busy:false,saveRpcSettingsText:"保存配置",enableDash:t.enableDashDownload,lastDirectDownloadLink:""},computed:{displaySize(){if(typeof this.size==="string"){return this.size}return formatFileSize(this.size)},sizeWarning(){if(typeof this.size==="string"){return false}return this.size>1073741824},selectedEpisodeCount(){return this.episodeList.filter(t=>t.checked).length},dash(){return this.dashModel.value==="dash"}},methods:{close(){this.$el.classList.remove("opened")},danmakuOptionChange(){t.downloadVideoDefaultDanmaku=this.danmakuModel.value},async codecChange(){t.downloadVideoDashCodec=this.codecModel.value;await this.formatChange()},async dashChange(){console.log("dash change");t.downloadVideoFormat=this.dashModel.value;const e=this.dashModel.value;let s=[];if(e==="flv"){s=await h.getAvailableFormats()}else{s=await h.getAvailableDashFormats()}d=s;[p]=e;this.qualityModel.items=s.map(t=>t.displayName);[this.qualityModel.value]=this.qualityModel.items;await this.formatChange()},async formatChange(){console.log("format change");const t=this.getFormat();try{this.size="获取大小中";const e=await t.downloadInfo(this.dash);this.size=e.totalSize}catch(t){this.size="获取大小失败";throw t}},getFormat(){const t=d.find(t=>t.displayName===this.qualityModel.value);if(!t){console.error(`No format found. model value = ${this.qualityModel.value}`);return null}return t},async exportData(t){if(this.busy===true){return}try{this.busy=true;if(!this.downloadSingle){await this.exportBatchData(t);return}const a=this.getFormat();const i=await a.downloadInfo(this.dash);switch(t){case"copyLink":await i.copyUrl();Toast.success("已复制链接到剪贴板.","下载视频",3e3);break;case"showLink":await i.showUrl();break;case"aria2":await i.exportAria2(false);break;case"aria2RPC":await i.exportAria2(true);break;case"copyVLD":await i.exportData(true);Toast.success("已复制VLD数据到剪贴板.","下载视频",3e3);break;case"exportVLD":await i.exportData(false);break;case"ffmpegFragments":if(i.fragments.length<2){Toast.info("当前视频没有分段.","分段列表",3e3)}else{const{getFragmentsList:t}=await e.importAsync("ffmpeg-support");const a=new n;a.add("ffmpeg-files.txt",t(i.fragments.length,s(),i.extension(i.fragments[0])));await a.emit()}break;default:break}}catch(t){logError(t)}finally{this.busy=false}},async exportBatchData(t){const a=this.episodeList;if(a.every(t=>t.checked===false)){Toast.info("请至少选择1集或以上的数量!","批量导出",3e3);return}const o=t=>{const e=a.find(e=>e.cid===t.cid);if(e===undefined){return false}return e.checked};const r=this.getFormat();if(this.danmakuModel.value!=="无"){const t=Toast.info("下载弹幕中...","批量导出");const s=new n;try{if(this.danmakuModel.value==="XML"){for(const t of a.filter(o)){const e=new i(t.cid);await e.fetchInfo();s.add(t.title+".xml",e.rawXML)}}else{const{convertToAss:t}=await e.importAsync("download-danmaku");for(const e of a.filter(o)){const a=new i(e.cid);await a.fetchInfo();s.add(e.title+".ass",await t(a.rawXML))}}await s.emit(this.cid+".danmakus.zip")}catch(t){logError(`弹幕下载失败`)}finally{t.dismiss()}}const l=Toast.info("获取链接中...","批量导出");const c=this.batchExtractor;c.itemFilter=o;let d;try{switch(t){case"aria2":d=await c.collectAria2(r,l,false);await n.single(s(false)+".txt",new Blob([d],{type:"text/plain"}),{ffmpeg:this.ffmpegOption});return;case"aria2RPC":await c.collectAria2(r,l,true);Toast.success(`成功发送了批量请求.`,"aria2 RPC",3e3);return;case"copyVLD":GM.setClipboard(await c.collectData(r,l),{mimetype:"text/plain"});Toast.success("已复制批量vld数据到剪贴板.","批量导出",3e3);return;case"exportVLD":d=await c.collectData(r,l);await n.single(s(false)+".json",new Blob([d],{type:"text/json"}),{ffmpeg:this.ffmpegOption});return;case"ffmpegFragments":{const t=await c.getRawItems(r);const a=new u(r,t[0].fragments);const{getBatchFragmentsList:i}=await e.importAsync("ffmpeg-support");const o=i(t,a.extension());if(!o){Toast.info("所有选择的分P都没有分段.","分段列表",3e3)}else{const t=new n;for(const[e,s]of o.entries()){t.add(e,s)}await t.emit(escapeFilename(`${s(false)}.zip`))}}break;case"ffmpegEpisodes":{const t=await c.getRawItems(r);const s=new u(r,t[0].fragments);const{getBatchEpisodesList:a}=await e.importAsync("ffmpeg-support");const i=a(t,s.extension());const o=new n;o.add("ffmpeg-files.txt",i);await o.emit()}break;default:return}}catch(t){logError(t)}finally{l.dismiss()}},async checkBatch(){const t=["/www.bilibili.com/bangumi","/www.bilibili.com/video/av"];if(!t.some(t=>document.URL.includes(t))){this.batch=false;this.episodeList=[];return}const{BatchExtractor:s}=await e.importAsync("batch-download");if(await s.test()!==true){this.batch=false;this.episodeList=[];return}const a=this.batchExtractor=new s;this.batch=true;this.episodeList=(await a.getItemList()).map((t,e)=>{return{aid:t.aid,cid:t.cid,title:t.title,index:e,checked:true}})},cancelDownload(){if(o){o.cancelDownload()}},async startDownload(){const t=this.getFormat();try{this.downloading=true;const e=await t.downloadInfo(this.dash);e.videoSpeed.speedUpdate=(t=>this.speed=t);e.progress=(t=>{this.progressPercent=Math.trunc(t*100)});o=e;await e.download();this.lastDirectDownloadLink=n.lastPackageUrl}catch(t){if(t!=="canceled"){logError(t)}this.progressPercent=0}finally{this.downloading=false;this.speed=""}},selectAllEpisodes(){this.episodeList.forEach(t=>t.checked=true)},unselectAllEpisodes(){this.episodeList.forEach(t=>t.checked=false)},inverseAllEpisodes(){this.episodeList.forEach(t=>t.checked=!t.checked)},toggleRpcSettings(){this.showRpcSettings=!this.showRpcSettings},saveRpcSettings(){if(this.rpcSettings.host===""){this.rpcSettings.host="127.0.0.1"}if(this.rpcSettings.port===""){this.rpcSettings.port="6800"}t.aria2RpcOption=this.rpcSettings;const e=t.aria2RpcOptionProfiles.find(e=>e.name===t.aria2RpcOptionSelectedProfile);if(e){Object.assign(e,this.rpcSettings);t.aria2RpcOptionProfiles=t.aria2RpcOptionProfiles}this.saveRpcSettingsText="已保存";setTimeout(()=>this.saveRpcSettingsText="保存配置",2e3)},updateProfile(e){t.aria2RpcOption=this.rpcSettings=_.omit(e,"name")}},async mounted(){}});Observer.videoChange(async()=>{r.close();r.batch=false;r.downloadSingle=true;const t=dq("#download-video");const e=await m();t.style.display=e?"flex":"none";if(!e){return}r.aid=c.aid;r.cid=c.cid;try{const t=new a(c.aid);await t.fetchInfo();r.coverUrl=t.coverUrl.replace("http:","https:")}catch(t){r.coverUrl=EmptyImageUrl}r.dashChange();await r.checkBatch()})}return{widget:{content:`\n`,condition:m,success:w}}}})();
+offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.js"] = (()=>{return(t,e)=>{const{getFriendlyTitle:s}=e.import("title");const{VideoInfo:a,DanmakuInfo:i}=e.import("video-info");const{DownloadVideoPackage:n}=e.import("download-video-package");class o{async getDashUrl(t){if(t){return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&fnver=0&fnval=16`}else{return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&fnver=0&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&otype=json`}}}class r extends o{async getDashUrl(t){if(t){return`https://api.bilibili.com/pgc/player/web/playurl?avid=56995872&cid=99547543&qn=${t}&otype=json&fourk=1&fnval=16`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=56995872&cid=99547543&otype=json&fourk=1&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=&otype=json`}}}class l extends o{constructor(t){super();this.ep=t}async getDashUrl(t){if(t){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&ep_id=${this.ep}`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&ep_id=${this.ep}`}}}const c={entity:new o,aid:"",cid:""};let d=[];let p=null;class h{constructor(t,e,s){this.quality=t;this.internalName=e;this.displayName=s}async downloadInfo(t=false){const e=new u(this);await e.fetchVideoInfo(t);return e}static parseFormats(t){const e=t.accept_quality;const s=t.accept_format.split(",");const a=t.accept_description;const i=e.map((t,e)=>{return new h(t,s[e],a[e])});return i}static async getAvailableDashFormats(){const t=await c.entity.getDashUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}return h.parseFormats(e.data||e.result||e)}static async getAvailableFormats(){const t=await c.entity.getUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}const s=e.data||e.result||e;return h.parseFormats(s)}}class u{constructor(t,e){this.fragmentSplitFactor=6*2;this.workingXhr=null;this.progressMap=new Map;this.format=t;this.fragments=e||[];this.videoSpeed=new f(this)}get danmakuOption(){return t.downloadVideoDefaultDanmaku}get isDash(){return this.fragments.some(t=>t.url.includes(".m4s"))}get totalSize(){return this.fragments.map(t=>t.size).reduce((t,e)=>t+e)}async fetchVideoInfo(s=false){if(!s){const t=await c.entity.getUrl(this.format.quality);const e=await Ajax.getTextWithCredentials(t);const s=JSON.parse(e.replace(/http:/g,"https:"));const a=s.data||s.result||s;if(a.quality!==this.format.quality){throw new Error("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const i=a.durl;this.fragments=i.map(t=>{return{length:t.length,size:t.size,url:t.url,backupUrls:t.backup_url}})}else{const{dashToFragment:s,getDashInfo:a}=await e.importAsync("video-dash");const i=await a(await c.entity.getDashUrl(this.format.quality),this.format.quality);console.log(i.videoDashes);const n=(()=>{const e=e=>e.videoCodec===t.downloadVideoDashCodec;if(i.videoDashes.some(e)){return i.videoDashes.filter(e).sort(ascendingSort(t=>t.bandWidth))[0]}else{return i.videoDashes.sort(ascendingSort(t=>t.bandWidth))[0]}})();const o=i.audioDashes.sort(descendingSort(t=>t.bandWidth))[0];this.fragments=[s(n),s(o)]}return this.fragments}updateProgress(){const t=this.progressMap?[...this.progressMap.values()].reduce((t,e)=>t+e,0)/this.totalSize:0;if(t>1||t<0){console.error(`[下载视频] 进度异常: ${t}`,this.progressMap.values())}this.progress&&this.progress(t)}cancelDownload(){this.videoSpeed.stopMeasure();if(this.workingXhr!==null){this.workingXhr.forEach(t=>t.abort())}else{logError("Cancel Download Failed: forEach in this.workingXhr not found.")}}downloadFragment(t){const e=[];const s=this.isDash?4*1024*1024:16*1024*1024;let a;if(t.size<=s*6){a=t.size/this.fragmentSplitFactor}else{a=s}let i=0;const n=t=>[...this.progressMap.keys()].indexOf(t)+1;while(i{const a=new XMLHttpRequest;a.open("GET",t.url);a.responseType="arraybuffer";a.withCredentials=false;a.addEventListener("progress",t=>{console.log(`[下载视频] 视频片段${n(a)}下载进度: ${t.loaded}/${r} bytes loaded, ${o}`);this.progressMap.set(a,t.loaded);this.updateProgress()});a.addEventListener("load",()=>{if((""+a.status)[0]==="2"){console.log(`[下载视频] 视频片段${n(a)}下载完成`);e(a.response)}else{s(`视频片段${n(a)}请求失败, response = ${a.status}`)}});a.addEventListener("abort",()=>s("canceled"));a.addEventListener("error",()=>{console.error(`[下载视频] 视频片段${n(a)}下载失败: ${o}`);this.progressMap.set(a,0);this.updateProgress();a.open("GET",t.url);a.setRequestHeader("Range",o);a.send()});a.setRequestHeader("Range",o);this.progressMap.set(a,0);a.send();this.workingXhr.push(a)}));i=Math.round(i+a)+1}return Promise.all(e)}async copyUrl(){const t=this.fragments.map(t=>t.url).reduce((t,e)=>t+"\r\n"+e);GM.setClipboard(t,"text")}async showUrl(){const t=this.fragments.map(t=>`\n${t.url}\n`).reduce((t,e)=>t+"\r\n"+e);Toast.success(t+`复制全部`,"显示链接");const e=await SpinQuery.select("#copy-link");e.addEventListener("click",async()=>{await this.copyUrl()})}async exportData(t=false){const e=JSON.stringify([{fragments:this.fragments,title:s(),totalSize:this.fragments.map(t=>t.size).reduce((t,e)=>t+e),referer:document.URL.replace(window.location.search,"")}]);if(t){GM.setClipboard(e,"text")}else{const t=new Blob([e],{type:"text/json"});const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.json`,t);i.add(s()+"."+this.danmakuOption.toLowerCase(),a);await i.emit(`${s()}.zip`)}}async exportAria2(a=false){if(a){const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.${this.danmakuOption==="ASS"?"ass":"xml"}`,a);await i.emit();const o=t.aria2RpcOption;const r=this.fragments.map((t,e)=>{let a="";if(this.fragments.length>1&&!this.isDash){a=" - "+(e+1)}const i=[];if(o.secretKey!==""){i.push(`token:${o.secretKey}`)}i.push([t.url]);i.push({referer:document.URL.replace(window.location.search,""),"user-agent":UserAgent,out:`${s()}${a}${this.extension(t)}`,split:this.fragmentSplitFactor,dir:o.baseDir+o.dir||undefined,"max-download-limit":o.maxDownloadLimit||undefined});const n=encodeURIComponent(`${s()}${a}`);return{params:i,id:n}});const{sendRpc:l}=await e.importAsync("aria2-rpc");await l(r)}else{const t=`\n# Generated by Bilibili Evolved Video Export\n# https://github.com/the1812/Bilibili-Evolved/\n${this.fragments.map((t,e)=>{let a="";if(this.fragments.length>1&&!this.isDash){a=" - "+(e+1)}return`\n${t.url}\n referer=${document.URL.replace(window.location.search,"")}\n user-agent=${UserAgent}\n out=${s()}${a}${this.extension(t)}\n split=${this.fragmentSplitFactor}\n`.trim()}).join("\n")}\n`.trim();const e=new Blob([t],{type:"text/plain"});const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.txt`,e);i.add(s()+"."+this.danmakuOption.toLowerCase(),a);await i.emit(`${s()}.zip`)}}extension(t){const e=t||this.fragments[0];const s=[".flv",".mp4"].find(t=>e.url.includes(t));if(s){return s}else if(e.url.includes(".m4s")){return this.fragments.indexOf(e)===0?".mp4":".m4a"}else{console.warn("No extension detected.");return".flv"}}async downloadDanmaku(){if(this.danmakuOption!=="无"){const t=new i(c.cid);await t.fetchInfo();if(this.danmakuOption==="XML"){return t.rawXML}else{const{convertToAss:s}=await e.importAsync("download-danmaku");return s(t.rawXML)}}else{return null}}async download(){this.workingXhr=[];this.progressMap=new Map;this.updateProgress();const t=[];this.videoSpeed.startMeasure();for(const e of this.fragments){const s=await this.downloadFragment(e);t.push(s)}if(t.length<1){throw new Error("下载失败.")}const e=s();const a=new n;t.forEach((s,i)=>{let n;const o=this.fragments[i];if(t.length>1&&!this.isDash){n=`${e} - ${i+1}${this.extension(o)}`}else{n=`${e}${this.extension(o)}`}a.add(n,new Blob(Array.isArray(s)?s:[s]))});const i=await this.downloadDanmaku();a.add(`${s()}.${this.danmakuOption==="ASS"?"ass":"xml"}`,i);await a.emit(e+".zip");this.progress&&this.progress(0);this.videoSpeed.stopMeasure()}}class f{constructor(t){this.lastProgress=0;this.measureInterval=1e3;this.workingDownloader=t}startMeasure(){this.intervalTimer=setInterval(()=>{const t=this.workingDownloader.progressMap?[...this.workingDownloader.progressMap.values()].reduce((t,e)=>t+e,0):0;const e=t-this.lastProgress;if(this.speedUpdate!==undefined){this.speedUpdate(formatFileSize(e)+"/s")}this.lastProgress=t},this.measureInterval)}stopMeasure(){clearInterval(this.intervalTimer)}}async function m(){const t=await SpinQuery.select(()=>(unsafeWindow||window).aid);const e=await SpinQuery.select(()=>(unsafeWindow||window).cid);if(!(t&&e)){return false}c.aid=t;c.cid=e;if(document.URL.includes("bangumi")){c.entity=new r}else if(document.URL.includes("cheese")){const t=document.URL.match(/cheese\/play\/ep([\d]+)/);c.entity=new l(t[1])}else{c.entity=new o}try{d=await h.getAvailableFormats()}catch(t){return false}return true}async function w(){p=d[0];e.applyStyle("downloadVideoStyle");const t=dq("#download-video");t.addEventListener("click",()=>{const t=dq(".download-video");t.classList.toggle("opened");window.scroll(0,0);dq(".gui-settings-mask").click()});t.addEventListener("mouseover",()=>{document.body.insertAdjacentHTML("beforeend",e.import("downloadVideoHtml"));g()},{once:true})}async function g(){let o;const r=new Vue({el:".download-video",components:{VDropdown:()=>e.importAsync("v-dropdown.vue"),VCheckbox:()=>e.importAsync("v-checkbox.vue"),RpcProfiles:()=>e.importAsync("aria2-rpc-profiles.vue")},data:{downloadSingle:true,coverUrl:EmptyImageUrl,aid:c.aid,cid:c.cid,dashModel:{value:t.downloadVideoFormat,items:["flv","dash"]},qualityModel:{value:p.displayName,items:d.map(t=>t.displayName)},danmakuModel:{value:t.downloadVideoDefaultDanmaku,items:["无","XML","ASS"]},codecModel:{value:t.downloadVideoDashCodec,items:["AVC/H.264","HEVC/H.265"]},progressPercent:0,size:"获取大小中",blobUrl:"",episodeList:[],downloading:false,speed:"",batch:false,rpcSettings:t.aria2RpcOption,showRpcSettings:false,busy:false,saveRpcSettingsText:"保存配置",enableDash:t.enableDashDownload,lastDirectDownloadLink:""},computed:{displaySize(){if(typeof this.size==="string"){return this.size}return formatFileSize(this.size)},sizeWarning(){if(typeof this.size==="string"){return false}return this.size>1073741824},selectedEpisodeCount(){return this.episodeList.filter(t=>t.checked).length},dash(){return this.dashModel.value==="dash"}},methods:{close(){this.$el.classList.remove("opened")},danmakuOptionChange(){t.downloadVideoDefaultDanmaku=this.danmakuModel.value},async codecChange(){t.downloadVideoDashCodec=this.codecModel.value;await this.formatChange()},async dashChange(){console.log("dash change");t.downloadVideoFormat=this.dashModel.value;const e=this.dashModel.value;let s=[];if(e==="flv"){s=await h.getAvailableFormats()}else{s=await h.getAvailableDashFormats()}d=s;[p]=e;this.qualityModel.items=s.map(t=>t.displayName);[this.qualityModel.value]=this.qualityModel.items;await this.formatChange()},async formatChange(){console.log("format change");const t=this.getFormat();try{this.size="获取大小中";const e=await t.downloadInfo(this.dash);this.size=e.totalSize}catch(t){this.size="获取大小失败";throw t}},getFormat(){const t=d.find(t=>t.displayName===this.qualityModel.value);if(!t){console.error(`No format found. model value = ${this.qualityModel.value}`);return null}return t},async exportData(t){if(this.busy===true){return}try{this.busy=true;if(!this.downloadSingle){await this.exportBatchData(t);return}const a=this.getFormat();const i=await a.downloadInfo(this.dash);switch(t){case"copyLink":await i.copyUrl();Toast.success("已复制链接到剪贴板.","下载视频",3e3);break;case"showLink":await i.showUrl();break;case"aria2":await i.exportAria2(false);break;case"aria2RPC":await i.exportAria2(true);break;case"copyVLD":await i.exportData(true);Toast.success("已复制VLD数据到剪贴板.","下载视频",3e3);break;case"exportVLD":await i.exportData(false);break;case"ffmpegFragments":if(i.fragments.length<2){Toast.info("当前视频没有分段.","分段列表",3e3)}else{const{getFragmentsList:t}=await e.importAsync("ffmpeg-support");const a=new n;a.add("ffmpeg-files.txt",t(i.fragments.length,s(),i.fragments.map(t=>i.extension(t))));await a.emit()}break;default:break}}catch(t){logError(t)}finally{this.busy=false}},async exportBatchData(t){const a=this.episodeList;if(a.every(t=>t.checked===false)){Toast.info("请至少选择1集或以上的数量!","批量导出",3e3);return}const o=t=>{const e=a.find(e=>e.cid===t.cid);if(e===undefined){return false}return e.checked};const r=this.getFormat();if(this.danmakuModel.value!=="无"){const t=Toast.info("下载弹幕中...","批量导出");const s=new n;try{if(this.danmakuModel.value==="XML"){for(const t of a.filter(o)){const e=new i(t.cid);await e.fetchInfo();s.add(t.title+".xml",e.rawXML)}}else{const{convertToAss:t}=await e.importAsync("download-danmaku");for(const e of a.filter(o)){const a=new i(e.cid);await a.fetchInfo();s.add(e.title+".ass",await t(a.rawXML))}}await s.emit(this.cid+".danmakus.zip")}catch(t){logError(`弹幕下载失败`)}finally{t.dismiss()}}const l=Toast.info("获取链接中...","批量导出");const c=this.batchExtractor;c.itemFilter=o;let d;try{switch(t){case"aria2":d=await c.collectAria2(r,l,false);await n.single(s(false)+".txt",new Blob([d],{type:"text/plain"}),{ffmpeg:this.ffmpegOption});return;case"aria2RPC":await c.collectAria2(r,l,true);Toast.success(`成功发送了批量请求.`,"aria2 RPC",3e3);return;case"copyVLD":GM.setClipboard(await c.collectData(r,l),{mimetype:"text/plain"});Toast.success("已复制批量vld数据到剪贴板.","批量导出",3e3);return;case"exportVLD":d=await c.collectData(r,l);await n.single(s(false)+".json",new Blob([d],{type:"text/json"}),{ffmpeg:this.ffmpegOption});return;case"ffmpegFragments":{const t=await c.getRawItems(r);const a=new u(r,t[0].fragments);const{getBatchFragmentsList:i}=await e.importAsync("ffmpeg-support");const o=this.dash?[".mp4","m4a"]:[a.extension()];const l=i(t,o);if(!l){Toast.info("所有选择的分P都没有分段.","分段列表",3e3)}else{const t=new n;for(const[e,s]of l.entries()){t.add(e,s)}await t.emit(escapeFilename(`${s(false)}.zip`))}}break;case"ffmpegEpisodes":{const t=await c.getRawItems(r);const s=new u(r,t[0].fragments);const{getBatchEpisodesList:a}=await e.importAsync("ffmpeg-support");const i=this.dash?[".mp4","m4a"]:[s.extension()];const o=a(t,i);const l=new n;l.add("ffmpeg-files.txt",o);await l.emit()}break;default:return}}catch(t){logError(t)}finally{l.dismiss()}},async checkBatch(){const t=["/www.bilibili.com/bangumi","/www.bilibili.com/video/av"];if(!t.some(t=>document.URL.includes(t))){this.batch=false;this.episodeList=[];return}const{BatchExtractor:s}=await e.importAsync("batch-download");if(await s.test()!==true){this.batch=false;this.episodeList=[];return}const a=this.batchExtractor=new s;this.batch=true;this.episodeList=(await a.getItemList()).map((t,e)=>{return{aid:t.aid,cid:t.cid,title:t.title,index:e,checked:true}})},cancelDownload(){if(o){o.cancelDownload()}},async startDownload(){const t=this.getFormat();try{this.downloading=true;const e=await t.downloadInfo(this.dash);e.videoSpeed.speedUpdate=(t=>this.speed=t);e.progress=(t=>{this.progressPercent=Math.trunc(t*100)});o=e;await e.download();this.lastDirectDownloadLink=n.lastPackageUrl}catch(t){if(t!=="canceled"){logError(t)}this.progressPercent=0}finally{this.downloading=false;this.speed=""}},selectAllEpisodes(){this.episodeList.forEach(t=>t.checked=true)},unselectAllEpisodes(){this.episodeList.forEach(t=>t.checked=false)},inverseAllEpisodes(){this.episodeList.forEach(t=>t.checked=!t.checked)},toggleRpcSettings(){this.showRpcSettings=!this.showRpcSettings},saveRpcSettings(){if(this.rpcSettings.host===""){this.rpcSettings.host="127.0.0.1"}if(this.rpcSettings.port===""){this.rpcSettings.port="6800"}t.aria2RpcOption=this.rpcSettings;const e=t.aria2RpcOptionProfiles.find(e=>e.name===t.aria2RpcOptionSelectedProfile);if(e){Object.assign(e,this.rpcSettings);t.aria2RpcOptionProfiles=t.aria2RpcOptionProfiles}this.saveRpcSettingsText="已保存";setTimeout(()=>this.saveRpcSettingsText="保存配置",2e3)},updateProfile(e){t.aria2RpcOption=this.rpcSettings=_.omit(e,"name")}},async mounted(){}});Observer.videoChange(async()=>{r.close();r.batch=false;r.downloadSingle=true;const t=dq("#download-video");const e=await m();t.style.display=e?"flex":"none";if(!e){return}r.aid=c.aid;r.cid=c.cid;try{const t=new a(c.aid);await t.fetchInfo();r.coverUrl=t.coverUrl.replace("http:","https:")}catch(t){r.coverUrl=EmptyImageUrl}r.dashChange();await r.checkBatch()})}return{widget:{content:`\n`,condition:m,success:w}}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/dpi-img.vue.min.js"] = (()=>{return(t,s)=>{const e=`
`;return{export:Object.assign({template:e},{props:["size","src","blur","root","rootMargin","threshold"],data(){return{srcset:null,actualSrc:null}},methods:{calcSrc(){if(!this.src||!this.size){return null}const t=this.src.substring(this.src.lastIndexOf(".")+1);this.srcset=getDpiSourceSet(this.src,this.size,t);this.actualSrc=this.src}},mounted(){const t={root:this.root,rootMargin:this.rootMargin||"200px",threshold:this.threshold};const s=new IntersectionObserver(t=>{t.forEach(t=>{if(t.isIntersecting){this.calcSrc();s.disconnect()}})},t);s.observe(this.$el)},computed:{width(){if(typeof this.size==="object"&&"width"in this.size){return this.size.width}return null},height(){if(typeof this.size==="object"&&"height"in this.size){return this.size.height}return null}}})}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/expand-danmaku.min.js"] = (()=>{return(e,a)=>{if(typeof isEmbeddedPlayer!=="undefined"&&isEmbeddedPlayer()){return}Observer.videoChange(async()=>{const e=await SpinQuery.select(".bui-collapse-wrap");if(e&&e.classList.contains("bui-collapse-wrap-folded")){const e=await SpinQuery.select(".bui-collapse-header");e.click()}})}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/expand-description.min.css"] = `.play-up-info .play-up-self,.video-desc .info{height:auto!important}.play-up-info .play-up-self-btn,.video-desc .btn{display:none!important}`;
@@ -1099,7 +1099,7 @@ offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/m
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/feeds-apis.min.js"] = (()=>{return(e,t)=>{const a={repost:{id:1,name:"转发"},textWithImages:{id:2,name:"图文"},text:{id:4,name:"文字"},video:{id:8,name:"视频"},miniVideo:{id:16,name:"小视频"},column:{id:64,name:"专栏"},audio:{id:256,name:"音频"},bangumi:{id:512,name:"番剧"},share:{id:2048,name:"分享"}};class i extends EventTarget{constructor(){super(...arguments);this.cards=[]}addEventListener(e,t,a){super.addEventListener(e,t,a)}removeEventListener(e,t,a){super.removeEventListener(e,t,a)}async addCard(e){if(e instanceof HTMLElement&&e.classList.contains("card")){if(e.querySelector(".skeleton")!==null){const t=Observer.childList(e,()=>{if(e.querySelector(".skeleton")===null){t.stop();this.addCard(e)}})}else{const t=await this.parseCard(e);this.cards.push(t);const a=new CustomEvent("addCard",{detail:t});this.dispatchEvent(a)}}}async removeCard(e){if(e instanceof HTMLElement&&e.classList.contains("card")){const t=(await this.parseCard(e)).id;const a=this.cards.findIndex(e=>e.id===t);const i=this.cards[a];this.cards.splice(a,1);const n=new CustomEvent("removeCard",{detail:i});this.dispatchEvent(n)}}async parseCard(e){const t=async t=>{const a=await SpinQuery.condition(()=>e.querySelector(t),e=>e!==null);if(a===null){console.warn(e,t);return""}return a.innerText};const i=async e=>{const a=parseInt(await t(e));if(isNaN(a)){return 0}return a};const n=(()=>{if(e.querySelector(".repost")){return a.repost}if(e.querySelector(".imagesbox")){return a.textWithImages}if(e.querySelector(".video-container")){return a.video}if(e.querySelector(".bangumi-container")){return a.bangumi}if(e.querySelector(".article-container")){return a.column}if(e.querySelector(".music-container")){return a.audio}if(e.querySelector(".h5share-container")){return a.share}if(e.querySelector(".vc-ctnr")){return a.miniVideo}return a.text})();const r={id:e.getAttribute("data-did"),username:await t(".main-content .user-name"),text:await t(".card-content .text.description,.video-container .title,.bangumi-container .title"),reposts:await i(".button-bar .single-button:nth-child(1) .text-offset"),comments:await i(".button-bar .single-button:nth-child(2) .text-offset"),likes:await i(".button-bar .single-button:nth-child(3) .text-offset"),element:e,type:n};e.setAttribute("data-type",n.id.toString());return r}async startWatching(){const e=await SpinQuery.select(".card-list .content");if(!e){return false}const t=[...e.querySelectorAll(".content>.card")];t.forEach(e=>this.addCard(e));Observer.childList(e,e=>{e.forEach(e=>{e.addedNodes.forEach(e=>this.addCard(e));e.removedNodes.forEach(e=>this.removeCard(e))})});return true}}const n=new i;const r=async(e="video")=>{const a=await Ajax.getJsonWithCredentials(`https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_new?uid=${getUID()}&type_list=${e==="video"?8:512}`);if(a.code!==0){throw new Error(a.message)}if(e==="video"){const{getWatchlaterList:e}=await t.importAsync("watchlater-api");const i=await e();return a.data.cards.map(e=>{const t=JSON.parse(e.card);const a=_.get(e,"display.topic_info.topic_details",[]).map(e=>{return{id:e.topic_id,name:e.topic_name}});return{id:e.desc.dynamic_id_str,aid:t.aid,title:t.title,upID:e.desc.user_profile.info.uid,upName:e.desc.user_profile.info.uname,upFaceUrl:e.desc.user_profile.info.face,coverUrl:t.pic,description:t.desc,timestamp:e.timestamp,time:new Date(e.timestamp*1e3),topics:a,dynamic:t.dynamic,like:formatCount(e.desc.like),duration:t.duration,durationText:formatDuration(t.duration,0),playCount:formatCount(t.stat.view),danmakuCount:formatCount(t.stat.danmaku),watchlater:i.includes(t.aid)}})}else if(e==="bangumi"){return a.data.cards.map(e=>{const t=JSON.parse(e.card);return{id:e.desc.dynamic_id_str,aid:t.aid,epID:t.episode_id,title:t.new_desc,upName:t.apiSeasonInfo.title,upFaceUrl:t.apiSeasonInfo.cover,coverUrl:t.cover,description:"",timestamp:e.timestamp,time:new Date(e.timestamp*1e3),like:formatCount(e.desc.like),durationText:"",playCount:formatCount(t.play_count),danmakuCount:formatCount(t.bullet_count),watchlater:false}})}else{return[]}};return{export:{feedsCardsManager:n,feedsCardTypes:a,getVideoFeeds:r}}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/feeds-filter-card.vue.min.js"] = (()=>{return(e,t)=>{const i=``;t.applyStyleFromText(`body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-audio .feed-card .card[data-type="256"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-bangumi .feed-card .card[data-type="512"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-column .feed-card .card[data-type="64"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-miniVideo .feed-card .card[data-type="16"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-repost .feed-card .card[data-type="1"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-share .feed-card .card[data-type="2048"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-text .feed-card .card[data-type="4"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-textWithImages .feed-card .card[data-type="2"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-video .feed-card .card[data-type="8"]{display:none!important}body.enable-feeds-filter:not(.disable-feeds-filter) .left-panel>*,body.enable-feeds-filter:not(.disable-feeds-filter) .right-panel>*{margin:0 0 8px!important}body.enable-feeds-filter:not(.disable-feeds-filter) .feed-card .card.pattern-block,body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-side-block-following-tags .left-panel .tag-panel,body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-side-block-live .right-panel .live-panel,body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-side-block-notice .right-panel .notice-panel,body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-side-block-profile .left-panel .user-wrapper,body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-side-block-trending-tags .right-panel .tag-panel{display:none!important}.feeds-filter{background-color:#fff;width:100%;padding:12px 16px;float:left;border-radius:4px;box-sizing:border-box;display:none;flex-direction:column}body.enable-feeds-filter:not(.disable-feeds-filter) .feeds-filter{display:flex}.feeds-filter,.feeds-filter *{transition:.2s ease-out}body.dark .feeds-filter{color:#eee;background-color:#444}.feeds-filter h1{font-weight:400;font-size:14px;margin:0 0 14px}.feeds-filter h2{font-weight:700;font-size:13px;margin:0 0 8px}.feeds-filter .feeds-filter-swtich:not(:last-child){margin-bottom:4px}.feeds-filter .feeds-filter-swtich label{cursor:pointer;margin:0;padding:4px 8px;border-radius:4px;background-color:#0001;display:flex;align-items:center;justify-content:space-between;border:1px solid transparent}.feeds-filter .feeds-filter-swtich label .name{font-size:12px}.feeds-filter .feeds-filter-swtich label .disabled{color:var(--theme-color)!important}.feeds-filter .feeds-filter-swtich label:hover{background-color:#0002}.feeds-filter .feeds-filter-swtich label input{display:none}.feeds-filter .feeds-filter-swtich label .be-icon{font-size:16px}.feeds-filter .feeds-filter-swtich label .be-icon.disabled{display:none}.feeds-filter .feeds-filter-swtich label.disabled{border-color:var(--theme-color)}.feeds-filter .feeds-filter-swtich label.disabled .be-icon{display:none}.feeds-filter .feeds-filter-swtich label.disabled .be-icon.disabled{display:block}.feeds-filter .filter-type-switch{flex:0 0 49%}.feeds-filter .filter-side-card-switch{flex:0 0 100%}.feeds-filter .filter-types{display:flex;flex-wrap:wrap;justify-content:space-between;margin-bottom:18px}.feeds-filter .filter-patterns:not(:empty){margin-bottom:8px}.feeds-filter .filter-patterns .pattern{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;border-radius:4px;background-color:#0001;font-size:12px}.feeds-filter .filter-patterns .pattern:not(:last-child){margin-bottom:4px}.feeds-filter .filter-patterns .pattern .be-icon{font-size:18px;cursor:pointer}.feeds-filter .add-pattern{display:flex;align-items:center;margin-bottom:18px}.feeds-filter .add-pattern input{color:inherit;background-color:transparent;font-size:12px;border:1px solid #8884;border-radius:4px;outline:0!important;padding:4px;flex:1 0 0;width:0}.feeds-filter .add-pattern input:focus{border-color:var(--theme-color)}.feeds-filter .add-pattern .be-icon{font-size:18px;cursor:pointer;margin-left:8px}`,"feeds-filter-card-style");const d={0:{className:"profile",displayName:"个人资料"},1:{className:"following-tags",displayName:"关注的话题"},2:{className:"notice",displayName:"公告栏"},3:{className:"live",displayName:"正在直播"},4:{className:"trending-tags",displayName:"热门话题"}};const s="feeds-filter-side-block-";return{export:Object.assign({template:i},{components:{FilterTypeSwitch:()=>t.importAsync("filter-type-switch.vue"),Icon:()=>t.importAsync("icon.vue")},methods:{updateCard(t){const i=(e,t)=>{if(e.startsWith("/")&&e.endsWith("/")){return new RegExp(e.slice(1,e.length-1)).test(t)}return t.includes(e)};const d=(()=>{return e.feedsFilterPatterns.some(e=>{const d=e.match(/(.+) up:([^ ]+)/);if(d){return i(d[1],t.text)&&i(d[2],t.username)}return i(e,t.text)})})();if(d){t.element.classList.add("pattern-block")}else{t.element.classList.remove("pattern-block")}},deletePattern(t){const i=e.feedsFilterPatterns.indexOf(t);if(i!==-1){this.patterns.splice(i,1)}},addPattern(e){if(e&&!this.patterns.includes(e)){this.patterns.push(e)}this.newPattern=""},updateBlockSide(){Object.entries(d).forEach(([e,t])=>{const i=s+t.className;document.body.classList[this.blockSideCards.includes(e)?"add":"remove"](i)})},toggleBlockSide(t){const i=this.blockSideCards.indexOf(t);const a=d[t];if(i!==-1){this.blockSideCards.splice(i,1);document.body.classList.remove(s+a.className)}else{this.blockSideCards.push(t);document.body.classList.add(s+a.className)}e.feedsFilterSideCards=this.blockSideCards},sideDisabled(e){return this.blockSideCards.includes(e)}},watch:{patterns(){e.feedsFilterPatterns=this.patterns;if(this.feedsCardsManager!==null){this.feedsCardsManager.cards.forEach(e=>this.updateCard(e))}}},data(){return{allTypes:[],patterns:[...e.feedsFilterPatterns],newPattern:"",feedsCardsManager:null,allSideCards:d,blockSideCards:[...e.feedsFilterSideCards]}},async mounted(){this.updateBlockSide();const e=await SpinQuery.select(".feed-card .tab-bar");if(!e){console.error("tabBar not found");return}const i=e.querySelector(".tab:nth-child(2) .tab-text");Observer.attributes(i,()=>{document.body.classList[i.classList.contains("selected")?"add":"remove"]("enable-feeds-filter")});const{feedsCardsManager:d,feedsCardTypes:s}=await t.importAsync("feeds-apis");const a=await d.startWatching();if(!a){console.error("feedsCardsManager.startWatching() failed");return}this.allTypes=Object.entries(s);d.cards.forEach(e=>this.updateCard(e));d.addEventListener("addCard",e=>{const t=e.detail;this.updateCard(t)});this.feedsCardsManager=d}})}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/feeds-filter.min.js"] = (()=>{return(e,t)=>{(async()=>{if(document.URL.replace(location.search,"")!=="https://t.bilibili.com/"){return}const e=await SpinQuery.select(".home-container .left-panel");if(e===null){return}e.insertAdjacentHTML("beforeend",html``);new Vue({el:"feeds-filter-card",components:{FeedsFilterCard:()=>t.importAsync("feeds-filter-card.vue")}})})();return{reload:()=>document.body.classList.remove("disable-feeds-filter"),unload:()=>document.body.classList.add("disable-feeds-filter")}}})();
-offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/ffmpeg-support.min.js"] = (()=>{return(e,t)=>{const n=(e,t,n)=>{if(e<2){return null}const r=[];for(let s=1;s<=e;s++){r.push(escapeFilename(`file '${t} - ${s}${n}'`))}return r.join("\n")};const r=(e,t)=>{const n=e=>e.fragments.length>1;const r=e.filter(n);if(r.length===0){return null}const s=new Map;r.forEach(e=>{s.set(escapeFilename(`ffmpeg-files-${e.title}.txt`),e.fragments.map((n,r)=>{return escapeFilename(`file '${e.title} - ${r+1}${t}'`)}).join("\n"))});return s};const s=(e,t)=>{const n=[];e.forEach(e=>{e.fragments.forEach((r,s)=>{let i="";if(e.fragments.length>1){i=` - ${s+1}`}n.push(escapeFilename(`file '${e.title}${i}${t}'`))})});return n.join("\n")};return{export:{getFragmentsList:n,getBatchFragmentsList:r,getBatchEpisodesList:s}}}})();
+offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/ffmpeg-support.min.js"] = (()=>{return(e,t)=>{const n=(e,t,n)=>{if(e<2){return null}const s=[];for(let r=1;r<=e;r++){let e=` - ${r}`;if(n.includes(".m4a")){e=""}s.push(escapeFilename(`file '${t}${e}${n[r-1]}'`))}return s.join("\n")};const s=(e,t)=>{const n=e=>e.fragments.length>1;const s=e.filter(n);if(s.length===0){return null}const r=new Map;s.forEach(e=>{r.set(escapeFilename(`ffmpeg-files-${e.title}.txt`),e.fragments.map((n,s)=>{return escapeFilename(`file '${e.title} - ${s+1}${t[s]}'`)}).join("\n"))});return r};const r=(e,t)=>{const n=[];e.forEach(e=>{e.fragments.forEach((s,r)=>{let i="";if(e.fragments.length>1&&!t.includes(".m4a")){i=` - ${r+1}`}n.push(escapeFilename(`file '${e.title}${i}${t[r]}'`))})});return n.join("\n")};return{export:{getFragmentsList:n,getBatchFragmentsList:s,getBatchEpisodesList:r}}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/fill-with-comments.min.js"] = (()=>{return(t,n)=>{const o="fill-with-comments-style";const i=t=>{if(t){n.applyStyleFromText(`\n .v-wrap { position: relative !important; }\n .v-wrap .l-con { width: 100% !important; }\n .v-wrap .r-con {\n position: absolute !important;\n top: 0 !important;\n right: 0 !important;\n }\n .video-desc .info { width: auto !important; }\n`,o)}else{dqa("#"+o).forEach(t=>t.remove())}};return{export:{fillWithComments:i}}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/filter-type-switch.vue.min.js"] = (()=>{return(e,s)=>{const i=``;return{export:Object.assign({template:i},{components:{Icon:()=>s.importAsync("icon.vue")},props:["name","type"],methods:{setFilter(s,i=true){document.body.classList[s?"add":"remove"](`feeds-filter-block-${this.name}`);if(!i){return}if(s){e.feedsFilterTypes.push(this.type.id)}else{const s=e.feedsFilterTypes.indexOf(this.type.id);if(s!==-1){e.feedsFilterTypes.splice(s,1)}}e.feedsFilterTypes=e.feedsFilterTypes}},data(){const s=e.feedsFilterTypes.includes(this.type.id);this.setFilter(s,false);return{disabled:s}},watch:{disabled(e){this.setFilter(e)}}})}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/fix-fullscreen.min.js"] = (()=>{return(e,n)=>{unsafeWindow.Element.ALLOW_KEYBOARD_INPUT={};const t=unsafeWindow.Element.prototype.requestFullscreen;unsafeWindow.Element.prototype.requestFullscreen=function(){t.call(this)}}})();
diff --git a/bilibili-evolved.preview-offline.user.js b/bilibili-evolved.preview-offline.user.js
index 991226f9b..7a013fc6e 100644
--- a/bilibili-evolved.preview-offline.user.js
+++ b/bilibili-evolved.preview-offline.user.js
@@ -1,6 +1,6 @@
// ==UserScript==
// @name Bilibili Evolved (Preview Offline)
-// @version 480.23
+// @version 480.30
// @description Bilibili Evolved 的预览离线版, 可以抢先体验新功能, 并且所有功能都已内置于脚本中.
// @author Grant Howard, Coulomb-G
// @copyright 2019, Grant Howard (https://github.com/the1812) & Coulomb-G (https://github.com/Coulomb-G)
@@ -1090,7 +1090,7 @@ offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/m
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video-package.min.js"] = (()=>{return(e,t)=>{class n{constructor(e={}){this.config=e;this.entries=[]}download(e,t){const a=document.createElement("a");const i=URL.createObjectURL(t);if(n.lastPackageUrl){URL.revokeObjectURL(n.lastPackageUrl)}n.lastPackageUrl=i;a.setAttribute("href",i);a.setAttribute("download",escapeFilename(e));document.body.appendChild(a);a.click();a.remove()}add(e,t){if(t===null||t===undefined){return}this.entries.push({name:escapeFilename(e),data:t})}async blob(){if(this.entries.length===0){return null}if(this.entries.length===1){const e=this.entries[0].data;return typeof e==="string"?new Blob([e]):e}const e=new JSZip;this.entries.forEach(({name:t,data:n})=>{e.file(t,n)});return await e.generateAsync({type:"blob"})}async emit(e){if(this.entries.length===0){return}if(!e||this.entries.length===1){e=this.entries[0].name}const t=await this.blob();if(!t){return}return this.download(e,t)}static async single(e,t,a={}){const i=new n(a);i.add(e,t);return await i.emit()}}n.lastPackageUrl="";return{export:{DownloadVideoPackage:n}}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.css"] = `.download-video{--download-video-background:white;--download-video-foreground:black;position:absolute;top:96px;left:50%;transform:translateX(-50%) scale(.95);background:var(--download-video-background);color:var(--download-video-foreground);box-shadow:rgba(0,0,0,.2) 0 4px 8px 0;z-index:10001;pointer-events:none;opacity:0;padding:16px;width:300px;display:flex;flex-direction:column;align-items:stretch;justify-content:space-between}.download-video,.download-video *{transition:.2s ease-out;-webkit-tap-highlight-color:transparent!important}.download-video.opened{pointer-events:initial;opacity:1;transform:translateX(-50%) scale(1)}body.dark .download-video{--download-video-background:#222;--download-video-foreground:#eee}.round-corner .download-video,.round-corner .download-video .episode-list .v-checkbox,.round-corner .download-video .rpc-settings{border-radius:var(--large-corner-radius)}.round-corner .download-video .button,.round-corner .download-video .cover,.round-corner .download-video .direct-download .progress .background,.round-corner .download-video .direct-download .progress .foreground,.round-corner .download-video .rpc-settings input[type=text],.round-corner .download-video .title,.round-corner .download-video button{border-radius:var(--corner-radius)}.download-video .cover{min-height:100px;max-height:120px;object-fit:contain}.download-video h1{font-size:13pt;font-weight:700;color:var(--download-video-foreground)}.download-video h2{font-size:11pt;font-weight:700;color:var(--download-video-foreground)}.download-video .header{display:flex;justify-content:space-between;align-items:center}.download-video .header .grow{flex-grow:1}.download-video .header .mdi-download{font-size:16pt;color:var(--download-video-foreground);margin-right:8px}.download-video .header .mdi-close{font-size:16pt;color:var(--download-video-foreground);cursor:pointer}.download-video .header .mdi-close:hover{color:var(--theme-color)}.download-video .info{display:flex;flex-direction:column;align-items:center;margin-top:12px}.download-video .title{display:flex;flex-direction:column;justify-content:space-between;align-items:stretch;margin-top:12px}.download-video .title .bold{width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center}.download-video .title .size{font-size:10pt;color:var(--download-video-foreground);align-self:center;display:flex;align-items:center;height:24px}.download-video .bold{color:var(--download-video-foreground);font-weight:700;font-size:12pt}.download-video .option-item{display:flex;justify-content:space-between;align-items:center;padding-top:12px;font-size:10pt}.download-video .tabs{display:flex;padding:12px 0;font-size:10pt}.download-video .tabs .tab{cursor:pointer;position:relative;opacity:.5}.download-video .tabs .tab.active{font-weight:700;opacity:1}.download-video .tabs .tab:not(:last-child){margin-right:16px}.download-video .tabs .tab::after{content:"";position:absolute;border-radius:2px;background-color:var(--theme-color);height:3px;width:80%;left:10%;bottom:-8px;transition:.2s ease-out;transform:scaleX(0)}.download-video .tabs .tab.active::after{transform:scaleX(1)}.download-video .separator{height:1px;background:#8884;width:100%;margin:12px 0;flex-shrink:0}.download-video .direct-download{display:flex;flex-direction:column;align-items:start;justify-content:space-between}.download-video .button,.download-video button{border:none;outline:0!important;padding:6px 16px;font-size:10pt;cursor:pointer;background:#8884;color:var(--download-video-foreground)}.download-video .button:hover,.download-video button:hover{background:#8886}.download-video .primary{background:var(--theme-color);color:var(--foreground-color);align-self:center}.download-video .primary:hover{background:var(--theme-color-90)}.download-video .busy .button,.download-video .busy .primary,.download-video .busy button,.download-video button:disabled{background-color:#0001;color:#8884;cursor:not-allowed}.download-video .busy .button,.download-video .busy button{cursor:wait!important}.download-video .direct-download .progress{align-self:stretch;display:flex;align-items:center;margin-top:8px}.download-video .direct-download .progress .background{flex-grow:1;height:4px;background:#8884;margin-right:4px;position:relative}.download-video .direct-download .progress .background .foreground{position:absolute;top:0;left:0;height:4px;background:linear-gradient(to right,var(--theme-color),var(--theme-color-60))}.download-video .direct-download .progress .percent{width:50px;text-align:right}.download-video .actions{display:flex;flex-wrap:wrap;justify-content:space-between;margin:8px -4px 0}.download-video .actions>*{margin:4px;flex-grow:1;flex-basis:calc(50% - 16px);display:flex;justify-content:center;align-items:center}.download-video i.mdi-alert-circle{font-size:14pt;color:#ff9800}.download-video .size-warning{position:relative;padding:0 8px}.download-video .size-warning-tip{position:absolute;bottom:100%;left:50%;transform:translateX(-50%);background:var(--download-video-background);color:var(--download-video-foreground);border:1px dashed var(--theme-color);z-index:2;font-size:10pt;width:200px;padding:8px;box-shadow:rgba(0,0,0,.2) 0 4px 8px 0;pointer-events:none;opacity:0}.download-video .size-warning:hover .size-warning-tip{opacity:1}.download-video .episode-list .v-checkbox{padding:4px 8px;margin:4px 0;position:relative;background-color:transparent}.download-video .episode-list .v-checkbox.checked{background-color:#8882}.download-video .episode-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}.download-video .episode-list{overflow:auto;max-height:320px}.download-video button.list-tool{padding:4px;line-height:1;font-size:12pt;margin:0 4px}.download-video .episode-header h2{flex-grow:1}.download-video .selected-count{width:64px;text-align:right}.download-video .aria2-rpc .mdi{margin-left:8px;font-size:14pt;line-height:1}.download-video .aria2-rpc{position:relative}.download-video .rpc-settings{position:absolute;display:flex;flex-direction:column;align-items:stretch;color:var(--download-video-foreground);background:#fff;bottom:120%;left:50%;cursor:initial;box-shadow:rgba(0,0,0,.2) 0 4px 8px 0;transform-origin:bottom;transform:translateX(-50%) scale(.9);opacity:0;pointer-events:none;padding:8px;z-index:3;transition:.3s cubic-bezier(.18,.89,.32,1.28);width:120%}body.dark .download-video .rpc-settings{background:#282828}.download-video .rpc-settings>*{margin:8px}.download-video .rpc-settings.show{opacity:1;transform:translateX(-50%) scale(1);pointer-events:initial}.download-video .rpc-settings input[type=text]{background:0 0;color:var(--download-video-foreground);border:1px solid #8884;padding:4px;margin-left:8px}.download-video .rpc-settings input[type=text]:focus{border-color:var(--theme-color)}.download-video .rpc-settings .operations{display:flex;align-items:center;justify-content:space-evenly}.download-video .final-dir{word-break:break-all}.download-video .rpc-settings-item{display:flex;align-items:center;justify-content:space-between;white-space:nowrap}.download-video .rpc-settings-item input[type=text]{flex-grow:1;margin-left:24px}.download-video button.cancel-download,.download-video button.start-download{margin-top:8px}.download-video .direct-download-header{align-self:stretch;display:flex;justify-content:space-between;align-items:center}body.dark .download-video .direct-download .progress .foreground{background:linear-gradient(to right,var(--theme-color-70),var(--theme-color))}`;
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.html"] = `![]()
警告: 过大的视频大小会在直接下载时占用大量内存, 并可能导致浏览器标签页崩溃. 请考虑降低清晰度或使用导出选项.
预计大小: {{displaySize}}导出
`;
-offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.js"] = (()=>{return(t,e)=>{const{getFriendlyTitle:s}=e.import("title");const{VideoInfo:a,DanmakuInfo:i}=e.import("video-info");const{DownloadVideoPackage:n}=e.import("download-video-package");class o{async getDashUrl(t){if(t){return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&fnver=0&fnval=16`}else{return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&fnver=0&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&otype=json`}}}class r extends o{async getDashUrl(t){if(t){return`https://api.bilibili.com/pgc/player/web/playurl?avid=56995872&cid=99547543&qn=${t}&otype=json&fourk=1&fnval=16`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=56995872&cid=99547543&otype=json&fourk=1&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=&otype=json`}}}class l extends o{constructor(t){super();this.ep=t}async getDashUrl(t){if(t){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&ep_id=${this.ep}`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&ep_id=${this.ep}`}}}const c={entity:new o,aid:"",cid:""};let d=[];let p=null;class h{constructor(t,e,s){this.quality=t;this.internalName=e;this.displayName=s}async downloadInfo(t=false){const e=new u(this);await e.fetchVideoInfo(t);return e}static parseFormats(t){const e=t.accept_quality;const s=t.accept_format.split(",");const a=t.accept_description;const i=e.map((t,e)=>{return new h(t,s[e],a[e])});return i}static async getAvailableDashFormats(){const t=await c.entity.getDashUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}return h.parseFormats(e.data||e.result||e)}static async getAvailableFormats(){const t=await c.entity.getUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}const s=e.data||e.result||e;return h.parseFormats(s)}}class u{constructor(t,e){this.fragmentSplitFactor=6*2;this.workingXhr=null;this.progressMap=new Map;this.format=t;this.fragments=e||[];this.videoSpeed=new f(this)}get danmakuOption(){return t.downloadVideoDefaultDanmaku}get isDash(){return this.fragments.some(t=>t.url.includes(".m4s"))}get totalSize(){return this.fragments.map(t=>t.size).reduce((t,e)=>t+e)}async fetchVideoInfo(s=false){if(!s){const t=await c.entity.getUrl(this.format.quality);const e=await Ajax.getTextWithCredentials(t);const s=JSON.parse(e.replace(/http:/g,"https:"));const a=s.data||s.result||s;if(a.quality!==this.format.quality){throw new Error("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const i=a.durl;this.fragments=i.map(t=>{return{length:t.length,size:t.size,url:t.url,backupUrls:t.backup_url}})}else{const{dashToFragment:s,getDashInfo:a}=await e.importAsync("video-dash");const i=await a(await c.entity.getDashUrl(this.format.quality),this.format.quality);console.log(i.videoDashes);const n=(()=>{const e=e=>e.videoCodec===t.downloadVideoDashCodec;if(i.videoDashes.some(e)){return i.videoDashes.filter(e).sort(ascendingSort(t=>t.bandWidth))[0]}else{return i.videoDashes.sort(ascendingSort(t=>t.bandWidth))[0]}})();const o=i.audioDashes.sort(descendingSort(t=>t.bandWidth))[0];this.fragments=[s(n),s(o)]}return this.fragments}updateProgress(){const t=this.progressMap?[...this.progressMap.values()].reduce((t,e)=>t+e,0)/this.totalSize:0;if(t>1||t<0){console.error(`[下载视频] 进度异常: ${t}`,this.progressMap.values())}this.progress&&this.progress(t)}cancelDownload(){this.videoSpeed.stopMeasure();if(this.workingXhr!==null){this.workingXhr.forEach(t=>t.abort())}else{logError("Cancel Download Failed: forEach in this.workingXhr not found.")}}downloadFragment(t){const e=[];const s=this.isDash?4*1024*1024:16*1024*1024;let a;if(t.size<=s*6){a=t.size/this.fragmentSplitFactor}else{a=s}let i=0;const n=t=>[...this.progressMap.keys()].indexOf(t)+1;while(i{const a=new XMLHttpRequest;a.open("GET",t.url);a.responseType="arraybuffer";a.withCredentials=false;a.addEventListener("progress",t=>{console.log(`[下载视频] 视频片段${n(a)}下载进度: ${t.loaded}/${r} bytes loaded, ${o}`);this.progressMap.set(a,t.loaded);this.updateProgress()});a.addEventListener("load",()=>{if((""+a.status)[0]==="2"){console.log(`[下载视频] 视频片段${n(a)}下载完成`);e(a.response)}else{s(`视频片段${n(a)}请求失败, response = ${a.status}`)}});a.addEventListener("abort",()=>s("canceled"));a.addEventListener("error",()=>{console.error(`[下载视频] 视频片段${n(a)}下载失败: ${o}`);this.progressMap.set(a,0);this.updateProgress();a.open("GET",t.url);a.setRequestHeader("Range",o);a.send()});a.setRequestHeader("Range",o);this.progressMap.set(a,0);a.send();this.workingXhr.push(a)}));i=Math.round(i+a)+1}return Promise.all(e)}async copyUrl(){const t=this.fragments.map(t=>t.url).reduce((t,e)=>t+"\r\n"+e);GM.setClipboard(t,"text")}async showUrl(){const t=this.fragments.map(t=>`\n${t.url}\n`).reduce((t,e)=>t+"\r\n"+e);Toast.success(t+`复制全部`,"显示链接");const e=await SpinQuery.select("#copy-link");e.addEventListener("click",async()=>{await this.copyUrl()})}async exportData(t=false){const e=JSON.stringify([{fragments:this.fragments,title:s(),totalSize:this.fragments.map(t=>t.size).reduce((t,e)=>t+e),referer:document.URL.replace(window.location.search,"")}]);if(t){GM.setClipboard(e,"text")}else{const t=new Blob([e],{type:"text/json"});const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.json`,t);i.add(s()+"."+this.danmakuOption.toLowerCase(),a);await i.emit(`${s()}.zip`)}}async exportAria2(a=false){if(a){const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.${this.danmakuOption==="ASS"?"ass":"xml"}`,a);await i.emit();const o=t.aria2RpcOption;const r=this.fragments.map((t,e)=>{let a="";if(this.fragments.length>1){a=" - "+(e+1)}const i=[];if(o.secretKey!==""){i.push(`token:${o.secretKey}`)}i.push([t.url]);i.push({referer:document.URL.replace(window.location.search,""),"user-agent":UserAgent,out:`${s()}${a}${this.extension(t)}`,split:this.fragmentSplitFactor,dir:o.baseDir+o.dir||undefined,"max-download-limit":o.maxDownloadLimit||undefined});const n=encodeURIComponent(`${s()}${a}`);return{params:i,id:n}});const{sendRpc:l}=await e.importAsync("aria2-rpc");await l(r)}else{const t=`\n# Generated by Bilibili Evolved Video Export\n# https://github.com/the1812/Bilibili-Evolved/\n${this.fragments.map((t,e)=>{let a="";if(this.fragments.length>1){a=" - "+(e+1)}return`\n${t.url}\n referer=${document.URL.replace(window.location.search,"")}\n user-agent=${UserAgent}\n out=${s()}${a}${this.extension(t)}\n split=${this.fragmentSplitFactor}\n`.trim()}).join("\n")}\n`.trim();const e=new Blob([t],{type:"text/plain"});const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.txt`,e);i.add(s()+"."+this.danmakuOption.toLowerCase(),a);await i.emit(`${s()}.zip`)}}extension(t){const e=t||this.fragments[0];const s=[".flv",".mp4",".m4s"].find(t=>e.url.includes(t));if(s){return s}else{console.warn("No extension detected.");return".flv"}}async downloadDanmaku(){if(this.danmakuOption!=="无"){const t=new i(c.cid);await t.fetchInfo();if(this.danmakuOption==="XML"){return t.rawXML}else{const{convertToAss:s}=await e.importAsync("download-danmaku");return s(t.rawXML)}}else{return null}}async download(){this.workingXhr=[];this.progressMap=new Map;this.updateProgress();const t=[];this.videoSpeed.startMeasure();for(const e of this.fragments){const s=await this.downloadFragment(e);t.push(s)}if(t.length<1){throw new Error("下载失败.")}const e=s();const a=new n;t.forEach((s,i)=>{let n;const o=this.fragments[i];if(t.length>1){n=`${e} - ${i+1}${this.extension(o)}`}else{n=`${e}${this.extension(o)}`}a.add(n,new Blob(Array.isArray(s)?s:[s],{type:this.extension(o)===".flv"?"video/x-flv":"video/mp4"}))});const i=await this.downloadDanmaku();a.add(`${s()}.${this.danmakuOption==="ASS"?"ass":"xml"}`,i);await a.emit(e+".zip");this.progress&&this.progress(0);this.videoSpeed.stopMeasure()}}class f{constructor(t){this.lastProgress=0;this.measureInterval=1e3;this.workingDownloader=t}startMeasure(){this.intervalTimer=setInterval(()=>{const t=this.workingDownloader.progressMap?[...this.workingDownloader.progressMap.values()].reduce((t,e)=>t+e,0):0;const e=t-this.lastProgress;if(this.speedUpdate!==undefined){this.speedUpdate(formatFileSize(e)+"/s")}this.lastProgress=t},this.measureInterval)}stopMeasure(){clearInterval(this.intervalTimer)}}async function m(){const t=await SpinQuery.select(()=>(unsafeWindow||window).aid);const e=await SpinQuery.select(()=>(unsafeWindow||window).cid);if(!(t&&e)){return false}c.aid=t;c.cid=e;if(document.URL.includes("bangumi")){c.entity=new r}else if(document.URL.includes("cheese")){const t=document.URL.match(/cheese\/play\/ep([\d]+)/);c.entity=new l(t[1])}else{c.entity=new o}try{d=await h.getAvailableFormats()}catch(t){return false}return true}async function w(){p=d[0];e.applyStyle("downloadVideoStyle");const t=dq("#download-video");t.addEventListener("click",()=>{const t=dq(".download-video");t.classList.toggle("opened");window.scroll(0,0);dq(".gui-settings-mask").click()});t.addEventListener("mouseover",()=>{document.body.insertAdjacentHTML("beforeend",e.import("downloadVideoHtml"));g()},{once:true})}async function g(){let o;const r=new Vue({el:".download-video",components:{VDropdown:()=>e.importAsync("v-dropdown.vue"),VCheckbox:()=>e.importAsync("v-checkbox.vue"),RpcProfiles:()=>e.importAsync("aria2-rpc-profiles.vue")},data:{downloadSingle:true,coverUrl:EmptyImageUrl,aid:c.aid,cid:c.cid,dashModel:{value:t.downloadVideoFormat,items:["flv","dash"]},qualityModel:{value:p.displayName,items:d.map(t=>t.displayName)},danmakuModel:{value:t.downloadVideoDefaultDanmaku,items:["无","XML","ASS"]},codecModel:{value:t.downloadVideoDashCodec,items:["AVC/H.264","HEVC/H.265"]},progressPercent:0,size:"获取大小中",blobUrl:"",episodeList:[],downloading:false,speed:"",batch:false,rpcSettings:t.aria2RpcOption,showRpcSettings:false,busy:false,saveRpcSettingsText:"保存配置",enableDash:t.enableDashDownload,lastDirectDownloadLink:""},computed:{displaySize(){if(typeof this.size==="string"){return this.size}return formatFileSize(this.size)},sizeWarning(){if(typeof this.size==="string"){return false}return this.size>1073741824},selectedEpisodeCount(){return this.episodeList.filter(t=>t.checked).length},dash(){return this.dashModel.value==="dash"}},methods:{close(){this.$el.classList.remove("opened")},danmakuOptionChange(){t.downloadVideoDefaultDanmaku=this.danmakuModel.value},async codecChange(){t.downloadVideoDashCodec=this.codecModel.value;await this.formatChange()},async dashChange(){console.log("dash change");t.downloadVideoFormat=this.dashModel.value;const e=this.dashModel.value;let s=[];if(e==="flv"){s=await h.getAvailableFormats()}else{s=await h.getAvailableDashFormats()}d=s;[p]=e;this.qualityModel.items=s.map(t=>t.displayName);[this.qualityModel.value]=this.qualityModel.items;await this.formatChange()},async formatChange(){console.log("format change");const t=this.getFormat();try{this.size="获取大小中";const e=await t.downloadInfo(this.dash);this.size=e.totalSize}catch(t){this.size="获取大小失败";throw t}},getFormat(){const t=d.find(t=>t.displayName===this.qualityModel.value);if(!t){console.error(`No format found. model value = ${this.qualityModel.value}`);return null}return t},async exportData(t){if(this.busy===true){return}try{this.busy=true;if(!this.downloadSingle){await this.exportBatchData(t);return}const a=this.getFormat();const i=await a.downloadInfo(this.dash);switch(t){case"copyLink":await i.copyUrl();Toast.success("已复制链接到剪贴板.","下载视频",3e3);break;case"showLink":await i.showUrl();break;case"aria2":await i.exportAria2(false);break;case"aria2RPC":await i.exportAria2(true);break;case"copyVLD":await i.exportData(true);Toast.success("已复制VLD数据到剪贴板.","下载视频",3e3);break;case"exportVLD":await i.exportData(false);break;case"ffmpegFragments":if(i.fragments.length<2){Toast.info("当前视频没有分段.","分段列表",3e3)}else{const{getFragmentsList:t}=await e.importAsync("ffmpeg-support");const a=new n;a.add("ffmpeg-files.txt",t(i.fragments.length,s(),i.extension(i.fragments[0])));await a.emit()}break;default:break}}catch(t){logError(t)}finally{this.busy=false}},async exportBatchData(t){const a=this.episodeList;if(a.every(t=>t.checked===false)){Toast.info("请至少选择1集或以上的数量!","批量导出",3e3);return}const o=t=>{const e=a.find(e=>e.cid===t.cid);if(e===undefined){return false}return e.checked};const r=this.getFormat();if(this.danmakuModel.value!=="无"){const t=Toast.info("下载弹幕中...","批量导出");const s=new n;try{if(this.danmakuModel.value==="XML"){for(const t of a.filter(o)){const e=new i(t.cid);await e.fetchInfo();s.add(t.title+".xml",e.rawXML)}}else{const{convertToAss:t}=await e.importAsync("download-danmaku");for(const e of a.filter(o)){const a=new i(e.cid);await a.fetchInfo();s.add(e.title+".ass",await t(a.rawXML))}}await s.emit(this.cid+".danmakus.zip")}catch(t){logError(`弹幕下载失败`)}finally{t.dismiss()}}const l=Toast.info("获取链接中...","批量导出");const c=this.batchExtractor;c.itemFilter=o;let d;try{switch(t){case"aria2":d=await c.collectAria2(r,l,false);await n.single(s(false)+".txt",new Blob([d],{type:"text/plain"}),{ffmpeg:this.ffmpegOption});return;case"aria2RPC":await c.collectAria2(r,l,true);Toast.success(`成功发送了批量请求.`,"aria2 RPC",3e3);return;case"copyVLD":GM.setClipboard(await c.collectData(r,l),{mimetype:"text/plain"});Toast.success("已复制批量vld数据到剪贴板.","批量导出",3e3);return;case"exportVLD":d=await c.collectData(r,l);await n.single(s(false)+".json",new Blob([d],{type:"text/json"}),{ffmpeg:this.ffmpegOption});return;case"ffmpegFragments":{const t=await c.getRawItems(r);const a=new u(r,t[0].fragments);const{getBatchFragmentsList:i}=await e.importAsync("ffmpeg-support");const o=i(t,a.extension());if(!o){Toast.info("所有选择的分P都没有分段.","分段列表",3e3)}else{const t=new n;for(const[e,s]of o.entries()){t.add(e,s)}await t.emit(escapeFilename(`${s(false)}.zip`))}}break;case"ffmpegEpisodes":{const t=await c.getRawItems(r);const s=new u(r,t[0].fragments);const{getBatchEpisodesList:a}=await e.importAsync("ffmpeg-support");const i=a(t,s.extension());const o=new n;o.add("ffmpeg-files.txt",i);await o.emit()}break;default:return}}catch(t){logError(t)}finally{l.dismiss()}},async checkBatch(){const t=["/www.bilibili.com/bangumi","/www.bilibili.com/video/av"];if(!t.some(t=>document.URL.includes(t))){this.batch=false;this.episodeList=[];return}const{BatchExtractor:s}=await e.importAsync("batch-download");if(await s.test()!==true){this.batch=false;this.episodeList=[];return}const a=this.batchExtractor=new s;this.batch=true;this.episodeList=(await a.getItemList()).map((t,e)=>{return{aid:t.aid,cid:t.cid,title:t.title,index:e,checked:true}})},cancelDownload(){if(o){o.cancelDownload()}},async startDownload(){const t=this.getFormat();try{this.downloading=true;const e=await t.downloadInfo(this.dash);e.videoSpeed.speedUpdate=(t=>this.speed=t);e.progress=(t=>{this.progressPercent=Math.trunc(t*100)});o=e;await e.download();this.lastDirectDownloadLink=n.lastPackageUrl}catch(t){if(t!=="canceled"){logError(t)}this.progressPercent=0}finally{this.downloading=false;this.speed=""}},selectAllEpisodes(){this.episodeList.forEach(t=>t.checked=true)},unselectAllEpisodes(){this.episodeList.forEach(t=>t.checked=false)},inverseAllEpisodes(){this.episodeList.forEach(t=>t.checked=!t.checked)},toggleRpcSettings(){this.showRpcSettings=!this.showRpcSettings},saveRpcSettings(){if(this.rpcSettings.host===""){this.rpcSettings.host="127.0.0.1"}if(this.rpcSettings.port===""){this.rpcSettings.port="6800"}t.aria2RpcOption=this.rpcSettings;const e=t.aria2RpcOptionProfiles.find(e=>e.name===t.aria2RpcOptionSelectedProfile);if(e){Object.assign(e,this.rpcSettings);t.aria2RpcOptionProfiles=t.aria2RpcOptionProfiles}this.saveRpcSettingsText="已保存";setTimeout(()=>this.saveRpcSettingsText="保存配置",2e3)},updateProfile(e){t.aria2RpcOption=this.rpcSettings=_.omit(e,"name")}},async mounted(){}});Observer.videoChange(async()=>{r.close();r.batch=false;r.downloadSingle=true;const t=dq("#download-video");const e=await m();t.style.display=e?"flex":"none";if(!e){return}r.aid=c.aid;r.cid=c.cid;try{const t=new a(c.aid);await t.fetchInfo();r.coverUrl=t.coverUrl.replace("http:","https:")}catch(t){r.coverUrl=EmptyImageUrl}r.dashChange();await r.checkBatch()})}return{widget:{content:`\n`,condition:m,success:w}}}})();
+offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.js"] = (()=>{return(t,e)=>{const{getFriendlyTitle:s}=e.import("title");const{VideoInfo:a,DanmakuInfo:i}=e.import("video-info");const{DownloadVideoPackage:n}=e.import("download-video-package");class o{async getDashUrl(t){if(t){return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&fnver=0&fnval=16`}else{return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&fnver=0&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&otype=json`}}}class r extends o{async getDashUrl(t){if(t){return`https://api.bilibili.com/pgc/player/web/playurl?avid=56995872&cid=99547543&qn=${t}&otype=json&fourk=1&fnval=16`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=56995872&cid=99547543&otype=json&fourk=1&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=&otype=json`}}}class l extends o{constructor(t){super();this.ep=t}async getDashUrl(t){if(t){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&ep_id=${this.ep}`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&ep_id=${this.ep}`}}}const c={entity:new o,aid:"",cid:""};let d=[];let p=null;class h{constructor(t,e,s){this.quality=t;this.internalName=e;this.displayName=s}async downloadInfo(t=false){const e=new u(this);await e.fetchVideoInfo(t);return e}static parseFormats(t){const e=t.accept_quality;const s=t.accept_format.split(",");const a=t.accept_description;const i=e.map((t,e)=>{return new h(t,s[e],a[e])});return i}static async getAvailableDashFormats(){const t=await c.entity.getDashUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}return h.parseFormats(e.data||e.result||e)}static async getAvailableFormats(){const t=await c.entity.getUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}const s=e.data||e.result||e;return h.parseFormats(s)}}class u{constructor(t,e){this.fragmentSplitFactor=6*2;this.workingXhr=null;this.progressMap=new Map;this.format=t;this.fragments=e||[];this.videoSpeed=new f(this)}get danmakuOption(){return t.downloadVideoDefaultDanmaku}get isDash(){return this.fragments.some(t=>t.url.includes(".m4s"))}get totalSize(){return this.fragments.map(t=>t.size).reduce((t,e)=>t+e)}async fetchVideoInfo(s=false){if(!s){const t=await c.entity.getUrl(this.format.quality);const e=await Ajax.getTextWithCredentials(t);const s=JSON.parse(e.replace(/http:/g,"https:"));const a=s.data||s.result||s;if(a.quality!==this.format.quality){throw new Error("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const i=a.durl;this.fragments=i.map(t=>{return{length:t.length,size:t.size,url:t.url,backupUrls:t.backup_url}})}else{const{dashToFragment:s,getDashInfo:a}=await e.importAsync("video-dash");const i=await a(await c.entity.getDashUrl(this.format.quality),this.format.quality);console.log(i.videoDashes);const n=(()=>{const e=e=>e.videoCodec===t.downloadVideoDashCodec;if(i.videoDashes.some(e)){return i.videoDashes.filter(e).sort(ascendingSort(t=>t.bandWidth))[0]}else{return i.videoDashes.sort(ascendingSort(t=>t.bandWidth))[0]}})();const o=i.audioDashes.sort(descendingSort(t=>t.bandWidth))[0];this.fragments=[s(n),s(o)]}return this.fragments}updateProgress(){const t=this.progressMap?[...this.progressMap.values()].reduce((t,e)=>t+e,0)/this.totalSize:0;if(t>1||t<0){console.error(`[下载视频] 进度异常: ${t}`,this.progressMap.values())}this.progress&&this.progress(t)}cancelDownload(){this.videoSpeed.stopMeasure();if(this.workingXhr!==null){this.workingXhr.forEach(t=>t.abort())}else{logError("Cancel Download Failed: forEach in this.workingXhr not found.")}}downloadFragment(t){const e=[];const s=this.isDash?4*1024*1024:16*1024*1024;let a;if(t.size<=s*6){a=t.size/this.fragmentSplitFactor}else{a=s}let i=0;const n=t=>[...this.progressMap.keys()].indexOf(t)+1;while(i{const a=new XMLHttpRequest;a.open("GET",t.url);a.responseType="arraybuffer";a.withCredentials=false;a.addEventListener("progress",t=>{console.log(`[下载视频] 视频片段${n(a)}下载进度: ${t.loaded}/${r} bytes loaded, ${o}`);this.progressMap.set(a,t.loaded);this.updateProgress()});a.addEventListener("load",()=>{if((""+a.status)[0]==="2"){console.log(`[下载视频] 视频片段${n(a)}下载完成`);e(a.response)}else{s(`视频片段${n(a)}请求失败, response = ${a.status}`)}});a.addEventListener("abort",()=>s("canceled"));a.addEventListener("error",()=>{console.error(`[下载视频] 视频片段${n(a)}下载失败: ${o}`);this.progressMap.set(a,0);this.updateProgress();a.open("GET",t.url);a.setRequestHeader("Range",o);a.send()});a.setRequestHeader("Range",o);this.progressMap.set(a,0);a.send();this.workingXhr.push(a)}));i=Math.round(i+a)+1}return Promise.all(e)}async copyUrl(){const t=this.fragments.map(t=>t.url).reduce((t,e)=>t+"\r\n"+e);GM.setClipboard(t,"text")}async showUrl(){const t=this.fragments.map(t=>`\n${t.url}\n`).reduce((t,e)=>t+"\r\n"+e);Toast.success(t+`复制全部`,"显示链接");const e=await SpinQuery.select("#copy-link");e.addEventListener("click",async()=>{await this.copyUrl()})}async exportData(t=false){const e=JSON.stringify([{fragments:this.fragments,title:s(),totalSize:this.fragments.map(t=>t.size).reduce((t,e)=>t+e),referer:document.URL.replace(window.location.search,"")}]);if(t){GM.setClipboard(e,"text")}else{const t=new Blob([e],{type:"text/json"});const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.json`,t);i.add(s()+"."+this.danmakuOption.toLowerCase(),a);await i.emit(`${s()}.zip`)}}async exportAria2(a=false){if(a){const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.${this.danmakuOption==="ASS"?"ass":"xml"}`,a);await i.emit();const o=t.aria2RpcOption;const r=this.fragments.map((t,e)=>{let a="";if(this.fragments.length>1&&!this.isDash){a=" - "+(e+1)}const i=[];if(o.secretKey!==""){i.push(`token:${o.secretKey}`)}i.push([t.url]);i.push({referer:document.URL.replace(window.location.search,""),"user-agent":UserAgent,out:`${s()}${a}${this.extension(t)}`,split:this.fragmentSplitFactor,dir:o.baseDir+o.dir||undefined,"max-download-limit":o.maxDownloadLimit||undefined});const n=encodeURIComponent(`${s()}${a}`);return{params:i,id:n}});const{sendRpc:l}=await e.importAsync("aria2-rpc");await l(r)}else{const t=`\n# Generated by Bilibili Evolved Video Export\n# https://github.com/the1812/Bilibili-Evolved/\n${this.fragments.map((t,e)=>{let a="";if(this.fragments.length>1&&!this.isDash){a=" - "+(e+1)}return`\n${t.url}\n referer=${document.URL.replace(window.location.search,"")}\n user-agent=${UserAgent}\n out=${s()}${a}${this.extension(t)}\n split=${this.fragmentSplitFactor}\n`.trim()}).join("\n")}\n`.trim();const e=new Blob([t],{type:"text/plain"});const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.txt`,e);i.add(s()+"."+this.danmakuOption.toLowerCase(),a);await i.emit(`${s()}.zip`)}}extension(t){const e=t||this.fragments[0];const s=[".flv",".mp4"].find(t=>e.url.includes(t));if(s){return s}else if(e.url.includes(".m4s")){return this.fragments.indexOf(e)===0?".mp4":".m4a"}else{console.warn("No extension detected.");return".flv"}}async downloadDanmaku(){if(this.danmakuOption!=="无"){const t=new i(c.cid);await t.fetchInfo();if(this.danmakuOption==="XML"){return t.rawXML}else{const{convertToAss:s}=await e.importAsync("download-danmaku");return s(t.rawXML)}}else{return null}}async download(){this.workingXhr=[];this.progressMap=new Map;this.updateProgress();const t=[];this.videoSpeed.startMeasure();for(const e of this.fragments){const s=await this.downloadFragment(e);t.push(s)}if(t.length<1){throw new Error("下载失败.")}const e=s();const a=new n;t.forEach((s,i)=>{let n;const o=this.fragments[i];if(t.length>1&&!this.isDash){n=`${e} - ${i+1}${this.extension(o)}`}else{n=`${e}${this.extension(o)}`}a.add(n,new Blob(Array.isArray(s)?s:[s]))});const i=await this.downloadDanmaku();a.add(`${s()}.${this.danmakuOption==="ASS"?"ass":"xml"}`,i);await a.emit(e+".zip");this.progress&&this.progress(0);this.videoSpeed.stopMeasure()}}class f{constructor(t){this.lastProgress=0;this.measureInterval=1e3;this.workingDownloader=t}startMeasure(){this.intervalTimer=setInterval(()=>{const t=this.workingDownloader.progressMap?[...this.workingDownloader.progressMap.values()].reduce((t,e)=>t+e,0):0;const e=t-this.lastProgress;if(this.speedUpdate!==undefined){this.speedUpdate(formatFileSize(e)+"/s")}this.lastProgress=t},this.measureInterval)}stopMeasure(){clearInterval(this.intervalTimer)}}async function m(){const t=await SpinQuery.select(()=>(unsafeWindow||window).aid);const e=await SpinQuery.select(()=>(unsafeWindow||window).cid);if(!(t&&e)){return false}c.aid=t;c.cid=e;if(document.URL.includes("bangumi")){c.entity=new r}else if(document.URL.includes("cheese")){const t=document.URL.match(/cheese\/play\/ep([\d]+)/);c.entity=new l(t[1])}else{c.entity=new o}try{d=await h.getAvailableFormats()}catch(t){return false}return true}async function w(){p=d[0];e.applyStyle("downloadVideoStyle");const t=dq("#download-video");t.addEventListener("click",()=>{const t=dq(".download-video");t.classList.toggle("opened");window.scroll(0,0);dq(".gui-settings-mask").click()});t.addEventListener("mouseover",()=>{document.body.insertAdjacentHTML("beforeend",e.import("downloadVideoHtml"));g()},{once:true})}async function g(){let o;const r=new Vue({el:".download-video",components:{VDropdown:()=>e.importAsync("v-dropdown.vue"),VCheckbox:()=>e.importAsync("v-checkbox.vue"),RpcProfiles:()=>e.importAsync("aria2-rpc-profiles.vue")},data:{downloadSingle:true,coverUrl:EmptyImageUrl,aid:c.aid,cid:c.cid,dashModel:{value:t.downloadVideoFormat,items:["flv","dash"]},qualityModel:{value:p.displayName,items:d.map(t=>t.displayName)},danmakuModel:{value:t.downloadVideoDefaultDanmaku,items:["无","XML","ASS"]},codecModel:{value:t.downloadVideoDashCodec,items:["AVC/H.264","HEVC/H.265"]},progressPercent:0,size:"获取大小中",blobUrl:"",episodeList:[],downloading:false,speed:"",batch:false,rpcSettings:t.aria2RpcOption,showRpcSettings:false,busy:false,saveRpcSettingsText:"保存配置",enableDash:t.enableDashDownload,lastDirectDownloadLink:""},computed:{displaySize(){if(typeof this.size==="string"){return this.size}return formatFileSize(this.size)},sizeWarning(){if(typeof this.size==="string"){return false}return this.size>1073741824},selectedEpisodeCount(){return this.episodeList.filter(t=>t.checked).length},dash(){return this.dashModel.value==="dash"}},methods:{close(){this.$el.classList.remove("opened")},danmakuOptionChange(){t.downloadVideoDefaultDanmaku=this.danmakuModel.value},async codecChange(){t.downloadVideoDashCodec=this.codecModel.value;await this.formatChange()},async dashChange(){console.log("dash change");t.downloadVideoFormat=this.dashModel.value;const e=this.dashModel.value;let s=[];if(e==="flv"){s=await h.getAvailableFormats()}else{s=await h.getAvailableDashFormats()}d=s;[p]=e;this.qualityModel.items=s.map(t=>t.displayName);[this.qualityModel.value]=this.qualityModel.items;await this.formatChange()},async formatChange(){console.log("format change");const t=this.getFormat();try{this.size="获取大小中";const e=await t.downloadInfo(this.dash);this.size=e.totalSize}catch(t){this.size="获取大小失败";throw t}},getFormat(){const t=d.find(t=>t.displayName===this.qualityModel.value);if(!t){console.error(`No format found. model value = ${this.qualityModel.value}`);return null}return t},async exportData(t){if(this.busy===true){return}try{this.busy=true;if(!this.downloadSingle){await this.exportBatchData(t);return}const a=this.getFormat();const i=await a.downloadInfo(this.dash);switch(t){case"copyLink":await i.copyUrl();Toast.success("已复制链接到剪贴板.","下载视频",3e3);break;case"showLink":await i.showUrl();break;case"aria2":await i.exportAria2(false);break;case"aria2RPC":await i.exportAria2(true);break;case"copyVLD":await i.exportData(true);Toast.success("已复制VLD数据到剪贴板.","下载视频",3e3);break;case"exportVLD":await i.exportData(false);break;case"ffmpegFragments":if(i.fragments.length<2){Toast.info("当前视频没有分段.","分段列表",3e3)}else{const{getFragmentsList:t}=await e.importAsync("ffmpeg-support");const a=new n;a.add("ffmpeg-files.txt",t(i.fragments.length,s(),i.fragments.map(t=>i.extension(t))));await a.emit()}break;default:break}}catch(t){logError(t)}finally{this.busy=false}},async exportBatchData(t){const a=this.episodeList;if(a.every(t=>t.checked===false)){Toast.info("请至少选择1集或以上的数量!","批量导出",3e3);return}const o=t=>{const e=a.find(e=>e.cid===t.cid);if(e===undefined){return false}return e.checked};const r=this.getFormat();if(this.danmakuModel.value!=="无"){const t=Toast.info("下载弹幕中...","批量导出");const s=new n;try{if(this.danmakuModel.value==="XML"){for(const t of a.filter(o)){const e=new i(t.cid);await e.fetchInfo();s.add(t.title+".xml",e.rawXML)}}else{const{convertToAss:t}=await e.importAsync("download-danmaku");for(const e of a.filter(o)){const a=new i(e.cid);await a.fetchInfo();s.add(e.title+".ass",await t(a.rawXML))}}await s.emit(this.cid+".danmakus.zip")}catch(t){logError(`弹幕下载失败`)}finally{t.dismiss()}}const l=Toast.info("获取链接中...","批量导出");const c=this.batchExtractor;c.itemFilter=o;let d;try{switch(t){case"aria2":d=await c.collectAria2(r,l,false);await n.single(s(false)+".txt",new Blob([d],{type:"text/plain"}),{ffmpeg:this.ffmpegOption});return;case"aria2RPC":await c.collectAria2(r,l,true);Toast.success(`成功发送了批量请求.`,"aria2 RPC",3e3);return;case"copyVLD":GM.setClipboard(await c.collectData(r,l),{mimetype:"text/plain"});Toast.success("已复制批量vld数据到剪贴板.","批量导出",3e3);return;case"exportVLD":d=await c.collectData(r,l);await n.single(s(false)+".json",new Blob([d],{type:"text/json"}),{ffmpeg:this.ffmpegOption});return;case"ffmpegFragments":{const t=await c.getRawItems(r);const a=new u(r,t[0].fragments);const{getBatchFragmentsList:i}=await e.importAsync("ffmpeg-support");const o=this.dash?[".mp4","m4a"]:[a.extension()];const l=i(t,o);if(!l){Toast.info("所有选择的分P都没有分段.","分段列表",3e3)}else{const t=new n;for(const[e,s]of l.entries()){t.add(e,s)}await t.emit(escapeFilename(`${s(false)}.zip`))}}break;case"ffmpegEpisodes":{const t=await c.getRawItems(r);const s=new u(r,t[0].fragments);const{getBatchEpisodesList:a}=await e.importAsync("ffmpeg-support");const i=this.dash?[".mp4","m4a"]:[s.extension()];const o=a(t,i);const l=new n;l.add("ffmpeg-files.txt",o);await l.emit()}break;default:return}}catch(t){logError(t)}finally{l.dismiss()}},async checkBatch(){const t=["/www.bilibili.com/bangumi","/www.bilibili.com/video/av"];if(!t.some(t=>document.URL.includes(t))){this.batch=false;this.episodeList=[];return}const{BatchExtractor:s}=await e.importAsync("batch-download");if(await s.test()!==true){this.batch=false;this.episodeList=[];return}const a=this.batchExtractor=new s;this.batch=true;this.episodeList=(await a.getItemList()).map((t,e)=>{return{aid:t.aid,cid:t.cid,title:t.title,index:e,checked:true}})},cancelDownload(){if(o){o.cancelDownload()}},async startDownload(){const t=this.getFormat();try{this.downloading=true;const e=await t.downloadInfo(this.dash);e.videoSpeed.speedUpdate=(t=>this.speed=t);e.progress=(t=>{this.progressPercent=Math.trunc(t*100)});o=e;await e.download();this.lastDirectDownloadLink=n.lastPackageUrl}catch(t){if(t!=="canceled"){logError(t)}this.progressPercent=0}finally{this.downloading=false;this.speed=""}},selectAllEpisodes(){this.episodeList.forEach(t=>t.checked=true)},unselectAllEpisodes(){this.episodeList.forEach(t=>t.checked=false)},inverseAllEpisodes(){this.episodeList.forEach(t=>t.checked=!t.checked)},toggleRpcSettings(){this.showRpcSettings=!this.showRpcSettings},saveRpcSettings(){if(this.rpcSettings.host===""){this.rpcSettings.host="127.0.0.1"}if(this.rpcSettings.port===""){this.rpcSettings.port="6800"}t.aria2RpcOption=this.rpcSettings;const e=t.aria2RpcOptionProfiles.find(e=>e.name===t.aria2RpcOptionSelectedProfile);if(e){Object.assign(e,this.rpcSettings);t.aria2RpcOptionProfiles=t.aria2RpcOptionProfiles}this.saveRpcSettingsText="已保存";setTimeout(()=>this.saveRpcSettingsText="保存配置",2e3)},updateProfile(e){t.aria2RpcOption=this.rpcSettings=_.omit(e,"name")}},async mounted(){}});Observer.videoChange(async()=>{r.close();r.batch=false;r.downloadSingle=true;const t=dq("#download-video");const e=await m();t.style.display=e?"flex":"none";if(!e){return}r.aid=c.aid;r.cid=c.cid;try{const t=new a(c.aid);await t.fetchInfo();r.coverUrl=t.coverUrl.replace("http:","https:")}catch(t){r.coverUrl=EmptyImageUrl}r.dashChange();await r.checkBatch()})}return{widget:{content:`\n`,condition:m,success:w}}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/dpi-img.vue.min.js"] = (()=>{return(t,s)=>{const e=`
`;return{export:Object.assign({template:e},{props:["size","src","blur","root","rootMargin","threshold"],data(){return{srcset:null,actualSrc:null}},methods:{calcSrc(){if(!this.src||!this.size){return null}const t=this.src.substring(this.src.lastIndexOf(".")+1);this.srcset=getDpiSourceSet(this.src,this.size,t);this.actualSrc=this.src}},mounted(){const t={root:this.root,rootMargin:this.rootMargin||"200px",threshold:this.threshold};const s=new IntersectionObserver(t=>{t.forEach(t=>{if(t.isIntersecting){this.calcSrc();s.disconnect()}})},t);s.observe(this.$el)},computed:{width(){if(typeof this.size==="object"&&"width"in this.size){return this.size.width}return null},height(){if(typeof this.size==="object"&&"height"in this.size){return this.size.height}return null}}})}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/expand-danmaku.min.js"] = (()=>{return(e,a)=>{if(typeof isEmbeddedPlayer!=="undefined"&&isEmbeddedPlayer()){return}Observer.videoChange(async()=>{const e=await SpinQuery.select(".bui-collapse-wrap");if(e&&e.classList.contains("bui-collapse-wrap-folded")){const e=await SpinQuery.select(".bui-collapse-header");e.click()}})}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/expand-description.min.css"] = `.play-up-info .play-up-self,.video-desc .info{height:auto!important}.play-up-info .play-up-self-btn,.video-desc .btn{display:none!important}`;
@@ -1099,7 +1099,7 @@ offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/m
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/feeds-apis.min.js"] = (()=>{return(e,t)=>{const a={repost:{id:1,name:"转发"},textWithImages:{id:2,name:"图文"},text:{id:4,name:"文字"},video:{id:8,name:"视频"},miniVideo:{id:16,name:"小视频"},column:{id:64,name:"专栏"},audio:{id:256,name:"音频"},bangumi:{id:512,name:"番剧"},share:{id:2048,name:"分享"}};class i extends EventTarget{constructor(){super(...arguments);this.cards=[]}addEventListener(e,t,a){super.addEventListener(e,t,a)}removeEventListener(e,t,a){super.removeEventListener(e,t,a)}async addCard(e){if(e instanceof HTMLElement&&e.classList.contains("card")){if(e.querySelector(".skeleton")!==null){const t=Observer.childList(e,()=>{if(e.querySelector(".skeleton")===null){t.stop();this.addCard(e)}})}else{const t=await this.parseCard(e);this.cards.push(t);const a=new CustomEvent("addCard",{detail:t});this.dispatchEvent(a)}}}async removeCard(e){if(e instanceof HTMLElement&&e.classList.contains("card")){const t=(await this.parseCard(e)).id;const a=this.cards.findIndex(e=>e.id===t);const i=this.cards[a];this.cards.splice(a,1);const n=new CustomEvent("removeCard",{detail:i});this.dispatchEvent(n)}}async parseCard(e){const t=async t=>{const a=await SpinQuery.condition(()=>e.querySelector(t),e=>e!==null);if(a===null){console.warn(e,t);return""}return a.innerText};const i=async e=>{const a=parseInt(await t(e));if(isNaN(a)){return 0}return a};const n=(()=>{if(e.querySelector(".repost")){return a.repost}if(e.querySelector(".imagesbox")){return a.textWithImages}if(e.querySelector(".video-container")){return a.video}if(e.querySelector(".bangumi-container")){return a.bangumi}if(e.querySelector(".article-container")){return a.column}if(e.querySelector(".music-container")){return a.audio}if(e.querySelector(".h5share-container")){return a.share}if(e.querySelector(".vc-ctnr")){return a.miniVideo}return a.text})();const r={id:e.getAttribute("data-did"),username:await t(".main-content .user-name"),text:await t(".card-content .text.description,.video-container .title,.bangumi-container .title"),reposts:await i(".button-bar .single-button:nth-child(1) .text-offset"),comments:await i(".button-bar .single-button:nth-child(2) .text-offset"),likes:await i(".button-bar .single-button:nth-child(3) .text-offset"),element:e,type:n};e.setAttribute("data-type",n.id.toString());return r}async startWatching(){const e=await SpinQuery.select(".card-list .content");if(!e){return false}const t=[...e.querySelectorAll(".content>.card")];t.forEach(e=>this.addCard(e));Observer.childList(e,e=>{e.forEach(e=>{e.addedNodes.forEach(e=>this.addCard(e));e.removedNodes.forEach(e=>this.removeCard(e))})});return true}}const n=new i;const r=async(e="video")=>{const a=await Ajax.getJsonWithCredentials(`https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_new?uid=${getUID()}&type_list=${e==="video"?8:512}`);if(a.code!==0){throw new Error(a.message)}if(e==="video"){const{getWatchlaterList:e}=await t.importAsync("watchlater-api");const i=await e();return a.data.cards.map(e=>{const t=JSON.parse(e.card);const a=_.get(e,"display.topic_info.topic_details",[]).map(e=>{return{id:e.topic_id,name:e.topic_name}});return{id:e.desc.dynamic_id_str,aid:t.aid,title:t.title,upID:e.desc.user_profile.info.uid,upName:e.desc.user_profile.info.uname,upFaceUrl:e.desc.user_profile.info.face,coverUrl:t.pic,description:t.desc,timestamp:e.timestamp,time:new Date(e.timestamp*1e3),topics:a,dynamic:t.dynamic,like:formatCount(e.desc.like),duration:t.duration,durationText:formatDuration(t.duration,0),playCount:formatCount(t.stat.view),danmakuCount:formatCount(t.stat.danmaku),watchlater:i.includes(t.aid)}})}else if(e==="bangumi"){return a.data.cards.map(e=>{const t=JSON.parse(e.card);return{id:e.desc.dynamic_id_str,aid:t.aid,epID:t.episode_id,title:t.new_desc,upName:t.apiSeasonInfo.title,upFaceUrl:t.apiSeasonInfo.cover,coverUrl:t.cover,description:"",timestamp:e.timestamp,time:new Date(e.timestamp*1e3),like:formatCount(e.desc.like),durationText:"",playCount:formatCount(t.play_count),danmakuCount:formatCount(t.bullet_count),watchlater:false}})}else{return[]}};return{export:{feedsCardsManager:n,feedsCardTypes:a,getVideoFeeds:r}}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/feeds-filter-card.vue.min.js"] = (()=>{return(e,t)=>{const i=``;t.applyStyleFromText(`body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-audio .feed-card .card[data-type="256"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-bangumi .feed-card .card[data-type="512"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-column .feed-card .card[data-type="64"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-miniVideo .feed-card .card[data-type="16"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-repost .feed-card .card[data-type="1"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-share .feed-card .card[data-type="2048"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-text .feed-card .card[data-type="4"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-textWithImages .feed-card .card[data-type="2"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-video .feed-card .card[data-type="8"]{display:none!important}body.enable-feeds-filter:not(.disable-feeds-filter) .left-panel>*,body.enable-feeds-filter:not(.disable-feeds-filter) .right-panel>*{margin:0 0 8px!important}body.enable-feeds-filter:not(.disable-feeds-filter) .feed-card .card.pattern-block,body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-side-block-following-tags .left-panel .tag-panel,body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-side-block-live .right-panel .live-panel,body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-side-block-notice .right-panel .notice-panel,body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-side-block-profile .left-panel .user-wrapper,body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-side-block-trending-tags .right-panel .tag-panel{display:none!important}.feeds-filter{background-color:#fff;width:100%;padding:12px 16px;float:left;border-radius:4px;box-sizing:border-box;display:none;flex-direction:column}body.enable-feeds-filter:not(.disable-feeds-filter) .feeds-filter{display:flex}.feeds-filter,.feeds-filter *{transition:.2s ease-out}body.dark .feeds-filter{color:#eee;background-color:#444}.feeds-filter h1{font-weight:400;font-size:14px;margin:0 0 14px}.feeds-filter h2{font-weight:700;font-size:13px;margin:0 0 8px}.feeds-filter .feeds-filter-swtich:not(:last-child){margin-bottom:4px}.feeds-filter .feeds-filter-swtich label{cursor:pointer;margin:0;padding:4px 8px;border-radius:4px;background-color:#0001;display:flex;align-items:center;justify-content:space-between;border:1px solid transparent}.feeds-filter .feeds-filter-swtich label .name{font-size:12px}.feeds-filter .feeds-filter-swtich label .disabled{color:var(--theme-color)!important}.feeds-filter .feeds-filter-swtich label:hover{background-color:#0002}.feeds-filter .feeds-filter-swtich label input{display:none}.feeds-filter .feeds-filter-swtich label .be-icon{font-size:16px}.feeds-filter .feeds-filter-swtich label .be-icon.disabled{display:none}.feeds-filter .feeds-filter-swtich label.disabled{border-color:var(--theme-color)}.feeds-filter .feeds-filter-swtich label.disabled .be-icon{display:none}.feeds-filter .feeds-filter-swtich label.disabled .be-icon.disabled{display:block}.feeds-filter .filter-type-switch{flex:0 0 49%}.feeds-filter .filter-side-card-switch{flex:0 0 100%}.feeds-filter .filter-types{display:flex;flex-wrap:wrap;justify-content:space-between;margin-bottom:18px}.feeds-filter .filter-patterns:not(:empty){margin-bottom:8px}.feeds-filter .filter-patterns .pattern{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;border-radius:4px;background-color:#0001;font-size:12px}.feeds-filter .filter-patterns .pattern:not(:last-child){margin-bottom:4px}.feeds-filter .filter-patterns .pattern .be-icon{font-size:18px;cursor:pointer}.feeds-filter .add-pattern{display:flex;align-items:center;margin-bottom:18px}.feeds-filter .add-pattern input{color:inherit;background-color:transparent;font-size:12px;border:1px solid #8884;border-radius:4px;outline:0!important;padding:4px;flex:1 0 0;width:0}.feeds-filter .add-pattern input:focus{border-color:var(--theme-color)}.feeds-filter .add-pattern .be-icon{font-size:18px;cursor:pointer;margin-left:8px}`,"feeds-filter-card-style");const d={0:{className:"profile",displayName:"个人资料"},1:{className:"following-tags",displayName:"关注的话题"},2:{className:"notice",displayName:"公告栏"},3:{className:"live",displayName:"正在直播"},4:{className:"trending-tags",displayName:"热门话题"}};const s="feeds-filter-side-block-";return{export:Object.assign({template:i},{components:{FilterTypeSwitch:()=>t.importAsync("filter-type-switch.vue"),Icon:()=>t.importAsync("icon.vue")},methods:{updateCard(t){const i=(e,t)=>{if(e.startsWith("/")&&e.endsWith("/")){return new RegExp(e.slice(1,e.length-1)).test(t)}return t.includes(e)};const d=(()=>{return e.feedsFilterPatterns.some(e=>{const d=e.match(/(.+) up:([^ ]+)/);if(d){return i(d[1],t.text)&&i(d[2],t.username)}return i(e,t.text)})})();if(d){t.element.classList.add("pattern-block")}else{t.element.classList.remove("pattern-block")}},deletePattern(t){const i=e.feedsFilterPatterns.indexOf(t);if(i!==-1){this.patterns.splice(i,1)}},addPattern(e){if(e&&!this.patterns.includes(e)){this.patterns.push(e)}this.newPattern=""},updateBlockSide(){Object.entries(d).forEach(([e,t])=>{const i=s+t.className;document.body.classList[this.blockSideCards.includes(e)?"add":"remove"](i)})},toggleBlockSide(t){const i=this.blockSideCards.indexOf(t);const a=d[t];if(i!==-1){this.blockSideCards.splice(i,1);document.body.classList.remove(s+a.className)}else{this.blockSideCards.push(t);document.body.classList.add(s+a.className)}e.feedsFilterSideCards=this.blockSideCards},sideDisabled(e){return this.blockSideCards.includes(e)}},watch:{patterns(){e.feedsFilterPatterns=this.patterns;if(this.feedsCardsManager!==null){this.feedsCardsManager.cards.forEach(e=>this.updateCard(e))}}},data(){return{allTypes:[],patterns:[...e.feedsFilterPatterns],newPattern:"",feedsCardsManager:null,allSideCards:d,blockSideCards:[...e.feedsFilterSideCards]}},async mounted(){this.updateBlockSide();const e=await SpinQuery.select(".feed-card .tab-bar");if(!e){console.error("tabBar not found");return}const i=e.querySelector(".tab:nth-child(2) .tab-text");Observer.attributes(i,()=>{document.body.classList[i.classList.contains("selected")?"add":"remove"]("enable-feeds-filter")});const{feedsCardsManager:d,feedsCardTypes:s}=await t.importAsync("feeds-apis");const a=await d.startWatching();if(!a){console.error("feedsCardsManager.startWatching() failed");return}this.allTypes=Object.entries(s);d.cards.forEach(e=>this.updateCard(e));d.addEventListener("addCard",e=>{const t=e.detail;this.updateCard(t)});this.feedsCardsManager=d}})}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/feeds-filter.min.js"] = (()=>{return(e,t)=>{(async()=>{if(document.URL.replace(location.search,"")!=="https://t.bilibili.com/"){return}const e=await SpinQuery.select(".home-container .left-panel");if(e===null){return}e.insertAdjacentHTML("beforeend",html``);new Vue({el:"feeds-filter-card",components:{FeedsFilterCard:()=>t.importAsync("feeds-filter-card.vue")}})})();return{reload:()=>document.body.classList.remove("disable-feeds-filter"),unload:()=>document.body.classList.add("disable-feeds-filter")}}})();
-offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/ffmpeg-support.min.js"] = (()=>{return(e,t)=>{const n=(e,t,n)=>{if(e<2){return null}const r=[];for(let s=1;s<=e;s++){r.push(escapeFilename(`file '${t} - ${s}${n}'`))}return r.join("\n")};const r=(e,t)=>{const n=e=>e.fragments.length>1;const r=e.filter(n);if(r.length===0){return null}const s=new Map;r.forEach(e=>{s.set(escapeFilename(`ffmpeg-files-${e.title}.txt`),e.fragments.map((n,r)=>{return escapeFilename(`file '${e.title} - ${r+1}${t}'`)}).join("\n"))});return s};const s=(e,t)=>{const n=[];e.forEach(e=>{e.fragments.forEach((r,s)=>{let i="";if(e.fragments.length>1){i=` - ${s+1}`}n.push(escapeFilename(`file '${e.title}${i}${t}'`))})});return n.join("\n")};return{export:{getFragmentsList:n,getBatchFragmentsList:r,getBatchEpisodesList:s}}}})();
+offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/ffmpeg-support.min.js"] = (()=>{return(e,t)=>{const n=(e,t,n)=>{if(e<2){return null}const s=[];for(let r=1;r<=e;r++){let e=` - ${r}`;if(n.includes(".m4a")){e=""}s.push(escapeFilename(`file '${t}${e}${n[r-1]}'`))}return s.join("\n")};const s=(e,t)=>{const n=e=>e.fragments.length>1;const s=e.filter(n);if(s.length===0){return null}const r=new Map;s.forEach(e=>{r.set(escapeFilename(`ffmpeg-files-${e.title}.txt`),e.fragments.map((n,s)=>{return escapeFilename(`file '${e.title} - ${s+1}${t[s]}'`)}).join("\n"))});return r};const r=(e,t)=>{const n=[];e.forEach(e=>{e.fragments.forEach((s,r)=>{let i="";if(e.fragments.length>1&&!t.includes(".m4a")){i=` - ${r+1}`}n.push(escapeFilename(`file '${e.title}${i}${t[r]}'`))})});return n.join("\n")};return{export:{getFragmentsList:n,getBatchFragmentsList:s,getBatchEpisodesList:r}}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/fill-with-comments.min.js"] = (()=>{return(t,n)=>{const o="fill-with-comments-style";const i=t=>{if(t){n.applyStyleFromText(`\n .v-wrap { position: relative !important; }\n .v-wrap .l-con { width: 100% !important; }\n .v-wrap .r-con {\n position: absolute !important;\n top: 0 !important;\n right: 0 !important;\n }\n .video-desc .info { width: auto !important; }\n`,o)}else{dqa("#"+o).forEach(t=>t.remove())}};return{export:{fillWithComments:i}}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/filter-type-switch.vue.min.js"] = (()=>{return(e,s)=>{const i=``;return{export:Object.assign({template:i},{components:{Icon:()=>s.importAsync("icon.vue")},props:["name","type"],methods:{setFilter(s,i=true){document.body.classList[s?"add":"remove"](`feeds-filter-block-${this.name}`);if(!i){return}if(s){e.feedsFilterTypes.push(this.type.id)}else{const s=e.feedsFilterTypes.indexOf(this.type.id);if(s!==-1){e.feedsFilterTypes.splice(s,1)}}e.feedsFilterTypes=e.feedsFilterTypes}},data(){const s=e.feedsFilterTypes.includes(this.type.id);this.setFilter(s,false);return{disabled:s}},watch:{disabled(e){this.setFilter(e)}}})}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/fix-fullscreen.min.js"] = (()=>{return(e,n)=>{unsafeWindow.Element.ALLOW_KEYBOARD_INPUT={};const t=unsafeWindow.Element.prototype.requestFullscreen;unsafeWindow.Element.prototype.requestFullscreen=function(){t.call(this)}}})();
diff --git a/bilibili-evolved.preview.user.js b/bilibili-evolved.preview.user.js
index 8e27b32b0..c16704cfb 100644
--- a/bilibili-evolved.preview.user.js
+++ b/bilibili-evolved.preview.user.js
@@ -1089,7 +1089,7 @@ onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/m
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/min/download-video-package.min.js"] = (()=>{return(e,t)=>{class n{constructor(e={}){this.config=e;this.entries=[]}download(e,t){const a=document.createElement("a");const i=URL.createObjectURL(t);if(n.lastPackageUrl){URL.revokeObjectURL(n.lastPackageUrl)}n.lastPackageUrl=i;a.setAttribute("href",i);a.setAttribute("download",escapeFilename(e));document.body.appendChild(a);a.click();a.remove()}add(e,t){if(t===null||t===undefined){return}this.entries.push({name:escapeFilename(e),data:t})}async blob(){if(this.entries.length===0){return null}if(this.entries.length===1){const e=this.entries[0].data;return typeof e==="string"?new Blob([e]):e}const e=new JSZip;this.entries.forEach(({name:t,data:n})=>{e.file(t,n)});return await e.generateAsync({type:"blob"})}async emit(e){if(this.entries.length===0){return}if(!e||this.entries.length===1){e=this.entries[0].name}const t=await this.blob();if(!t){return}return this.download(e,t)}static async single(e,t,a={}){const i=new n(a);i.add(e,t);return await i.emit()}}n.lastPackageUrl="";return{export:{DownloadVideoPackage:n}}}})();
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/min/download-video.min.css"] = `.download-video{--download-video-background:white;--download-video-foreground:black;position:absolute;top:96px;left:50%;transform:translateX(-50%) scale(.95);background:var(--download-video-background);color:var(--download-video-foreground);box-shadow:rgba(0,0,0,.2) 0 4px 8px 0;z-index:10001;pointer-events:none;opacity:0;padding:16px;width:300px;display:flex;flex-direction:column;align-items:stretch;justify-content:space-between}.download-video,.download-video *{transition:.2s ease-out;-webkit-tap-highlight-color:transparent!important}.download-video.opened{pointer-events:initial;opacity:1;transform:translateX(-50%) scale(1)}body.dark .download-video{--download-video-background:#222;--download-video-foreground:#eee}.round-corner .download-video,.round-corner .download-video .episode-list .v-checkbox,.round-corner .download-video .rpc-settings{border-radius:var(--large-corner-radius)}.round-corner .download-video .button,.round-corner .download-video .cover,.round-corner .download-video .direct-download .progress .background,.round-corner .download-video .direct-download .progress .foreground,.round-corner .download-video .rpc-settings input[type=text],.round-corner .download-video .title,.round-corner .download-video button{border-radius:var(--corner-radius)}.download-video .cover{min-height:100px;max-height:120px;object-fit:contain}.download-video h1{font-size:13pt;font-weight:700;color:var(--download-video-foreground)}.download-video h2{font-size:11pt;font-weight:700;color:var(--download-video-foreground)}.download-video .header{display:flex;justify-content:space-between;align-items:center}.download-video .header .grow{flex-grow:1}.download-video .header .mdi-download{font-size:16pt;color:var(--download-video-foreground);margin-right:8px}.download-video .header .mdi-close{font-size:16pt;color:var(--download-video-foreground);cursor:pointer}.download-video .header .mdi-close:hover{color:var(--theme-color)}.download-video .info{display:flex;flex-direction:column;align-items:center;margin-top:12px}.download-video .title{display:flex;flex-direction:column;justify-content:space-between;align-items:stretch;margin-top:12px}.download-video .title .bold{width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center}.download-video .title .size{font-size:10pt;color:var(--download-video-foreground);align-self:center;display:flex;align-items:center;height:24px}.download-video .bold{color:var(--download-video-foreground);font-weight:700;font-size:12pt}.download-video .option-item{display:flex;justify-content:space-between;align-items:center;padding-top:12px;font-size:10pt}.download-video .tabs{display:flex;padding:12px 0;font-size:10pt}.download-video .tabs .tab{cursor:pointer;position:relative;opacity:.5}.download-video .tabs .tab.active{font-weight:700;opacity:1}.download-video .tabs .tab:not(:last-child){margin-right:16px}.download-video .tabs .tab::after{content:"";position:absolute;border-radius:2px;background-color:var(--theme-color);height:3px;width:80%;left:10%;bottom:-8px;transition:.2s ease-out;transform:scaleX(0)}.download-video .tabs .tab.active::after{transform:scaleX(1)}.download-video .separator{height:1px;background:#8884;width:100%;margin:12px 0;flex-shrink:0}.download-video .direct-download{display:flex;flex-direction:column;align-items:start;justify-content:space-between}.download-video .button,.download-video button{border:none;outline:0!important;padding:6px 16px;font-size:10pt;cursor:pointer;background:#8884;color:var(--download-video-foreground)}.download-video .button:hover,.download-video button:hover{background:#8886}.download-video .primary{background:var(--theme-color);color:var(--foreground-color);align-self:center}.download-video .primary:hover{background:var(--theme-color-90)}.download-video .busy .button,.download-video .busy .primary,.download-video .busy button,.download-video button:disabled{background-color:#0001;color:#8884;cursor:not-allowed}.download-video .busy .button,.download-video .busy button{cursor:wait!important}.download-video .direct-download .progress{align-self:stretch;display:flex;align-items:center;margin-top:8px}.download-video .direct-download .progress .background{flex-grow:1;height:4px;background:#8884;margin-right:4px;position:relative}.download-video .direct-download .progress .background .foreground{position:absolute;top:0;left:0;height:4px;background:linear-gradient(to right,var(--theme-color),var(--theme-color-60))}.download-video .direct-download .progress .percent{width:50px;text-align:right}.download-video .actions{display:flex;flex-wrap:wrap;justify-content:space-between;margin:8px -4px 0}.download-video .actions>*{margin:4px;flex-grow:1;flex-basis:calc(50% - 16px);display:flex;justify-content:center;align-items:center}.download-video i.mdi-alert-circle{font-size:14pt;color:#ff9800}.download-video .size-warning{position:relative;padding:0 8px}.download-video .size-warning-tip{position:absolute;bottom:100%;left:50%;transform:translateX(-50%);background:var(--download-video-background);color:var(--download-video-foreground);border:1px dashed var(--theme-color);z-index:2;font-size:10pt;width:200px;padding:8px;box-shadow:rgba(0,0,0,.2) 0 4px 8px 0;pointer-events:none;opacity:0}.download-video .size-warning:hover .size-warning-tip{opacity:1}.download-video .episode-list .v-checkbox{padding:4px 8px;margin:4px 0;position:relative;background-color:transparent}.download-video .episode-list .v-checkbox.checked{background-color:#8882}.download-video .episode-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}.download-video .episode-list{overflow:auto;max-height:320px}.download-video button.list-tool{padding:4px;line-height:1;font-size:12pt;margin:0 4px}.download-video .episode-header h2{flex-grow:1}.download-video .selected-count{width:64px;text-align:right}.download-video .aria2-rpc .mdi{margin-left:8px;font-size:14pt;line-height:1}.download-video .aria2-rpc{position:relative}.download-video .rpc-settings{position:absolute;display:flex;flex-direction:column;align-items:stretch;color:var(--download-video-foreground);background:#fff;bottom:120%;left:50%;cursor:initial;box-shadow:rgba(0,0,0,.2) 0 4px 8px 0;transform-origin:bottom;transform:translateX(-50%) scale(.9);opacity:0;pointer-events:none;padding:8px;z-index:3;transition:.3s cubic-bezier(.18,.89,.32,1.28);width:120%}body.dark .download-video .rpc-settings{background:#282828}.download-video .rpc-settings>*{margin:8px}.download-video .rpc-settings.show{opacity:1;transform:translateX(-50%) scale(1);pointer-events:initial}.download-video .rpc-settings input[type=text]{background:0 0;color:var(--download-video-foreground);border:1px solid #8884;padding:4px;margin-left:8px}.download-video .rpc-settings input[type=text]:focus{border-color:var(--theme-color)}.download-video .rpc-settings .operations{display:flex;align-items:center;justify-content:space-evenly}.download-video .final-dir{word-break:break-all}.download-video .rpc-settings-item{display:flex;align-items:center;justify-content:space-between;white-space:nowrap}.download-video .rpc-settings-item input[type=text]{flex-grow:1;margin-left:24px}.download-video button.cancel-download,.download-video button.start-download{margin-top:8px}.download-video .direct-download-header{align-self:stretch;display:flex;justify-content:space-between;align-items:center}body.dark .download-video .direct-download .progress .foreground{background:linear-gradient(to right,var(--theme-color-70),var(--theme-color))}`;
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/min/download-video.min.html"] = `![]()
警告: 过大的视频大小会在直接下载时占用大量内存, 并可能导致浏览器标签页崩溃. 请考虑降低清晰度或使用导出选项.
预计大小: {{displaySize}}导出
`;
-onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/min/download-video.min.js"] = (()=>{return(t,e)=>{const{getFriendlyTitle:s}=e.import("title");const{VideoInfo:a,DanmakuInfo:i}=e.import("video-info");const{DownloadVideoPackage:n}=e.import("download-video-package");class o{async getDashUrl(t){if(t){return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&fnver=0&fnval=16`}else{return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&fnver=0&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&otype=json`}}}class r extends o{async getDashUrl(t){if(t){return`https://api.bilibili.com/pgc/player/web/playurl?avid=56995872&cid=99547543&qn=${t}&otype=json&fourk=1&fnval=16`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=56995872&cid=99547543&otype=json&fourk=1&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=&otype=json`}}}class l extends o{constructor(t){super();this.ep=t}async getDashUrl(t){if(t){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&ep_id=${this.ep}`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&ep_id=${this.ep}`}}}const c={entity:new o,aid:"",cid:""};let d=[];let p=null;class h{constructor(t,e,s){this.quality=t;this.internalName=e;this.displayName=s}async downloadInfo(t=false){const e=new u(this);await e.fetchVideoInfo(t);return e}static parseFormats(t){const e=t.accept_quality;const s=t.accept_format.split(",");const a=t.accept_description;const i=e.map((t,e)=>{return new h(t,s[e],a[e])});return i}static async getAvailableDashFormats(){const t=await c.entity.getDashUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}return h.parseFormats(e.data||e.result||e)}static async getAvailableFormats(){const t=await c.entity.getUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}const s=e.data||e.result||e;return h.parseFormats(s)}}class u{constructor(t,e){this.fragmentSplitFactor=6*2;this.workingXhr=null;this.progressMap=new Map;this.format=t;this.fragments=e||[];this.videoSpeed=new f(this)}get danmakuOption(){return t.downloadVideoDefaultDanmaku}get isDash(){return this.fragments.some(t=>t.url.includes(".m4s"))}get totalSize(){return this.fragments.map(t=>t.size).reduce((t,e)=>t+e)}async fetchVideoInfo(s=false){if(!s){const t=await c.entity.getUrl(this.format.quality);const e=await Ajax.getTextWithCredentials(t);const s=JSON.parse(e.replace(/http:/g,"https:"));const a=s.data||s.result||s;if(a.quality!==this.format.quality){throw new Error("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const i=a.durl;this.fragments=i.map(t=>{return{length:t.length,size:t.size,url:t.url,backupUrls:t.backup_url}})}else{const{dashToFragment:s,getDashInfo:a}=await e.importAsync("video-dash");const i=await a(await c.entity.getDashUrl(this.format.quality),this.format.quality);console.log(i.videoDashes);const n=(()=>{const e=e=>e.videoCodec===t.downloadVideoDashCodec;if(i.videoDashes.some(e)){return i.videoDashes.filter(e).sort(ascendingSort(t=>t.bandWidth))[0]}else{return i.videoDashes.sort(ascendingSort(t=>t.bandWidth))[0]}})();const o=i.audioDashes.sort(descendingSort(t=>t.bandWidth))[0];this.fragments=[s(n),s(o)]}return this.fragments}updateProgress(){const t=this.progressMap?[...this.progressMap.values()].reduce((t,e)=>t+e,0)/this.totalSize:0;if(t>1||t<0){console.error(`[下载视频] 进度异常: ${t}`,this.progressMap.values())}this.progress&&this.progress(t)}cancelDownload(){this.videoSpeed.stopMeasure();if(this.workingXhr!==null){this.workingXhr.forEach(t=>t.abort())}else{logError("Cancel Download Failed: forEach in this.workingXhr not found.")}}downloadFragment(t){const e=[];const s=this.isDash?4*1024*1024:16*1024*1024;let a;if(t.size<=s*6){a=t.size/this.fragmentSplitFactor}else{a=s}let i=0;const n=t=>[...this.progressMap.keys()].indexOf(t)+1;while(i{const a=new XMLHttpRequest;a.open("GET",t.url);a.responseType="arraybuffer";a.withCredentials=false;a.addEventListener("progress",t=>{console.log(`[下载视频] 视频片段${n(a)}下载进度: ${t.loaded}/${r} bytes loaded, ${o}`);this.progressMap.set(a,t.loaded);this.updateProgress()});a.addEventListener("load",()=>{if((""+a.status)[0]==="2"){console.log(`[下载视频] 视频片段${n(a)}下载完成`);e(a.response)}else{s(`视频片段${n(a)}请求失败, response = ${a.status}`)}});a.addEventListener("abort",()=>s("canceled"));a.addEventListener("error",()=>{console.error(`[下载视频] 视频片段${n(a)}下载失败: ${o}`);this.progressMap.set(a,0);this.updateProgress();a.open("GET",t.url);a.setRequestHeader("Range",o);a.send()});a.setRequestHeader("Range",o);this.progressMap.set(a,0);a.send();this.workingXhr.push(a)}));i=Math.round(i+a)+1}return Promise.all(e)}async copyUrl(){const t=this.fragments.map(t=>t.url).reduce((t,e)=>t+"\r\n"+e);GM.setClipboard(t,"text")}async showUrl(){const t=this.fragments.map(t=>`\n${t.url}\n`).reduce((t,e)=>t+"\r\n"+e);Toast.success(t+`复制全部`,"显示链接");const e=await SpinQuery.select("#copy-link");e.addEventListener("click",async()=>{await this.copyUrl()})}async exportData(t=false){const e=JSON.stringify([{fragments:this.fragments,title:s(),totalSize:this.fragments.map(t=>t.size).reduce((t,e)=>t+e),referer:document.URL.replace(window.location.search,"")}]);if(t){GM.setClipboard(e,"text")}else{const t=new Blob([e],{type:"text/json"});const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.json`,t);i.add(s()+"."+this.danmakuOption.toLowerCase(),a);await i.emit(`${s()}.zip`)}}async exportAria2(a=false){if(a){const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.${this.danmakuOption==="ASS"?"ass":"xml"}`,a);await i.emit();const o=t.aria2RpcOption;const r=this.fragments.map((t,e)=>{let a="";if(this.fragments.length>1){a=" - "+(e+1)}const i=[];if(o.secretKey!==""){i.push(`token:${o.secretKey}`)}i.push([t.url]);i.push({referer:document.URL.replace(window.location.search,""),"user-agent":UserAgent,out:`${s()}${a}${this.extension(t)}`,split:this.fragmentSplitFactor,dir:o.baseDir+o.dir||undefined,"max-download-limit":o.maxDownloadLimit||undefined});const n=encodeURIComponent(`${s()}${a}`);return{params:i,id:n}});const{sendRpc:l}=await e.importAsync("aria2-rpc");await l(r)}else{const t=`\n# Generated by Bilibili Evolved Video Export\n# https://github.com/the1812/Bilibili-Evolved/\n${this.fragments.map((t,e)=>{let a="";if(this.fragments.length>1){a=" - "+(e+1)}return`\n${t.url}\n referer=${document.URL.replace(window.location.search,"")}\n user-agent=${UserAgent}\n out=${s()}${a}${this.extension(t)}\n split=${this.fragmentSplitFactor}\n`.trim()}).join("\n")}\n`.trim();const e=new Blob([t],{type:"text/plain"});const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.txt`,e);i.add(s()+"."+this.danmakuOption.toLowerCase(),a);await i.emit(`${s()}.zip`)}}extension(t){const e=t||this.fragments[0];const s=[".flv",".mp4",".m4s"].find(t=>e.url.includes(t));if(s){return s}else{console.warn("No extension detected.");return".flv"}}async downloadDanmaku(){if(this.danmakuOption!=="无"){const t=new i(c.cid);await t.fetchInfo();if(this.danmakuOption==="XML"){return t.rawXML}else{const{convertToAss:s}=await e.importAsync("download-danmaku");return s(t.rawXML)}}else{return null}}async download(){this.workingXhr=[];this.progressMap=new Map;this.updateProgress();const t=[];this.videoSpeed.startMeasure();for(const e of this.fragments){const s=await this.downloadFragment(e);t.push(s)}if(t.length<1){throw new Error("下载失败.")}const e=s();const a=new n;t.forEach((s,i)=>{let n;const o=this.fragments[i];if(t.length>1){n=`${e} - ${i+1}${this.extension(o)}`}else{n=`${e}${this.extension(o)}`}a.add(n,new Blob(Array.isArray(s)?s:[s],{type:this.extension(o)===".flv"?"video/x-flv":"video/mp4"}))});const i=await this.downloadDanmaku();a.add(`${s()}.${this.danmakuOption==="ASS"?"ass":"xml"}`,i);await a.emit(e+".zip");this.progress&&this.progress(0);this.videoSpeed.stopMeasure()}}class f{constructor(t){this.lastProgress=0;this.measureInterval=1e3;this.workingDownloader=t}startMeasure(){this.intervalTimer=setInterval(()=>{const t=this.workingDownloader.progressMap?[...this.workingDownloader.progressMap.values()].reduce((t,e)=>t+e,0):0;const e=t-this.lastProgress;if(this.speedUpdate!==undefined){this.speedUpdate(formatFileSize(e)+"/s")}this.lastProgress=t},this.measureInterval)}stopMeasure(){clearInterval(this.intervalTimer)}}async function m(){const t=await SpinQuery.select(()=>(unsafeWindow||window).aid);const e=await SpinQuery.select(()=>(unsafeWindow||window).cid);if(!(t&&e)){return false}c.aid=t;c.cid=e;if(document.URL.includes("bangumi")){c.entity=new r}else if(document.URL.includes("cheese")){const t=document.URL.match(/cheese\/play\/ep([\d]+)/);c.entity=new l(t[1])}else{c.entity=new o}try{d=await h.getAvailableFormats()}catch(t){return false}return true}async function w(){p=d[0];e.applyStyle("downloadVideoStyle");const t=dq("#download-video");t.addEventListener("click",()=>{const t=dq(".download-video");t.classList.toggle("opened");window.scroll(0,0);dq(".gui-settings-mask").click()});t.addEventListener("mouseover",()=>{document.body.insertAdjacentHTML("beforeend",e.import("downloadVideoHtml"));g()},{once:true})}async function g(){let o;const r=new Vue({el:".download-video",components:{VDropdown:()=>e.importAsync("v-dropdown.vue"),VCheckbox:()=>e.importAsync("v-checkbox.vue"),RpcProfiles:()=>e.importAsync("aria2-rpc-profiles.vue")},data:{downloadSingle:true,coverUrl:EmptyImageUrl,aid:c.aid,cid:c.cid,dashModel:{value:t.downloadVideoFormat,items:["flv","dash"]},qualityModel:{value:p.displayName,items:d.map(t=>t.displayName)},danmakuModel:{value:t.downloadVideoDefaultDanmaku,items:["无","XML","ASS"]},codecModel:{value:t.downloadVideoDashCodec,items:["AVC/H.264","HEVC/H.265"]},progressPercent:0,size:"获取大小中",blobUrl:"",episodeList:[],downloading:false,speed:"",batch:false,rpcSettings:t.aria2RpcOption,showRpcSettings:false,busy:false,saveRpcSettingsText:"保存配置",enableDash:t.enableDashDownload,lastDirectDownloadLink:""},computed:{displaySize(){if(typeof this.size==="string"){return this.size}return formatFileSize(this.size)},sizeWarning(){if(typeof this.size==="string"){return false}return this.size>1073741824},selectedEpisodeCount(){return this.episodeList.filter(t=>t.checked).length},dash(){return this.dashModel.value==="dash"}},methods:{close(){this.$el.classList.remove("opened")},danmakuOptionChange(){t.downloadVideoDefaultDanmaku=this.danmakuModel.value},async codecChange(){t.downloadVideoDashCodec=this.codecModel.value;await this.formatChange()},async dashChange(){console.log("dash change");t.downloadVideoFormat=this.dashModel.value;const e=this.dashModel.value;let s=[];if(e==="flv"){s=await h.getAvailableFormats()}else{s=await h.getAvailableDashFormats()}d=s;[p]=e;this.qualityModel.items=s.map(t=>t.displayName);[this.qualityModel.value]=this.qualityModel.items;await this.formatChange()},async formatChange(){console.log("format change");const t=this.getFormat();try{this.size="获取大小中";const e=await t.downloadInfo(this.dash);this.size=e.totalSize}catch(t){this.size="获取大小失败";throw t}},getFormat(){const t=d.find(t=>t.displayName===this.qualityModel.value);if(!t){console.error(`No format found. model value = ${this.qualityModel.value}`);return null}return t},async exportData(t){if(this.busy===true){return}try{this.busy=true;if(!this.downloadSingle){await this.exportBatchData(t);return}const a=this.getFormat();const i=await a.downloadInfo(this.dash);switch(t){case"copyLink":await i.copyUrl();Toast.success("已复制链接到剪贴板.","下载视频",3e3);break;case"showLink":await i.showUrl();break;case"aria2":await i.exportAria2(false);break;case"aria2RPC":await i.exportAria2(true);break;case"copyVLD":await i.exportData(true);Toast.success("已复制VLD数据到剪贴板.","下载视频",3e3);break;case"exportVLD":await i.exportData(false);break;case"ffmpegFragments":if(i.fragments.length<2){Toast.info("当前视频没有分段.","分段列表",3e3)}else{const{getFragmentsList:t}=await e.importAsync("ffmpeg-support");const a=new n;a.add("ffmpeg-files.txt",t(i.fragments.length,s(),i.extension(i.fragments[0])));await a.emit()}break;default:break}}catch(t){logError(t)}finally{this.busy=false}},async exportBatchData(t){const a=this.episodeList;if(a.every(t=>t.checked===false)){Toast.info("请至少选择1集或以上的数量!","批量导出",3e3);return}const o=t=>{const e=a.find(e=>e.cid===t.cid);if(e===undefined){return false}return e.checked};const r=this.getFormat();if(this.danmakuModel.value!=="无"){const t=Toast.info("下载弹幕中...","批量导出");const s=new n;try{if(this.danmakuModel.value==="XML"){for(const t of a.filter(o)){const e=new i(t.cid);await e.fetchInfo();s.add(t.title+".xml",e.rawXML)}}else{const{convertToAss:t}=await e.importAsync("download-danmaku");for(const e of a.filter(o)){const a=new i(e.cid);await a.fetchInfo();s.add(e.title+".ass",await t(a.rawXML))}}await s.emit(this.cid+".danmakus.zip")}catch(t){logError(`弹幕下载失败`)}finally{t.dismiss()}}const l=Toast.info("获取链接中...","批量导出");const c=this.batchExtractor;c.itemFilter=o;let d;try{switch(t){case"aria2":d=await c.collectAria2(r,l,false);await n.single(s(false)+".txt",new Blob([d],{type:"text/plain"}),{ffmpeg:this.ffmpegOption});return;case"aria2RPC":await c.collectAria2(r,l,true);Toast.success(`成功发送了批量请求.`,"aria2 RPC",3e3);return;case"copyVLD":GM.setClipboard(await c.collectData(r,l),{mimetype:"text/plain"});Toast.success("已复制批量vld数据到剪贴板.","批量导出",3e3);return;case"exportVLD":d=await c.collectData(r,l);await n.single(s(false)+".json",new Blob([d],{type:"text/json"}),{ffmpeg:this.ffmpegOption});return;case"ffmpegFragments":{const t=await c.getRawItems(r);const a=new u(r,t[0].fragments);const{getBatchFragmentsList:i}=await e.importAsync("ffmpeg-support");const o=i(t,a.extension());if(!o){Toast.info("所有选择的分P都没有分段.","分段列表",3e3)}else{const t=new n;for(const[e,s]of o.entries()){t.add(e,s)}await t.emit(escapeFilename(`${s(false)}.zip`))}}break;case"ffmpegEpisodes":{const t=await c.getRawItems(r);const s=new u(r,t[0].fragments);const{getBatchEpisodesList:a}=await e.importAsync("ffmpeg-support");const i=a(t,s.extension());const o=new n;o.add("ffmpeg-files.txt",i);await o.emit()}break;default:return}}catch(t){logError(t)}finally{l.dismiss()}},async checkBatch(){const t=["/www.bilibili.com/bangumi","/www.bilibili.com/video/av"];if(!t.some(t=>document.URL.includes(t))){this.batch=false;this.episodeList=[];return}const{BatchExtractor:s}=await e.importAsync("batch-download");if(await s.test()!==true){this.batch=false;this.episodeList=[];return}const a=this.batchExtractor=new s;this.batch=true;this.episodeList=(await a.getItemList()).map((t,e)=>{return{aid:t.aid,cid:t.cid,title:t.title,index:e,checked:true}})},cancelDownload(){if(o){o.cancelDownload()}},async startDownload(){const t=this.getFormat();try{this.downloading=true;const e=await t.downloadInfo(this.dash);e.videoSpeed.speedUpdate=(t=>this.speed=t);e.progress=(t=>{this.progressPercent=Math.trunc(t*100)});o=e;await e.download();this.lastDirectDownloadLink=n.lastPackageUrl}catch(t){if(t!=="canceled"){logError(t)}this.progressPercent=0}finally{this.downloading=false;this.speed=""}},selectAllEpisodes(){this.episodeList.forEach(t=>t.checked=true)},unselectAllEpisodes(){this.episodeList.forEach(t=>t.checked=false)},inverseAllEpisodes(){this.episodeList.forEach(t=>t.checked=!t.checked)},toggleRpcSettings(){this.showRpcSettings=!this.showRpcSettings},saveRpcSettings(){if(this.rpcSettings.host===""){this.rpcSettings.host="127.0.0.1"}if(this.rpcSettings.port===""){this.rpcSettings.port="6800"}t.aria2RpcOption=this.rpcSettings;const e=t.aria2RpcOptionProfiles.find(e=>e.name===t.aria2RpcOptionSelectedProfile);if(e){Object.assign(e,this.rpcSettings);t.aria2RpcOptionProfiles=t.aria2RpcOptionProfiles}this.saveRpcSettingsText="已保存";setTimeout(()=>this.saveRpcSettingsText="保存配置",2e3)},updateProfile(e){t.aria2RpcOption=this.rpcSettings=_.omit(e,"name")}},async mounted(){}});Observer.videoChange(async()=>{r.close();r.batch=false;r.downloadSingle=true;const t=dq("#download-video");const e=await m();t.style.display=e?"flex":"none";if(!e){return}r.aid=c.aid;r.cid=c.cid;try{const t=new a(c.aid);await t.fetchInfo();r.coverUrl=t.coverUrl.replace("http:","https:")}catch(t){r.coverUrl=EmptyImageUrl}r.dashChange();await r.checkBatch()})}return{widget:{content:`\n`,condition:m,success:w}}}})();
+onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/min/download-video.min.js"] = (()=>{return(t,e)=>{const{getFriendlyTitle:s}=e.import("title");const{VideoInfo:a,DanmakuInfo:i}=e.import("video-info");const{DownloadVideoPackage:n}=e.import("download-video-package");class o{async getDashUrl(t){if(t){return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&fnver=0&fnval=16`}else{return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&fnver=0&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&otype=json`}}}class r extends o{async getDashUrl(t){if(t){return`https://api.bilibili.com/pgc/player/web/playurl?avid=56995872&cid=99547543&qn=${t}&otype=json&fourk=1&fnval=16`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=56995872&cid=99547543&otype=json&fourk=1&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=&otype=json`}}}class l extends o{constructor(t){super();this.ep=t}async getDashUrl(t){if(t){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&ep_id=${this.ep}`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&ep_id=${this.ep}`}}}const c={entity:new o,aid:"",cid:""};let d=[];let p=null;class h{constructor(t,e,s){this.quality=t;this.internalName=e;this.displayName=s}async downloadInfo(t=false){const e=new u(this);await e.fetchVideoInfo(t);return e}static parseFormats(t){const e=t.accept_quality;const s=t.accept_format.split(",");const a=t.accept_description;const i=e.map((t,e)=>{return new h(t,s[e],a[e])});return i}static async getAvailableDashFormats(){const t=await c.entity.getDashUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}return h.parseFormats(e.data||e.result||e)}static async getAvailableFormats(){const t=await c.entity.getUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}const s=e.data||e.result||e;return h.parseFormats(s)}}class u{constructor(t,e){this.fragmentSplitFactor=6*2;this.workingXhr=null;this.progressMap=new Map;this.format=t;this.fragments=e||[];this.videoSpeed=new f(this)}get danmakuOption(){return t.downloadVideoDefaultDanmaku}get isDash(){return this.fragments.some(t=>t.url.includes(".m4s"))}get totalSize(){return this.fragments.map(t=>t.size).reduce((t,e)=>t+e)}async fetchVideoInfo(s=false){if(!s){const t=await c.entity.getUrl(this.format.quality);const e=await Ajax.getTextWithCredentials(t);const s=JSON.parse(e.replace(/http:/g,"https:"));const a=s.data||s.result||s;if(a.quality!==this.format.quality){throw new Error("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const i=a.durl;this.fragments=i.map(t=>{return{length:t.length,size:t.size,url:t.url,backupUrls:t.backup_url}})}else{const{dashToFragment:s,getDashInfo:a}=await e.importAsync("video-dash");const i=await a(await c.entity.getDashUrl(this.format.quality),this.format.quality);console.log(i.videoDashes);const n=(()=>{const e=e=>e.videoCodec===t.downloadVideoDashCodec;if(i.videoDashes.some(e)){return i.videoDashes.filter(e).sort(ascendingSort(t=>t.bandWidth))[0]}else{return i.videoDashes.sort(ascendingSort(t=>t.bandWidth))[0]}})();const o=i.audioDashes.sort(descendingSort(t=>t.bandWidth))[0];this.fragments=[s(n),s(o)]}return this.fragments}updateProgress(){const t=this.progressMap?[...this.progressMap.values()].reduce((t,e)=>t+e,0)/this.totalSize:0;if(t>1||t<0){console.error(`[下载视频] 进度异常: ${t}`,this.progressMap.values())}this.progress&&this.progress(t)}cancelDownload(){this.videoSpeed.stopMeasure();if(this.workingXhr!==null){this.workingXhr.forEach(t=>t.abort())}else{logError("Cancel Download Failed: forEach in this.workingXhr not found.")}}downloadFragment(t){const e=[];const s=this.isDash?4*1024*1024:16*1024*1024;let a;if(t.size<=s*6){a=t.size/this.fragmentSplitFactor}else{a=s}let i=0;const n=t=>[...this.progressMap.keys()].indexOf(t)+1;while(i{const a=new XMLHttpRequest;a.open("GET",t.url);a.responseType="arraybuffer";a.withCredentials=false;a.addEventListener("progress",t=>{console.log(`[下载视频] 视频片段${n(a)}下载进度: ${t.loaded}/${r} bytes loaded, ${o}`);this.progressMap.set(a,t.loaded);this.updateProgress()});a.addEventListener("load",()=>{if((""+a.status)[0]==="2"){console.log(`[下载视频] 视频片段${n(a)}下载完成`);e(a.response)}else{s(`视频片段${n(a)}请求失败, response = ${a.status}`)}});a.addEventListener("abort",()=>s("canceled"));a.addEventListener("error",()=>{console.error(`[下载视频] 视频片段${n(a)}下载失败: ${o}`);this.progressMap.set(a,0);this.updateProgress();a.open("GET",t.url);a.setRequestHeader("Range",o);a.send()});a.setRequestHeader("Range",o);this.progressMap.set(a,0);a.send();this.workingXhr.push(a)}));i=Math.round(i+a)+1}return Promise.all(e)}async copyUrl(){const t=this.fragments.map(t=>t.url).reduce((t,e)=>t+"\r\n"+e);GM.setClipboard(t,"text")}async showUrl(){const t=this.fragments.map(t=>`\n${t.url}\n`).reduce((t,e)=>t+"\r\n"+e);Toast.success(t+`复制全部`,"显示链接");const e=await SpinQuery.select("#copy-link");e.addEventListener("click",async()=>{await this.copyUrl()})}async exportData(t=false){const e=JSON.stringify([{fragments:this.fragments,title:s(),totalSize:this.fragments.map(t=>t.size).reduce((t,e)=>t+e),referer:document.URL.replace(window.location.search,"")}]);if(t){GM.setClipboard(e,"text")}else{const t=new Blob([e],{type:"text/json"});const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.json`,t);i.add(s()+"."+this.danmakuOption.toLowerCase(),a);await i.emit(`${s()}.zip`)}}async exportAria2(a=false){if(a){const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.${this.danmakuOption==="ASS"?"ass":"xml"}`,a);await i.emit();const o=t.aria2RpcOption;const r=this.fragments.map((t,e)=>{let a="";if(this.fragments.length>1&&!this.isDash){a=" - "+(e+1)}const i=[];if(o.secretKey!==""){i.push(`token:${o.secretKey}`)}i.push([t.url]);i.push({referer:document.URL.replace(window.location.search,""),"user-agent":UserAgent,out:`${s()}${a}${this.extension(t)}`,split:this.fragmentSplitFactor,dir:o.baseDir+o.dir||undefined,"max-download-limit":o.maxDownloadLimit||undefined});const n=encodeURIComponent(`${s()}${a}`);return{params:i,id:n}});const{sendRpc:l}=await e.importAsync("aria2-rpc");await l(r)}else{const t=`\n# Generated by Bilibili Evolved Video Export\n# https://github.com/the1812/Bilibili-Evolved/\n${this.fragments.map((t,e)=>{let a="";if(this.fragments.length>1&&!this.isDash){a=" - "+(e+1)}return`\n${t.url}\n referer=${document.URL.replace(window.location.search,"")}\n user-agent=${UserAgent}\n out=${s()}${a}${this.extension(t)}\n split=${this.fragmentSplitFactor}\n`.trim()}).join("\n")}\n`.trim();const e=new Blob([t],{type:"text/plain"});const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.txt`,e);i.add(s()+"."+this.danmakuOption.toLowerCase(),a);await i.emit(`${s()}.zip`)}}extension(t){const e=t||this.fragments[0];const s=[".flv",".mp4"].find(t=>e.url.includes(t));if(s){return s}else if(e.url.includes(".m4s")){return this.fragments.indexOf(e)===0?".mp4":".m4a"}else{console.warn("No extension detected.");return".flv"}}async downloadDanmaku(){if(this.danmakuOption!=="无"){const t=new i(c.cid);await t.fetchInfo();if(this.danmakuOption==="XML"){return t.rawXML}else{const{convertToAss:s}=await e.importAsync("download-danmaku");return s(t.rawXML)}}else{return null}}async download(){this.workingXhr=[];this.progressMap=new Map;this.updateProgress();const t=[];this.videoSpeed.startMeasure();for(const e of this.fragments){const s=await this.downloadFragment(e);t.push(s)}if(t.length<1){throw new Error("下载失败.")}const e=s();const a=new n;t.forEach((s,i)=>{let n;const o=this.fragments[i];if(t.length>1&&!this.isDash){n=`${e} - ${i+1}${this.extension(o)}`}else{n=`${e}${this.extension(o)}`}a.add(n,new Blob(Array.isArray(s)?s:[s]))});const i=await this.downloadDanmaku();a.add(`${s()}.${this.danmakuOption==="ASS"?"ass":"xml"}`,i);await a.emit(e+".zip");this.progress&&this.progress(0);this.videoSpeed.stopMeasure()}}class f{constructor(t){this.lastProgress=0;this.measureInterval=1e3;this.workingDownloader=t}startMeasure(){this.intervalTimer=setInterval(()=>{const t=this.workingDownloader.progressMap?[...this.workingDownloader.progressMap.values()].reduce((t,e)=>t+e,0):0;const e=t-this.lastProgress;if(this.speedUpdate!==undefined){this.speedUpdate(formatFileSize(e)+"/s")}this.lastProgress=t},this.measureInterval)}stopMeasure(){clearInterval(this.intervalTimer)}}async function m(){const t=await SpinQuery.select(()=>(unsafeWindow||window).aid);const e=await SpinQuery.select(()=>(unsafeWindow||window).cid);if(!(t&&e)){return false}c.aid=t;c.cid=e;if(document.URL.includes("bangumi")){c.entity=new r}else if(document.URL.includes("cheese")){const t=document.URL.match(/cheese\/play\/ep([\d]+)/);c.entity=new l(t[1])}else{c.entity=new o}try{d=await h.getAvailableFormats()}catch(t){return false}return true}async function w(){p=d[0];e.applyStyle("downloadVideoStyle");const t=dq("#download-video");t.addEventListener("click",()=>{const t=dq(".download-video");t.classList.toggle("opened");window.scroll(0,0);dq(".gui-settings-mask").click()});t.addEventListener("mouseover",()=>{document.body.insertAdjacentHTML("beforeend",e.import("downloadVideoHtml"));g()},{once:true})}async function g(){let o;const r=new Vue({el:".download-video",components:{VDropdown:()=>e.importAsync("v-dropdown.vue"),VCheckbox:()=>e.importAsync("v-checkbox.vue"),RpcProfiles:()=>e.importAsync("aria2-rpc-profiles.vue")},data:{downloadSingle:true,coverUrl:EmptyImageUrl,aid:c.aid,cid:c.cid,dashModel:{value:t.downloadVideoFormat,items:["flv","dash"]},qualityModel:{value:p.displayName,items:d.map(t=>t.displayName)},danmakuModel:{value:t.downloadVideoDefaultDanmaku,items:["无","XML","ASS"]},codecModel:{value:t.downloadVideoDashCodec,items:["AVC/H.264","HEVC/H.265"]},progressPercent:0,size:"获取大小中",blobUrl:"",episodeList:[],downloading:false,speed:"",batch:false,rpcSettings:t.aria2RpcOption,showRpcSettings:false,busy:false,saveRpcSettingsText:"保存配置",enableDash:t.enableDashDownload,lastDirectDownloadLink:""},computed:{displaySize(){if(typeof this.size==="string"){return this.size}return formatFileSize(this.size)},sizeWarning(){if(typeof this.size==="string"){return false}return this.size>1073741824},selectedEpisodeCount(){return this.episodeList.filter(t=>t.checked).length},dash(){return this.dashModel.value==="dash"}},methods:{close(){this.$el.classList.remove("opened")},danmakuOptionChange(){t.downloadVideoDefaultDanmaku=this.danmakuModel.value},async codecChange(){t.downloadVideoDashCodec=this.codecModel.value;await this.formatChange()},async dashChange(){console.log("dash change");t.downloadVideoFormat=this.dashModel.value;const e=this.dashModel.value;let s=[];if(e==="flv"){s=await h.getAvailableFormats()}else{s=await h.getAvailableDashFormats()}d=s;[p]=e;this.qualityModel.items=s.map(t=>t.displayName);[this.qualityModel.value]=this.qualityModel.items;await this.formatChange()},async formatChange(){console.log("format change");const t=this.getFormat();try{this.size="获取大小中";const e=await t.downloadInfo(this.dash);this.size=e.totalSize}catch(t){this.size="获取大小失败";throw t}},getFormat(){const t=d.find(t=>t.displayName===this.qualityModel.value);if(!t){console.error(`No format found. model value = ${this.qualityModel.value}`);return null}return t},async exportData(t){if(this.busy===true){return}try{this.busy=true;if(!this.downloadSingle){await this.exportBatchData(t);return}const a=this.getFormat();const i=await a.downloadInfo(this.dash);switch(t){case"copyLink":await i.copyUrl();Toast.success("已复制链接到剪贴板.","下载视频",3e3);break;case"showLink":await i.showUrl();break;case"aria2":await i.exportAria2(false);break;case"aria2RPC":await i.exportAria2(true);break;case"copyVLD":await i.exportData(true);Toast.success("已复制VLD数据到剪贴板.","下载视频",3e3);break;case"exportVLD":await i.exportData(false);break;case"ffmpegFragments":if(i.fragments.length<2){Toast.info("当前视频没有分段.","分段列表",3e3)}else{const{getFragmentsList:t}=await e.importAsync("ffmpeg-support");const a=new n;a.add("ffmpeg-files.txt",t(i.fragments.length,s(),i.fragments.map(t=>i.extension(t))));await a.emit()}break;default:break}}catch(t){logError(t)}finally{this.busy=false}},async exportBatchData(t){const a=this.episodeList;if(a.every(t=>t.checked===false)){Toast.info("请至少选择1集或以上的数量!","批量导出",3e3);return}const o=t=>{const e=a.find(e=>e.cid===t.cid);if(e===undefined){return false}return e.checked};const r=this.getFormat();if(this.danmakuModel.value!=="无"){const t=Toast.info("下载弹幕中...","批量导出");const s=new n;try{if(this.danmakuModel.value==="XML"){for(const t of a.filter(o)){const e=new i(t.cid);await e.fetchInfo();s.add(t.title+".xml",e.rawXML)}}else{const{convertToAss:t}=await e.importAsync("download-danmaku");for(const e of a.filter(o)){const a=new i(e.cid);await a.fetchInfo();s.add(e.title+".ass",await t(a.rawXML))}}await s.emit(this.cid+".danmakus.zip")}catch(t){logError(`弹幕下载失败`)}finally{t.dismiss()}}const l=Toast.info("获取链接中...","批量导出");const c=this.batchExtractor;c.itemFilter=o;let d;try{switch(t){case"aria2":d=await c.collectAria2(r,l,false);await n.single(s(false)+".txt",new Blob([d],{type:"text/plain"}),{ffmpeg:this.ffmpegOption});return;case"aria2RPC":await c.collectAria2(r,l,true);Toast.success(`成功发送了批量请求.`,"aria2 RPC",3e3);return;case"copyVLD":GM.setClipboard(await c.collectData(r,l),{mimetype:"text/plain"});Toast.success("已复制批量vld数据到剪贴板.","批量导出",3e3);return;case"exportVLD":d=await c.collectData(r,l);await n.single(s(false)+".json",new Blob([d],{type:"text/json"}),{ffmpeg:this.ffmpegOption});return;case"ffmpegFragments":{const t=await c.getRawItems(r);const a=new u(r,t[0].fragments);const{getBatchFragmentsList:i}=await e.importAsync("ffmpeg-support");const o=this.dash?[".mp4","m4a"]:[a.extension()];const l=i(t,o);if(!l){Toast.info("所有选择的分P都没有分段.","分段列表",3e3)}else{const t=new n;for(const[e,s]of l.entries()){t.add(e,s)}await t.emit(escapeFilename(`${s(false)}.zip`))}}break;case"ffmpegEpisodes":{const t=await c.getRawItems(r);const s=new u(r,t[0].fragments);const{getBatchEpisodesList:a}=await e.importAsync("ffmpeg-support");const i=this.dash?[".mp4","m4a"]:[s.extension()];const o=a(t,i);const l=new n;l.add("ffmpeg-files.txt",o);await l.emit()}break;default:return}}catch(t){logError(t)}finally{l.dismiss()}},async checkBatch(){const t=["/www.bilibili.com/bangumi","/www.bilibili.com/video/av"];if(!t.some(t=>document.URL.includes(t))){this.batch=false;this.episodeList=[];return}const{BatchExtractor:s}=await e.importAsync("batch-download");if(await s.test()!==true){this.batch=false;this.episodeList=[];return}const a=this.batchExtractor=new s;this.batch=true;this.episodeList=(await a.getItemList()).map((t,e)=>{return{aid:t.aid,cid:t.cid,title:t.title,index:e,checked:true}})},cancelDownload(){if(o){o.cancelDownload()}},async startDownload(){const t=this.getFormat();try{this.downloading=true;const e=await t.downloadInfo(this.dash);e.videoSpeed.speedUpdate=(t=>this.speed=t);e.progress=(t=>{this.progressPercent=Math.trunc(t*100)});o=e;await e.download();this.lastDirectDownloadLink=n.lastPackageUrl}catch(t){if(t!=="canceled"){logError(t)}this.progressPercent=0}finally{this.downloading=false;this.speed=""}},selectAllEpisodes(){this.episodeList.forEach(t=>t.checked=true)},unselectAllEpisodes(){this.episodeList.forEach(t=>t.checked=false)},inverseAllEpisodes(){this.episodeList.forEach(t=>t.checked=!t.checked)},toggleRpcSettings(){this.showRpcSettings=!this.showRpcSettings},saveRpcSettings(){if(this.rpcSettings.host===""){this.rpcSettings.host="127.0.0.1"}if(this.rpcSettings.port===""){this.rpcSettings.port="6800"}t.aria2RpcOption=this.rpcSettings;const e=t.aria2RpcOptionProfiles.find(e=>e.name===t.aria2RpcOptionSelectedProfile);if(e){Object.assign(e,this.rpcSettings);t.aria2RpcOptionProfiles=t.aria2RpcOptionProfiles}this.saveRpcSettingsText="已保存";setTimeout(()=>this.saveRpcSettingsText="保存配置",2e3)},updateProfile(e){t.aria2RpcOption=this.rpcSettings=_.omit(e,"name")}},async mounted(){}});Observer.videoChange(async()=>{r.close();r.batch=false;r.downloadSingle=true;const t=dq("#download-video");const e=await m();t.style.display=e?"flex":"none";if(!e){return}r.aid=c.aid;r.cid=c.cid;try{const t=new a(c.aid);await t.fetchInfo();r.coverUrl=t.coverUrl.replace("http:","https:")}catch(t){r.coverUrl=EmptyImageUrl}r.dashChange();await r.checkBatch()})}return{widget:{content:`\n`,condition:m,success:w}}}})();
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/min/dpi-img.vue.min.js"] = (()=>{return(t,s)=>{const e=`
`;return{export:Object.assign({template:e},{props:["size","src","blur","root","rootMargin","threshold"],data(){return{srcset:null,actualSrc:null}},methods:{calcSrc(){if(!this.src||!this.size){return null}const t=this.src.substring(this.src.lastIndexOf(".")+1);this.srcset=getDpiSourceSet(this.src,this.size,t);this.actualSrc=this.src}},mounted(){const t={root:this.root,rootMargin:this.rootMargin||"200px",threshold:this.threshold};const s=new IntersectionObserver(t=>{t.forEach(t=>{if(t.isIntersecting){this.calcSrc();s.disconnect()}})},t);s.observe(this.$el)},computed:{width(){if(typeof this.size==="object"&&"width"in this.size){return this.size.width}return null},height(){if(typeof this.size==="object"&&"height"in this.size){return this.size.height}return null}}})}}})();
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/min/expand-danmaku.min.js"] = (()=>{return(e,a)=>{if(typeof isEmbeddedPlayer!=="undefined"&&isEmbeddedPlayer()){return}Observer.videoChange(async()=>{const e=await SpinQuery.select(".bui-collapse-wrap");if(e&&e.classList.contains("bui-collapse-wrap-folded")){const e=await SpinQuery.select(".bui-collapse-header");e.click()}})}})();
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/min/expand-description.min.css"] = `.play-up-info .play-up-self,.video-desc .info{height:auto!important}.play-up-info .play-up-self-btn,.video-desc .btn{display:none!important}`;
@@ -1098,7 +1098,7 @@ onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/m
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/min/feeds-apis.min.js"] = (()=>{return(e,t)=>{const a={repost:{id:1,name:"转发"},textWithImages:{id:2,name:"图文"},text:{id:4,name:"文字"},video:{id:8,name:"视频"},miniVideo:{id:16,name:"小视频"},column:{id:64,name:"专栏"},audio:{id:256,name:"音频"},bangumi:{id:512,name:"番剧"},share:{id:2048,name:"分享"}};class i extends EventTarget{constructor(){super(...arguments);this.cards=[]}addEventListener(e,t,a){super.addEventListener(e,t,a)}removeEventListener(e,t,a){super.removeEventListener(e,t,a)}async addCard(e){if(e instanceof HTMLElement&&e.classList.contains("card")){if(e.querySelector(".skeleton")!==null){const t=Observer.childList(e,()=>{if(e.querySelector(".skeleton")===null){t.stop();this.addCard(e)}})}else{const t=await this.parseCard(e);this.cards.push(t);const a=new CustomEvent("addCard",{detail:t});this.dispatchEvent(a)}}}async removeCard(e){if(e instanceof HTMLElement&&e.classList.contains("card")){const t=(await this.parseCard(e)).id;const a=this.cards.findIndex(e=>e.id===t);const i=this.cards[a];this.cards.splice(a,1);const n=new CustomEvent("removeCard",{detail:i});this.dispatchEvent(n)}}async parseCard(e){const t=async t=>{const a=await SpinQuery.condition(()=>e.querySelector(t),e=>e!==null);if(a===null){console.warn(e,t);return""}return a.innerText};const i=async e=>{const a=parseInt(await t(e));if(isNaN(a)){return 0}return a};const n=(()=>{if(e.querySelector(".repost")){return a.repost}if(e.querySelector(".imagesbox")){return a.textWithImages}if(e.querySelector(".video-container")){return a.video}if(e.querySelector(".bangumi-container")){return a.bangumi}if(e.querySelector(".article-container")){return a.column}if(e.querySelector(".music-container")){return a.audio}if(e.querySelector(".h5share-container")){return a.share}if(e.querySelector(".vc-ctnr")){return a.miniVideo}return a.text})();const r={id:e.getAttribute("data-did"),username:await t(".main-content .user-name"),text:await t(".card-content .text.description,.video-container .title,.bangumi-container .title"),reposts:await i(".button-bar .single-button:nth-child(1) .text-offset"),comments:await i(".button-bar .single-button:nth-child(2) .text-offset"),likes:await i(".button-bar .single-button:nth-child(3) .text-offset"),element:e,type:n};e.setAttribute("data-type",n.id.toString());return r}async startWatching(){const e=await SpinQuery.select(".card-list .content");if(!e){return false}const t=[...e.querySelectorAll(".content>.card")];t.forEach(e=>this.addCard(e));Observer.childList(e,e=>{e.forEach(e=>{e.addedNodes.forEach(e=>this.addCard(e));e.removedNodes.forEach(e=>this.removeCard(e))})});return true}}const n=new i;const r=async(e="video")=>{const a=await Ajax.getJsonWithCredentials(`https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_new?uid=${getUID()}&type_list=${e==="video"?8:512}`);if(a.code!==0){throw new Error(a.message)}if(e==="video"){const{getWatchlaterList:e}=await t.importAsync("watchlater-api");const i=await e();return a.data.cards.map(e=>{const t=JSON.parse(e.card);const a=_.get(e,"display.topic_info.topic_details",[]).map(e=>{return{id:e.topic_id,name:e.topic_name}});return{id:e.desc.dynamic_id_str,aid:t.aid,title:t.title,upID:e.desc.user_profile.info.uid,upName:e.desc.user_profile.info.uname,upFaceUrl:e.desc.user_profile.info.face,coverUrl:t.pic,description:t.desc,timestamp:e.timestamp,time:new Date(e.timestamp*1e3),topics:a,dynamic:t.dynamic,like:formatCount(e.desc.like),duration:t.duration,durationText:formatDuration(t.duration,0),playCount:formatCount(t.stat.view),danmakuCount:formatCount(t.stat.danmaku),watchlater:i.includes(t.aid)}})}else if(e==="bangumi"){return a.data.cards.map(e=>{const t=JSON.parse(e.card);return{id:e.desc.dynamic_id_str,aid:t.aid,epID:t.episode_id,title:t.new_desc,upName:t.apiSeasonInfo.title,upFaceUrl:t.apiSeasonInfo.cover,coverUrl:t.cover,description:"",timestamp:e.timestamp,time:new Date(e.timestamp*1e3),like:formatCount(e.desc.like),durationText:"",playCount:formatCount(t.play_count),danmakuCount:formatCount(t.bullet_count),watchlater:false}})}else{return[]}};return{export:{feedsCardsManager:n,feedsCardTypes:a,getVideoFeeds:r}}}})();
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/min/feeds-filter-card.vue.min.js"] = (()=>{return(e,t)=>{const i=``;t.applyStyleFromText(`body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-audio .feed-card .card[data-type="256"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-bangumi .feed-card .card[data-type="512"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-column .feed-card .card[data-type="64"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-miniVideo .feed-card .card[data-type="16"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-repost .feed-card .card[data-type="1"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-share .feed-card .card[data-type="2048"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-text .feed-card .card[data-type="4"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-textWithImages .feed-card .card[data-type="2"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-video .feed-card .card[data-type="8"]{display:none!important}body.enable-feeds-filter:not(.disable-feeds-filter) .left-panel>*,body.enable-feeds-filter:not(.disable-feeds-filter) .right-panel>*{margin:0 0 8px!important}body.enable-feeds-filter:not(.disable-feeds-filter) .feed-card .card.pattern-block,body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-side-block-following-tags .left-panel .tag-panel,body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-side-block-live .right-panel .live-panel,body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-side-block-notice .right-panel .notice-panel,body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-side-block-profile .left-panel .user-wrapper,body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-side-block-trending-tags .right-panel .tag-panel{display:none!important}.feeds-filter{background-color:#fff;width:100%;padding:12px 16px;float:left;border-radius:4px;box-sizing:border-box;display:none;flex-direction:column}body.enable-feeds-filter:not(.disable-feeds-filter) .feeds-filter{display:flex}.feeds-filter,.feeds-filter *{transition:.2s ease-out}body.dark .feeds-filter{color:#eee;background-color:#444}.feeds-filter h1{font-weight:400;font-size:14px;margin:0 0 14px}.feeds-filter h2{font-weight:700;font-size:13px;margin:0 0 8px}.feeds-filter .feeds-filter-swtich:not(:last-child){margin-bottom:4px}.feeds-filter .feeds-filter-swtich label{cursor:pointer;margin:0;padding:4px 8px;border-radius:4px;background-color:#0001;display:flex;align-items:center;justify-content:space-between;border:1px solid transparent}.feeds-filter .feeds-filter-swtich label .name{font-size:12px}.feeds-filter .feeds-filter-swtich label .disabled{color:var(--theme-color)!important}.feeds-filter .feeds-filter-swtich label:hover{background-color:#0002}.feeds-filter .feeds-filter-swtich label input{display:none}.feeds-filter .feeds-filter-swtich label .be-icon{font-size:16px}.feeds-filter .feeds-filter-swtich label .be-icon.disabled{display:none}.feeds-filter .feeds-filter-swtich label.disabled{border-color:var(--theme-color)}.feeds-filter .feeds-filter-swtich label.disabled .be-icon{display:none}.feeds-filter .feeds-filter-swtich label.disabled .be-icon.disabled{display:block}.feeds-filter .filter-type-switch{flex:0 0 49%}.feeds-filter .filter-side-card-switch{flex:0 0 100%}.feeds-filter .filter-types{display:flex;flex-wrap:wrap;justify-content:space-between;margin-bottom:18px}.feeds-filter .filter-patterns:not(:empty){margin-bottom:8px}.feeds-filter .filter-patterns .pattern{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;border-radius:4px;background-color:#0001;font-size:12px}.feeds-filter .filter-patterns .pattern:not(:last-child){margin-bottom:4px}.feeds-filter .filter-patterns .pattern .be-icon{font-size:18px;cursor:pointer}.feeds-filter .add-pattern{display:flex;align-items:center;margin-bottom:18px}.feeds-filter .add-pattern input{color:inherit;background-color:transparent;font-size:12px;border:1px solid #8884;border-radius:4px;outline:0!important;padding:4px;flex:1 0 0;width:0}.feeds-filter .add-pattern input:focus{border-color:var(--theme-color)}.feeds-filter .add-pattern .be-icon{font-size:18px;cursor:pointer;margin-left:8px}`,"feeds-filter-card-style");const d={0:{className:"profile",displayName:"个人资料"},1:{className:"following-tags",displayName:"关注的话题"},2:{className:"notice",displayName:"公告栏"},3:{className:"live",displayName:"正在直播"},4:{className:"trending-tags",displayName:"热门话题"}};const s="feeds-filter-side-block-";return{export:Object.assign({template:i},{components:{FilterTypeSwitch:()=>t.importAsync("filter-type-switch.vue"),Icon:()=>t.importAsync("icon.vue")},methods:{updateCard(t){const i=(e,t)=>{if(e.startsWith("/")&&e.endsWith("/")){return new RegExp(e.slice(1,e.length-1)).test(t)}return t.includes(e)};const d=(()=>{return e.feedsFilterPatterns.some(e=>{const d=e.match(/(.+) up:([^ ]+)/);if(d){return i(d[1],t.text)&&i(d[2],t.username)}return i(e,t.text)})})();if(d){t.element.classList.add("pattern-block")}else{t.element.classList.remove("pattern-block")}},deletePattern(t){const i=e.feedsFilterPatterns.indexOf(t);if(i!==-1){this.patterns.splice(i,1)}},addPattern(e){if(e&&!this.patterns.includes(e)){this.patterns.push(e)}this.newPattern=""},updateBlockSide(){Object.entries(d).forEach(([e,t])=>{const i=s+t.className;document.body.classList[this.blockSideCards.includes(e)?"add":"remove"](i)})},toggleBlockSide(t){const i=this.blockSideCards.indexOf(t);const a=d[t];if(i!==-1){this.blockSideCards.splice(i,1);document.body.classList.remove(s+a.className)}else{this.blockSideCards.push(t);document.body.classList.add(s+a.className)}e.feedsFilterSideCards=this.blockSideCards},sideDisabled(e){return this.blockSideCards.includes(e)}},watch:{patterns(){e.feedsFilterPatterns=this.patterns;if(this.feedsCardsManager!==null){this.feedsCardsManager.cards.forEach(e=>this.updateCard(e))}}},data(){return{allTypes:[],patterns:[...e.feedsFilterPatterns],newPattern:"",feedsCardsManager:null,allSideCards:d,blockSideCards:[...e.feedsFilterSideCards]}},async mounted(){this.updateBlockSide();const e=await SpinQuery.select(".feed-card .tab-bar");if(!e){console.error("tabBar not found");return}const i=e.querySelector(".tab:nth-child(2) .tab-text");Observer.attributes(i,()=>{document.body.classList[i.classList.contains("selected")?"add":"remove"]("enable-feeds-filter")});const{feedsCardsManager:d,feedsCardTypes:s}=await t.importAsync("feeds-apis");const a=await d.startWatching();if(!a){console.error("feedsCardsManager.startWatching() failed");return}this.allTypes=Object.entries(s);d.cards.forEach(e=>this.updateCard(e));d.addEventListener("addCard",e=>{const t=e.detail;this.updateCard(t)});this.feedsCardsManager=d}})}}})();
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/min/feeds-filter.min.js"] = (()=>{return(e,t)=>{(async()=>{if(document.URL.replace(location.search,"")!=="https://t.bilibili.com/"){return}const e=await SpinQuery.select(".home-container .left-panel");if(e===null){return}e.insertAdjacentHTML("beforeend",html``);new Vue({el:"feeds-filter-card",components:{FeedsFilterCard:()=>t.importAsync("feeds-filter-card.vue")}})})();return{reload:()=>document.body.classList.remove("disable-feeds-filter"),unload:()=>document.body.classList.add("disable-feeds-filter")}}})();
-onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/min/ffmpeg-support.min.js"] = (()=>{return(e,t)=>{const n=(e,t,n)=>{if(e<2){return null}const r=[];for(let s=1;s<=e;s++){r.push(escapeFilename(`file '${t} - ${s}${n}'`))}return r.join("\n")};const r=(e,t)=>{const n=e=>e.fragments.length>1;const r=e.filter(n);if(r.length===0){return null}const s=new Map;r.forEach(e=>{s.set(escapeFilename(`ffmpeg-files-${e.title}.txt`),e.fragments.map((n,r)=>{return escapeFilename(`file '${e.title} - ${r+1}${t}'`)}).join("\n"))});return s};const s=(e,t)=>{const n=[];e.forEach(e=>{e.fragments.forEach((r,s)=>{let i="";if(e.fragments.length>1){i=` - ${s+1}`}n.push(escapeFilename(`file '${e.title}${i}${t}'`))})});return n.join("\n")};return{export:{getFragmentsList:n,getBatchFragmentsList:r,getBatchEpisodesList:s}}}})();
+onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/min/ffmpeg-support.min.js"] = (()=>{return(e,t)=>{const n=(e,t,n)=>{if(e<2){return null}const s=[];for(let r=1;r<=e;r++){let e=` - ${r}`;if(n.includes(".m4a")){e=""}s.push(escapeFilename(`file '${t}${e}${n[r-1]}'`))}return s.join("\n")};const s=(e,t)=>{const n=e=>e.fragments.length>1;const s=e.filter(n);if(s.length===0){return null}const r=new Map;s.forEach(e=>{r.set(escapeFilename(`ffmpeg-files-${e.title}.txt`),e.fragments.map((n,s)=>{return escapeFilename(`file '${e.title} - ${s+1}${t[s]}'`)}).join("\n"))});return r};const r=(e,t)=>{const n=[];e.forEach(e=>{e.fragments.forEach((s,r)=>{let i="";if(e.fragments.length>1&&!t.includes(".m4a")){i=` - ${r+1}`}n.push(escapeFilename(`file '${e.title}${i}${t[r]}'`))})});return n.join("\n")};return{export:{getFragmentsList:n,getBatchFragmentsList:s,getBatchEpisodesList:r}}}})();
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/min/fill-with-comments.min.js"] = (()=>{return(t,n)=>{const o="fill-with-comments-style";const i=t=>{if(t){n.applyStyleFromText(`\n .v-wrap { position: relative !important; }\n .v-wrap .l-con { width: 100% !important; }\n .v-wrap .r-con {\n position: absolute !important;\n top: 0 !important;\n right: 0 !important;\n }\n .video-desc .info { width: auto !important; }\n`,o)}else{dqa("#"+o).forEach(t=>t.remove())}};return{export:{fillWithComments:i}}}})();
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/min/filter-type-switch.vue.min.js"] = (()=>{return(e,s)=>{const i=``;return{export:Object.assign({template:i},{components:{Icon:()=>s.importAsync("icon.vue")},props:["name","type"],methods:{setFilter(s,i=true){document.body.classList[s?"add":"remove"](`feeds-filter-block-${this.name}`);if(!i){return}if(s){e.feedsFilterTypes.push(this.type.id)}else{const s=e.feedsFilterTypes.indexOf(this.type.id);if(s!==-1){e.feedsFilterTypes.splice(s,1)}}e.feedsFilterTypes=e.feedsFilterTypes}},data(){const s=e.feedsFilterTypes.includes(this.type.id);this.setFilter(s,false);return{disabled:s}},watch:{disabled(e){this.setFilter(e)}}})}}})();
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/min/fix-fullscreen.min.js"] = (()=>{return(e,n)=>{unsafeWindow.Element.ALLOW_KEYBOARD_INPUT={};const t=unsafeWindow.Element.prototype.requestFullscreen;unsafeWindow.Element.prototype.requestFullscreen=function(){t.call(this)}}})();
diff --git a/bilibili-evolved.user.js b/bilibili-evolved.user.js
index 914c7bf18..c46c976c5 100644
--- a/bilibili-evolved.user.js
+++ b/bilibili-evolved.user.js
@@ -1089,7 +1089,7 @@ onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/mi
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video-package.min.js"] = (()=>{return(e,t)=>{class n{constructor(e={}){this.config=e;this.entries=[]}download(e,t){const a=document.createElement("a");const i=URL.createObjectURL(t);if(n.lastPackageUrl){URL.revokeObjectURL(n.lastPackageUrl)}n.lastPackageUrl=i;a.setAttribute("href",i);a.setAttribute("download",escapeFilename(e));document.body.appendChild(a);a.click();a.remove()}add(e,t){if(t===null||t===undefined){return}this.entries.push({name:escapeFilename(e),data:t})}async blob(){if(this.entries.length===0){return null}if(this.entries.length===1){const e=this.entries[0].data;return typeof e==="string"?new Blob([e]):e}const e=new JSZip;this.entries.forEach(({name:t,data:n})=>{e.file(t,n)});return await e.generateAsync({type:"blob"})}async emit(e){if(this.entries.length===0){return}if(!e||this.entries.length===1){e=this.entries[0].name}const t=await this.blob();if(!t){return}return this.download(e,t)}static async single(e,t,a={}){const i=new n(a);i.add(e,t);return await i.emit()}}n.lastPackageUrl="";return{export:{DownloadVideoPackage:n}}}})();
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.css"] = `.download-video{--download-video-background:white;--download-video-foreground:black;position:absolute;top:96px;left:50%;transform:translateX(-50%) scale(.95);background:var(--download-video-background);color:var(--download-video-foreground);box-shadow:rgba(0,0,0,.2) 0 4px 8px 0;z-index:10001;pointer-events:none;opacity:0;padding:16px;width:300px;display:flex;flex-direction:column;align-items:stretch;justify-content:space-between}.download-video,.download-video *{transition:.2s ease-out;-webkit-tap-highlight-color:transparent!important}.download-video.opened{pointer-events:initial;opacity:1;transform:translateX(-50%) scale(1)}body.dark .download-video{--download-video-background:#222;--download-video-foreground:#eee}.round-corner .download-video,.round-corner .download-video .episode-list .v-checkbox,.round-corner .download-video .rpc-settings{border-radius:var(--large-corner-radius)}.round-corner .download-video .button,.round-corner .download-video .cover,.round-corner .download-video .direct-download .progress .background,.round-corner .download-video .direct-download .progress .foreground,.round-corner .download-video .rpc-settings input[type=text],.round-corner .download-video .title,.round-corner .download-video button{border-radius:var(--corner-radius)}.download-video .cover{min-height:100px;max-height:120px;object-fit:contain}.download-video h1{font-size:13pt;font-weight:700;color:var(--download-video-foreground)}.download-video h2{font-size:11pt;font-weight:700;color:var(--download-video-foreground)}.download-video .header{display:flex;justify-content:space-between;align-items:center}.download-video .header .grow{flex-grow:1}.download-video .header .mdi-download{font-size:16pt;color:var(--download-video-foreground);margin-right:8px}.download-video .header .mdi-close{font-size:16pt;color:var(--download-video-foreground);cursor:pointer}.download-video .header .mdi-close:hover{color:var(--theme-color)}.download-video .info{display:flex;flex-direction:column;align-items:center;margin-top:12px}.download-video .title{display:flex;flex-direction:column;justify-content:space-between;align-items:stretch;margin-top:12px}.download-video .title .bold{width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center}.download-video .title .size{font-size:10pt;color:var(--download-video-foreground);align-self:center;display:flex;align-items:center;height:24px}.download-video .bold{color:var(--download-video-foreground);font-weight:700;font-size:12pt}.download-video .option-item{display:flex;justify-content:space-between;align-items:center;padding-top:12px;font-size:10pt}.download-video .tabs{display:flex;padding:12px 0;font-size:10pt}.download-video .tabs .tab{cursor:pointer;position:relative;opacity:.5}.download-video .tabs .tab.active{font-weight:700;opacity:1}.download-video .tabs .tab:not(:last-child){margin-right:16px}.download-video .tabs .tab::after{content:"";position:absolute;border-radius:2px;background-color:var(--theme-color);height:3px;width:80%;left:10%;bottom:-8px;transition:.2s ease-out;transform:scaleX(0)}.download-video .tabs .tab.active::after{transform:scaleX(1)}.download-video .separator{height:1px;background:#8884;width:100%;margin:12px 0;flex-shrink:0}.download-video .direct-download{display:flex;flex-direction:column;align-items:start;justify-content:space-between}.download-video .button,.download-video button{border:none;outline:0!important;padding:6px 16px;font-size:10pt;cursor:pointer;background:#8884;color:var(--download-video-foreground)}.download-video .button:hover,.download-video button:hover{background:#8886}.download-video .primary{background:var(--theme-color);color:var(--foreground-color);align-self:center}.download-video .primary:hover{background:var(--theme-color-90)}.download-video .busy .button,.download-video .busy .primary,.download-video .busy button,.download-video button:disabled{background-color:#0001;color:#8884;cursor:not-allowed}.download-video .busy .button,.download-video .busy button{cursor:wait!important}.download-video .direct-download .progress{align-self:stretch;display:flex;align-items:center;margin-top:8px}.download-video .direct-download .progress .background{flex-grow:1;height:4px;background:#8884;margin-right:4px;position:relative}.download-video .direct-download .progress .background .foreground{position:absolute;top:0;left:0;height:4px;background:linear-gradient(to right,var(--theme-color),var(--theme-color-60))}.download-video .direct-download .progress .percent{width:50px;text-align:right}.download-video .actions{display:flex;flex-wrap:wrap;justify-content:space-between;margin:8px -4px 0}.download-video .actions>*{margin:4px;flex-grow:1;flex-basis:calc(50% - 16px);display:flex;justify-content:center;align-items:center}.download-video i.mdi-alert-circle{font-size:14pt;color:#ff9800}.download-video .size-warning{position:relative;padding:0 8px}.download-video .size-warning-tip{position:absolute;bottom:100%;left:50%;transform:translateX(-50%);background:var(--download-video-background);color:var(--download-video-foreground);border:1px dashed var(--theme-color);z-index:2;font-size:10pt;width:200px;padding:8px;box-shadow:rgba(0,0,0,.2) 0 4px 8px 0;pointer-events:none;opacity:0}.download-video .size-warning:hover .size-warning-tip{opacity:1}.download-video .episode-list .v-checkbox{padding:4px 8px;margin:4px 0;position:relative;background-color:transparent}.download-video .episode-list .v-checkbox.checked{background-color:#8882}.download-video .episode-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}.download-video .episode-list{overflow:auto;max-height:320px}.download-video button.list-tool{padding:4px;line-height:1;font-size:12pt;margin:0 4px}.download-video .episode-header h2{flex-grow:1}.download-video .selected-count{width:64px;text-align:right}.download-video .aria2-rpc .mdi{margin-left:8px;font-size:14pt;line-height:1}.download-video .aria2-rpc{position:relative}.download-video .rpc-settings{position:absolute;display:flex;flex-direction:column;align-items:stretch;color:var(--download-video-foreground);background:#fff;bottom:120%;left:50%;cursor:initial;box-shadow:rgba(0,0,0,.2) 0 4px 8px 0;transform-origin:bottom;transform:translateX(-50%) scale(.9);opacity:0;pointer-events:none;padding:8px;z-index:3;transition:.3s cubic-bezier(.18,.89,.32,1.28);width:120%}body.dark .download-video .rpc-settings{background:#282828}.download-video .rpc-settings>*{margin:8px}.download-video .rpc-settings.show{opacity:1;transform:translateX(-50%) scale(1);pointer-events:initial}.download-video .rpc-settings input[type=text]{background:0 0;color:var(--download-video-foreground);border:1px solid #8884;padding:4px;margin-left:8px}.download-video .rpc-settings input[type=text]:focus{border-color:var(--theme-color)}.download-video .rpc-settings .operations{display:flex;align-items:center;justify-content:space-evenly}.download-video .final-dir{word-break:break-all}.download-video .rpc-settings-item{display:flex;align-items:center;justify-content:space-between;white-space:nowrap}.download-video .rpc-settings-item input[type=text]{flex-grow:1;margin-left:24px}.download-video button.cancel-download,.download-video button.start-download{margin-top:8px}.download-video .direct-download-header{align-self:stretch;display:flex;justify-content:space-between;align-items:center}body.dark .download-video .direct-download .progress .foreground{background:linear-gradient(to right,var(--theme-color-70),var(--theme-color))}`;
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.html"] = `![]()
警告: 过大的视频大小会在直接下载时占用大量内存, 并可能导致浏览器标签页崩溃. 请考虑降低清晰度或使用导出选项.
预计大小: {{displaySize}}导出
`;
-onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.js"] = (()=>{return(t,e)=>{const{getFriendlyTitle:s}=e.import("title");const{VideoInfo:a,DanmakuInfo:i}=e.import("video-info");const{DownloadVideoPackage:n}=e.import("download-video-package");class o{async getDashUrl(t){if(t){return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&fnver=0&fnval=16`}else{return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&fnver=0&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&otype=json`}}}class r extends o{async getDashUrl(t){if(t){return`https://api.bilibili.com/pgc/player/web/playurl?avid=56995872&cid=99547543&qn=${t}&otype=json&fourk=1&fnval=16`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=56995872&cid=99547543&otype=json&fourk=1&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=&otype=json`}}}class l extends o{constructor(t){super();this.ep=t}async getDashUrl(t){if(t){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&ep_id=${this.ep}`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&ep_id=${this.ep}`}}}const c={entity:new o,aid:"",cid:""};let d=[];let p=null;class h{constructor(t,e,s){this.quality=t;this.internalName=e;this.displayName=s}async downloadInfo(t=false){const e=new u(this);await e.fetchVideoInfo(t);return e}static parseFormats(t){const e=t.accept_quality;const s=t.accept_format.split(",");const a=t.accept_description;const i=e.map((t,e)=>{return new h(t,s[e],a[e])});return i}static async getAvailableDashFormats(){const t=await c.entity.getDashUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}return h.parseFormats(e.data||e.result||e)}static async getAvailableFormats(){const t=await c.entity.getUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}const s=e.data||e.result||e;return h.parseFormats(s)}}class u{constructor(t,e){this.fragmentSplitFactor=6*2;this.workingXhr=null;this.progressMap=new Map;this.format=t;this.fragments=e||[];this.videoSpeed=new f(this)}get danmakuOption(){return t.downloadVideoDefaultDanmaku}get isDash(){return this.fragments.some(t=>t.url.includes(".m4s"))}get totalSize(){return this.fragments.map(t=>t.size).reduce((t,e)=>t+e)}async fetchVideoInfo(s=false){if(!s){const t=await c.entity.getUrl(this.format.quality);const e=await Ajax.getTextWithCredentials(t);const s=JSON.parse(e.replace(/http:/g,"https:"));const a=s.data||s.result||s;if(a.quality!==this.format.quality){throw new Error("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const i=a.durl;this.fragments=i.map(t=>{return{length:t.length,size:t.size,url:t.url,backupUrls:t.backup_url}})}else{const{dashToFragment:s,getDashInfo:a}=await e.importAsync("video-dash");const i=await a(await c.entity.getDashUrl(this.format.quality),this.format.quality);console.log(i.videoDashes);const n=(()=>{const e=e=>e.videoCodec===t.downloadVideoDashCodec;if(i.videoDashes.some(e)){return i.videoDashes.filter(e).sort(ascendingSort(t=>t.bandWidth))[0]}else{return i.videoDashes.sort(ascendingSort(t=>t.bandWidth))[0]}})();const o=i.audioDashes.sort(descendingSort(t=>t.bandWidth))[0];this.fragments=[s(n),s(o)]}return this.fragments}updateProgress(){const t=this.progressMap?[...this.progressMap.values()].reduce((t,e)=>t+e,0)/this.totalSize:0;if(t>1||t<0){console.error(`[下载视频] 进度异常: ${t}`,this.progressMap.values())}this.progress&&this.progress(t)}cancelDownload(){this.videoSpeed.stopMeasure();if(this.workingXhr!==null){this.workingXhr.forEach(t=>t.abort())}else{logError("Cancel Download Failed: forEach in this.workingXhr not found.")}}downloadFragment(t){const e=[];const s=this.isDash?4*1024*1024:16*1024*1024;let a;if(t.size<=s*6){a=t.size/this.fragmentSplitFactor}else{a=s}let i=0;const n=t=>[...this.progressMap.keys()].indexOf(t)+1;while(i{const a=new XMLHttpRequest;a.open("GET",t.url);a.responseType="arraybuffer";a.withCredentials=false;a.addEventListener("progress",t=>{console.log(`[下载视频] 视频片段${n(a)}下载进度: ${t.loaded}/${r} bytes loaded, ${o}`);this.progressMap.set(a,t.loaded);this.updateProgress()});a.addEventListener("load",()=>{if((""+a.status)[0]==="2"){console.log(`[下载视频] 视频片段${n(a)}下载完成`);e(a.response)}else{s(`视频片段${n(a)}请求失败, response = ${a.status}`)}});a.addEventListener("abort",()=>s("canceled"));a.addEventListener("error",()=>{console.error(`[下载视频] 视频片段${n(a)}下载失败: ${o}`);this.progressMap.set(a,0);this.updateProgress();a.open("GET",t.url);a.setRequestHeader("Range",o);a.send()});a.setRequestHeader("Range",o);this.progressMap.set(a,0);a.send();this.workingXhr.push(a)}));i=Math.round(i+a)+1}return Promise.all(e)}async copyUrl(){const t=this.fragments.map(t=>t.url).reduce((t,e)=>t+"\r\n"+e);GM.setClipboard(t,"text")}async showUrl(){const t=this.fragments.map(t=>`\n${t.url}\n`).reduce((t,e)=>t+"\r\n"+e);Toast.success(t+`复制全部`,"显示链接");const e=await SpinQuery.select("#copy-link");e.addEventListener("click",async()=>{await this.copyUrl()})}async exportData(t=false){const e=JSON.stringify([{fragments:this.fragments,title:s(),totalSize:this.fragments.map(t=>t.size).reduce((t,e)=>t+e),referer:document.URL.replace(window.location.search,"")}]);if(t){GM.setClipboard(e,"text")}else{const t=new Blob([e],{type:"text/json"});const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.json`,t);i.add(s()+"."+this.danmakuOption.toLowerCase(),a);await i.emit(`${s()}.zip`)}}async exportAria2(a=false){if(a){const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.${this.danmakuOption==="ASS"?"ass":"xml"}`,a);await i.emit();const o=t.aria2RpcOption;const r=this.fragments.map((t,e)=>{let a="";if(this.fragments.length>1){a=" - "+(e+1)}const i=[];if(o.secretKey!==""){i.push(`token:${o.secretKey}`)}i.push([t.url]);i.push({referer:document.URL.replace(window.location.search,""),"user-agent":UserAgent,out:`${s()}${a}${this.extension(t)}`,split:this.fragmentSplitFactor,dir:o.baseDir+o.dir||undefined,"max-download-limit":o.maxDownloadLimit||undefined});const n=encodeURIComponent(`${s()}${a}`);return{params:i,id:n}});const{sendRpc:l}=await e.importAsync("aria2-rpc");await l(r)}else{const t=`\n# Generated by Bilibili Evolved Video Export\n# https://github.com/the1812/Bilibili-Evolved/\n${this.fragments.map((t,e)=>{let a="";if(this.fragments.length>1){a=" - "+(e+1)}return`\n${t.url}\n referer=${document.URL.replace(window.location.search,"")}\n user-agent=${UserAgent}\n out=${s()}${a}${this.extension(t)}\n split=${this.fragmentSplitFactor}\n`.trim()}).join("\n")}\n`.trim();const e=new Blob([t],{type:"text/plain"});const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.txt`,e);i.add(s()+"."+this.danmakuOption.toLowerCase(),a);await i.emit(`${s()}.zip`)}}extension(t){const e=t||this.fragments[0];const s=[".flv",".mp4",".m4s"].find(t=>e.url.includes(t));if(s){return s}else{console.warn("No extension detected.");return".flv"}}async downloadDanmaku(){if(this.danmakuOption!=="无"){const t=new i(c.cid);await t.fetchInfo();if(this.danmakuOption==="XML"){return t.rawXML}else{const{convertToAss:s}=await e.importAsync("download-danmaku");return s(t.rawXML)}}else{return null}}async download(){this.workingXhr=[];this.progressMap=new Map;this.updateProgress();const t=[];this.videoSpeed.startMeasure();for(const e of this.fragments){const s=await this.downloadFragment(e);t.push(s)}if(t.length<1){throw new Error("下载失败.")}const e=s();const a=new n;t.forEach((s,i)=>{let n;const o=this.fragments[i];if(t.length>1){n=`${e} - ${i+1}${this.extension(o)}`}else{n=`${e}${this.extension(o)}`}a.add(n,new Blob(Array.isArray(s)?s:[s],{type:this.extension(o)===".flv"?"video/x-flv":"video/mp4"}))});const i=await this.downloadDanmaku();a.add(`${s()}.${this.danmakuOption==="ASS"?"ass":"xml"}`,i);await a.emit(e+".zip");this.progress&&this.progress(0);this.videoSpeed.stopMeasure()}}class f{constructor(t){this.lastProgress=0;this.measureInterval=1e3;this.workingDownloader=t}startMeasure(){this.intervalTimer=setInterval(()=>{const t=this.workingDownloader.progressMap?[...this.workingDownloader.progressMap.values()].reduce((t,e)=>t+e,0):0;const e=t-this.lastProgress;if(this.speedUpdate!==undefined){this.speedUpdate(formatFileSize(e)+"/s")}this.lastProgress=t},this.measureInterval)}stopMeasure(){clearInterval(this.intervalTimer)}}async function m(){const t=await SpinQuery.select(()=>(unsafeWindow||window).aid);const e=await SpinQuery.select(()=>(unsafeWindow||window).cid);if(!(t&&e)){return false}c.aid=t;c.cid=e;if(document.URL.includes("bangumi")){c.entity=new r}else if(document.URL.includes("cheese")){const t=document.URL.match(/cheese\/play\/ep([\d]+)/);c.entity=new l(t[1])}else{c.entity=new o}try{d=await h.getAvailableFormats()}catch(t){return false}return true}async function w(){p=d[0];e.applyStyle("downloadVideoStyle");const t=dq("#download-video");t.addEventListener("click",()=>{const t=dq(".download-video");t.classList.toggle("opened");window.scroll(0,0);dq(".gui-settings-mask").click()});t.addEventListener("mouseover",()=>{document.body.insertAdjacentHTML("beforeend",e.import("downloadVideoHtml"));g()},{once:true})}async function g(){let o;const r=new Vue({el:".download-video",components:{VDropdown:()=>e.importAsync("v-dropdown.vue"),VCheckbox:()=>e.importAsync("v-checkbox.vue"),RpcProfiles:()=>e.importAsync("aria2-rpc-profiles.vue")},data:{downloadSingle:true,coverUrl:EmptyImageUrl,aid:c.aid,cid:c.cid,dashModel:{value:t.downloadVideoFormat,items:["flv","dash"]},qualityModel:{value:p.displayName,items:d.map(t=>t.displayName)},danmakuModel:{value:t.downloadVideoDefaultDanmaku,items:["无","XML","ASS"]},codecModel:{value:t.downloadVideoDashCodec,items:["AVC/H.264","HEVC/H.265"]},progressPercent:0,size:"获取大小中",blobUrl:"",episodeList:[],downloading:false,speed:"",batch:false,rpcSettings:t.aria2RpcOption,showRpcSettings:false,busy:false,saveRpcSettingsText:"保存配置",enableDash:t.enableDashDownload,lastDirectDownloadLink:""},computed:{displaySize(){if(typeof this.size==="string"){return this.size}return formatFileSize(this.size)},sizeWarning(){if(typeof this.size==="string"){return false}return this.size>1073741824},selectedEpisodeCount(){return this.episodeList.filter(t=>t.checked).length},dash(){return this.dashModel.value==="dash"}},methods:{close(){this.$el.classList.remove("opened")},danmakuOptionChange(){t.downloadVideoDefaultDanmaku=this.danmakuModel.value},async codecChange(){t.downloadVideoDashCodec=this.codecModel.value;await this.formatChange()},async dashChange(){console.log("dash change");t.downloadVideoFormat=this.dashModel.value;const e=this.dashModel.value;let s=[];if(e==="flv"){s=await h.getAvailableFormats()}else{s=await h.getAvailableDashFormats()}d=s;[p]=e;this.qualityModel.items=s.map(t=>t.displayName);[this.qualityModel.value]=this.qualityModel.items;await this.formatChange()},async formatChange(){console.log("format change");const t=this.getFormat();try{this.size="获取大小中";const e=await t.downloadInfo(this.dash);this.size=e.totalSize}catch(t){this.size="获取大小失败";throw t}},getFormat(){const t=d.find(t=>t.displayName===this.qualityModel.value);if(!t){console.error(`No format found. model value = ${this.qualityModel.value}`);return null}return t},async exportData(t){if(this.busy===true){return}try{this.busy=true;if(!this.downloadSingle){await this.exportBatchData(t);return}const a=this.getFormat();const i=await a.downloadInfo(this.dash);switch(t){case"copyLink":await i.copyUrl();Toast.success("已复制链接到剪贴板.","下载视频",3e3);break;case"showLink":await i.showUrl();break;case"aria2":await i.exportAria2(false);break;case"aria2RPC":await i.exportAria2(true);break;case"copyVLD":await i.exportData(true);Toast.success("已复制VLD数据到剪贴板.","下载视频",3e3);break;case"exportVLD":await i.exportData(false);break;case"ffmpegFragments":if(i.fragments.length<2){Toast.info("当前视频没有分段.","分段列表",3e3)}else{const{getFragmentsList:t}=await e.importAsync("ffmpeg-support");const a=new n;a.add("ffmpeg-files.txt",t(i.fragments.length,s(),i.extension(i.fragments[0])));await a.emit()}break;default:break}}catch(t){logError(t)}finally{this.busy=false}},async exportBatchData(t){const a=this.episodeList;if(a.every(t=>t.checked===false)){Toast.info("请至少选择1集或以上的数量!","批量导出",3e3);return}const o=t=>{const e=a.find(e=>e.cid===t.cid);if(e===undefined){return false}return e.checked};const r=this.getFormat();if(this.danmakuModel.value!=="无"){const t=Toast.info("下载弹幕中...","批量导出");const s=new n;try{if(this.danmakuModel.value==="XML"){for(const t of a.filter(o)){const e=new i(t.cid);await e.fetchInfo();s.add(t.title+".xml",e.rawXML)}}else{const{convertToAss:t}=await e.importAsync("download-danmaku");for(const e of a.filter(o)){const a=new i(e.cid);await a.fetchInfo();s.add(e.title+".ass",await t(a.rawXML))}}await s.emit(this.cid+".danmakus.zip")}catch(t){logError(`弹幕下载失败`)}finally{t.dismiss()}}const l=Toast.info("获取链接中...","批量导出");const c=this.batchExtractor;c.itemFilter=o;let d;try{switch(t){case"aria2":d=await c.collectAria2(r,l,false);await n.single(s(false)+".txt",new Blob([d],{type:"text/plain"}),{ffmpeg:this.ffmpegOption});return;case"aria2RPC":await c.collectAria2(r,l,true);Toast.success(`成功发送了批量请求.`,"aria2 RPC",3e3);return;case"copyVLD":GM.setClipboard(await c.collectData(r,l),{mimetype:"text/plain"});Toast.success("已复制批量vld数据到剪贴板.","批量导出",3e3);return;case"exportVLD":d=await c.collectData(r,l);await n.single(s(false)+".json",new Blob([d],{type:"text/json"}),{ffmpeg:this.ffmpegOption});return;case"ffmpegFragments":{const t=await c.getRawItems(r);const a=new u(r,t[0].fragments);const{getBatchFragmentsList:i}=await e.importAsync("ffmpeg-support");const o=i(t,a.extension());if(!o){Toast.info("所有选择的分P都没有分段.","分段列表",3e3)}else{const t=new n;for(const[e,s]of o.entries()){t.add(e,s)}await t.emit(escapeFilename(`${s(false)}.zip`))}}break;case"ffmpegEpisodes":{const t=await c.getRawItems(r);const s=new u(r,t[0].fragments);const{getBatchEpisodesList:a}=await e.importAsync("ffmpeg-support");const i=a(t,s.extension());const o=new n;o.add("ffmpeg-files.txt",i);await o.emit()}break;default:return}}catch(t){logError(t)}finally{l.dismiss()}},async checkBatch(){const t=["/www.bilibili.com/bangumi","/www.bilibili.com/video/av"];if(!t.some(t=>document.URL.includes(t))){this.batch=false;this.episodeList=[];return}const{BatchExtractor:s}=await e.importAsync("batch-download");if(await s.test()!==true){this.batch=false;this.episodeList=[];return}const a=this.batchExtractor=new s;this.batch=true;this.episodeList=(await a.getItemList()).map((t,e)=>{return{aid:t.aid,cid:t.cid,title:t.title,index:e,checked:true}})},cancelDownload(){if(o){o.cancelDownload()}},async startDownload(){const t=this.getFormat();try{this.downloading=true;const e=await t.downloadInfo(this.dash);e.videoSpeed.speedUpdate=(t=>this.speed=t);e.progress=(t=>{this.progressPercent=Math.trunc(t*100)});o=e;await e.download();this.lastDirectDownloadLink=n.lastPackageUrl}catch(t){if(t!=="canceled"){logError(t)}this.progressPercent=0}finally{this.downloading=false;this.speed=""}},selectAllEpisodes(){this.episodeList.forEach(t=>t.checked=true)},unselectAllEpisodes(){this.episodeList.forEach(t=>t.checked=false)},inverseAllEpisodes(){this.episodeList.forEach(t=>t.checked=!t.checked)},toggleRpcSettings(){this.showRpcSettings=!this.showRpcSettings},saveRpcSettings(){if(this.rpcSettings.host===""){this.rpcSettings.host="127.0.0.1"}if(this.rpcSettings.port===""){this.rpcSettings.port="6800"}t.aria2RpcOption=this.rpcSettings;const e=t.aria2RpcOptionProfiles.find(e=>e.name===t.aria2RpcOptionSelectedProfile);if(e){Object.assign(e,this.rpcSettings);t.aria2RpcOptionProfiles=t.aria2RpcOptionProfiles}this.saveRpcSettingsText="已保存";setTimeout(()=>this.saveRpcSettingsText="保存配置",2e3)},updateProfile(e){t.aria2RpcOption=this.rpcSettings=_.omit(e,"name")}},async mounted(){}});Observer.videoChange(async()=>{r.close();r.batch=false;r.downloadSingle=true;const t=dq("#download-video");const e=await m();t.style.display=e?"flex":"none";if(!e){return}r.aid=c.aid;r.cid=c.cid;try{const t=new a(c.aid);await t.fetchInfo();r.coverUrl=t.coverUrl.replace("http:","https:")}catch(t){r.coverUrl=EmptyImageUrl}r.dashChange();await r.checkBatch()})}return{widget:{content:`\n`,condition:m,success:w}}}})();
+onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.js"] = (()=>{return(t,e)=>{const{getFriendlyTitle:s}=e.import("title");const{VideoInfo:a,DanmakuInfo:i}=e.import("video-info");const{DownloadVideoPackage:n}=e.import("download-video-package");class o{async getDashUrl(t){if(t){return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&fnver=0&fnval=16`}else{return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&fnver=0&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&otype=json`}}}class r extends o{async getDashUrl(t){if(t){return`https://api.bilibili.com/pgc/player/web/playurl?avid=56995872&cid=99547543&qn=${t}&otype=json&fourk=1&fnval=16`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=56995872&cid=99547543&otype=json&fourk=1&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=&otype=json`}}}class l extends o{constructor(t){super();this.ep=t}async getDashUrl(t){if(t){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&ep_id=${this.ep}`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&ep_id=${this.ep}`}}}const c={entity:new o,aid:"",cid:""};let d=[];let p=null;class h{constructor(t,e,s){this.quality=t;this.internalName=e;this.displayName=s}async downloadInfo(t=false){const e=new u(this);await e.fetchVideoInfo(t);return e}static parseFormats(t){const e=t.accept_quality;const s=t.accept_format.split(",");const a=t.accept_description;const i=e.map((t,e)=>{return new h(t,s[e],a[e])});return i}static async getAvailableDashFormats(){const t=await c.entity.getDashUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}return h.parseFormats(e.data||e.result||e)}static async getAvailableFormats(){const t=await c.entity.getUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}const s=e.data||e.result||e;return h.parseFormats(s)}}class u{constructor(t,e){this.fragmentSplitFactor=6*2;this.workingXhr=null;this.progressMap=new Map;this.format=t;this.fragments=e||[];this.videoSpeed=new f(this)}get danmakuOption(){return t.downloadVideoDefaultDanmaku}get isDash(){return this.fragments.some(t=>t.url.includes(".m4s"))}get totalSize(){return this.fragments.map(t=>t.size).reduce((t,e)=>t+e)}async fetchVideoInfo(s=false){if(!s){const t=await c.entity.getUrl(this.format.quality);const e=await Ajax.getTextWithCredentials(t);const s=JSON.parse(e.replace(/http:/g,"https:"));const a=s.data||s.result||s;if(a.quality!==this.format.quality){throw new Error("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const i=a.durl;this.fragments=i.map(t=>{return{length:t.length,size:t.size,url:t.url,backupUrls:t.backup_url}})}else{const{dashToFragment:s,getDashInfo:a}=await e.importAsync("video-dash");const i=await a(await c.entity.getDashUrl(this.format.quality),this.format.quality);console.log(i.videoDashes);const n=(()=>{const e=e=>e.videoCodec===t.downloadVideoDashCodec;if(i.videoDashes.some(e)){return i.videoDashes.filter(e).sort(ascendingSort(t=>t.bandWidth))[0]}else{return i.videoDashes.sort(ascendingSort(t=>t.bandWidth))[0]}})();const o=i.audioDashes.sort(descendingSort(t=>t.bandWidth))[0];this.fragments=[s(n),s(o)]}return this.fragments}updateProgress(){const t=this.progressMap?[...this.progressMap.values()].reduce((t,e)=>t+e,0)/this.totalSize:0;if(t>1||t<0){console.error(`[下载视频] 进度异常: ${t}`,this.progressMap.values())}this.progress&&this.progress(t)}cancelDownload(){this.videoSpeed.stopMeasure();if(this.workingXhr!==null){this.workingXhr.forEach(t=>t.abort())}else{logError("Cancel Download Failed: forEach in this.workingXhr not found.")}}downloadFragment(t){const e=[];const s=this.isDash?4*1024*1024:16*1024*1024;let a;if(t.size<=s*6){a=t.size/this.fragmentSplitFactor}else{a=s}let i=0;const n=t=>[...this.progressMap.keys()].indexOf(t)+1;while(i{const a=new XMLHttpRequest;a.open("GET",t.url);a.responseType="arraybuffer";a.withCredentials=false;a.addEventListener("progress",t=>{console.log(`[下载视频] 视频片段${n(a)}下载进度: ${t.loaded}/${r} bytes loaded, ${o}`);this.progressMap.set(a,t.loaded);this.updateProgress()});a.addEventListener("load",()=>{if((""+a.status)[0]==="2"){console.log(`[下载视频] 视频片段${n(a)}下载完成`);e(a.response)}else{s(`视频片段${n(a)}请求失败, response = ${a.status}`)}});a.addEventListener("abort",()=>s("canceled"));a.addEventListener("error",()=>{console.error(`[下载视频] 视频片段${n(a)}下载失败: ${o}`);this.progressMap.set(a,0);this.updateProgress();a.open("GET",t.url);a.setRequestHeader("Range",o);a.send()});a.setRequestHeader("Range",o);this.progressMap.set(a,0);a.send();this.workingXhr.push(a)}));i=Math.round(i+a)+1}return Promise.all(e)}async copyUrl(){const t=this.fragments.map(t=>t.url).reduce((t,e)=>t+"\r\n"+e);GM.setClipboard(t,"text")}async showUrl(){const t=this.fragments.map(t=>`\n${t.url}\n`).reduce((t,e)=>t+"\r\n"+e);Toast.success(t+`复制全部`,"显示链接");const e=await SpinQuery.select("#copy-link");e.addEventListener("click",async()=>{await this.copyUrl()})}async exportData(t=false){const e=JSON.stringify([{fragments:this.fragments,title:s(),totalSize:this.fragments.map(t=>t.size).reduce((t,e)=>t+e),referer:document.URL.replace(window.location.search,"")}]);if(t){GM.setClipboard(e,"text")}else{const t=new Blob([e],{type:"text/json"});const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.json`,t);i.add(s()+"."+this.danmakuOption.toLowerCase(),a);await i.emit(`${s()}.zip`)}}async exportAria2(a=false){if(a){const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.${this.danmakuOption==="ASS"?"ass":"xml"}`,a);await i.emit();const o=t.aria2RpcOption;const r=this.fragments.map((t,e)=>{let a="";if(this.fragments.length>1&&!this.isDash){a=" - "+(e+1)}const i=[];if(o.secretKey!==""){i.push(`token:${o.secretKey}`)}i.push([t.url]);i.push({referer:document.URL.replace(window.location.search,""),"user-agent":UserAgent,out:`${s()}${a}${this.extension(t)}`,split:this.fragmentSplitFactor,dir:o.baseDir+o.dir||undefined,"max-download-limit":o.maxDownloadLimit||undefined});const n=encodeURIComponent(`${s()}${a}`);return{params:i,id:n}});const{sendRpc:l}=await e.importAsync("aria2-rpc");await l(r)}else{const t=`\n# Generated by Bilibili Evolved Video Export\n# https://github.com/the1812/Bilibili-Evolved/\n${this.fragments.map((t,e)=>{let a="";if(this.fragments.length>1&&!this.isDash){a=" - "+(e+1)}return`\n${t.url}\n referer=${document.URL.replace(window.location.search,"")}\n user-agent=${UserAgent}\n out=${s()}${a}${this.extension(t)}\n split=${this.fragmentSplitFactor}\n`.trim()}).join("\n")}\n`.trim();const e=new Blob([t],{type:"text/plain"});const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.txt`,e);i.add(s()+"."+this.danmakuOption.toLowerCase(),a);await i.emit(`${s()}.zip`)}}extension(t){const e=t||this.fragments[0];const s=[".flv",".mp4"].find(t=>e.url.includes(t));if(s){return s}else if(e.url.includes(".m4s")){return this.fragments.indexOf(e)===0?".mp4":".m4a"}else{console.warn("No extension detected.");return".flv"}}async downloadDanmaku(){if(this.danmakuOption!=="无"){const t=new i(c.cid);await t.fetchInfo();if(this.danmakuOption==="XML"){return t.rawXML}else{const{convertToAss:s}=await e.importAsync("download-danmaku");return s(t.rawXML)}}else{return null}}async download(){this.workingXhr=[];this.progressMap=new Map;this.updateProgress();const t=[];this.videoSpeed.startMeasure();for(const e of this.fragments){const s=await this.downloadFragment(e);t.push(s)}if(t.length<1){throw new Error("下载失败.")}const e=s();const a=new n;t.forEach((s,i)=>{let n;const o=this.fragments[i];if(t.length>1&&!this.isDash){n=`${e} - ${i+1}${this.extension(o)}`}else{n=`${e}${this.extension(o)}`}a.add(n,new Blob(Array.isArray(s)?s:[s]))});const i=await this.downloadDanmaku();a.add(`${s()}.${this.danmakuOption==="ASS"?"ass":"xml"}`,i);await a.emit(e+".zip");this.progress&&this.progress(0);this.videoSpeed.stopMeasure()}}class f{constructor(t){this.lastProgress=0;this.measureInterval=1e3;this.workingDownloader=t}startMeasure(){this.intervalTimer=setInterval(()=>{const t=this.workingDownloader.progressMap?[...this.workingDownloader.progressMap.values()].reduce((t,e)=>t+e,0):0;const e=t-this.lastProgress;if(this.speedUpdate!==undefined){this.speedUpdate(formatFileSize(e)+"/s")}this.lastProgress=t},this.measureInterval)}stopMeasure(){clearInterval(this.intervalTimer)}}async function m(){const t=await SpinQuery.select(()=>(unsafeWindow||window).aid);const e=await SpinQuery.select(()=>(unsafeWindow||window).cid);if(!(t&&e)){return false}c.aid=t;c.cid=e;if(document.URL.includes("bangumi")){c.entity=new r}else if(document.URL.includes("cheese")){const t=document.URL.match(/cheese\/play\/ep([\d]+)/);c.entity=new l(t[1])}else{c.entity=new o}try{d=await h.getAvailableFormats()}catch(t){return false}return true}async function w(){p=d[0];e.applyStyle("downloadVideoStyle");const t=dq("#download-video");t.addEventListener("click",()=>{const t=dq(".download-video");t.classList.toggle("opened");window.scroll(0,0);dq(".gui-settings-mask").click()});t.addEventListener("mouseover",()=>{document.body.insertAdjacentHTML("beforeend",e.import("downloadVideoHtml"));g()},{once:true})}async function g(){let o;const r=new Vue({el:".download-video",components:{VDropdown:()=>e.importAsync("v-dropdown.vue"),VCheckbox:()=>e.importAsync("v-checkbox.vue"),RpcProfiles:()=>e.importAsync("aria2-rpc-profiles.vue")},data:{downloadSingle:true,coverUrl:EmptyImageUrl,aid:c.aid,cid:c.cid,dashModel:{value:t.downloadVideoFormat,items:["flv","dash"]},qualityModel:{value:p.displayName,items:d.map(t=>t.displayName)},danmakuModel:{value:t.downloadVideoDefaultDanmaku,items:["无","XML","ASS"]},codecModel:{value:t.downloadVideoDashCodec,items:["AVC/H.264","HEVC/H.265"]},progressPercent:0,size:"获取大小中",blobUrl:"",episodeList:[],downloading:false,speed:"",batch:false,rpcSettings:t.aria2RpcOption,showRpcSettings:false,busy:false,saveRpcSettingsText:"保存配置",enableDash:t.enableDashDownload,lastDirectDownloadLink:""},computed:{displaySize(){if(typeof this.size==="string"){return this.size}return formatFileSize(this.size)},sizeWarning(){if(typeof this.size==="string"){return false}return this.size>1073741824},selectedEpisodeCount(){return this.episodeList.filter(t=>t.checked).length},dash(){return this.dashModel.value==="dash"}},methods:{close(){this.$el.classList.remove("opened")},danmakuOptionChange(){t.downloadVideoDefaultDanmaku=this.danmakuModel.value},async codecChange(){t.downloadVideoDashCodec=this.codecModel.value;await this.formatChange()},async dashChange(){console.log("dash change");t.downloadVideoFormat=this.dashModel.value;const e=this.dashModel.value;let s=[];if(e==="flv"){s=await h.getAvailableFormats()}else{s=await h.getAvailableDashFormats()}d=s;[p]=e;this.qualityModel.items=s.map(t=>t.displayName);[this.qualityModel.value]=this.qualityModel.items;await this.formatChange()},async formatChange(){console.log("format change");const t=this.getFormat();try{this.size="获取大小中";const e=await t.downloadInfo(this.dash);this.size=e.totalSize}catch(t){this.size="获取大小失败";throw t}},getFormat(){const t=d.find(t=>t.displayName===this.qualityModel.value);if(!t){console.error(`No format found. model value = ${this.qualityModel.value}`);return null}return t},async exportData(t){if(this.busy===true){return}try{this.busy=true;if(!this.downloadSingle){await this.exportBatchData(t);return}const a=this.getFormat();const i=await a.downloadInfo(this.dash);switch(t){case"copyLink":await i.copyUrl();Toast.success("已复制链接到剪贴板.","下载视频",3e3);break;case"showLink":await i.showUrl();break;case"aria2":await i.exportAria2(false);break;case"aria2RPC":await i.exportAria2(true);break;case"copyVLD":await i.exportData(true);Toast.success("已复制VLD数据到剪贴板.","下载视频",3e3);break;case"exportVLD":await i.exportData(false);break;case"ffmpegFragments":if(i.fragments.length<2){Toast.info("当前视频没有分段.","分段列表",3e3)}else{const{getFragmentsList:t}=await e.importAsync("ffmpeg-support");const a=new n;a.add("ffmpeg-files.txt",t(i.fragments.length,s(),i.fragments.map(t=>i.extension(t))));await a.emit()}break;default:break}}catch(t){logError(t)}finally{this.busy=false}},async exportBatchData(t){const a=this.episodeList;if(a.every(t=>t.checked===false)){Toast.info("请至少选择1集或以上的数量!","批量导出",3e3);return}const o=t=>{const e=a.find(e=>e.cid===t.cid);if(e===undefined){return false}return e.checked};const r=this.getFormat();if(this.danmakuModel.value!=="无"){const t=Toast.info("下载弹幕中...","批量导出");const s=new n;try{if(this.danmakuModel.value==="XML"){for(const t of a.filter(o)){const e=new i(t.cid);await e.fetchInfo();s.add(t.title+".xml",e.rawXML)}}else{const{convertToAss:t}=await e.importAsync("download-danmaku");for(const e of a.filter(o)){const a=new i(e.cid);await a.fetchInfo();s.add(e.title+".ass",await t(a.rawXML))}}await s.emit(this.cid+".danmakus.zip")}catch(t){logError(`弹幕下载失败`)}finally{t.dismiss()}}const l=Toast.info("获取链接中...","批量导出");const c=this.batchExtractor;c.itemFilter=o;let d;try{switch(t){case"aria2":d=await c.collectAria2(r,l,false);await n.single(s(false)+".txt",new Blob([d],{type:"text/plain"}),{ffmpeg:this.ffmpegOption});return;case"aria2RPC":await c.collectAria2(r,l,true);Toast.success(`成功发送了批量请求.`,"aria2 RPC",3e3);return;case"copyVLD":GM.setClipboard(await c.collectData(r,l),{mimetype:"text/plain"});Toast.success("已复制批量vld数据到剪贴板.","批量导出",3e3);return;case"exportVLD":d=await c.collectData(r,l);await n.single(s(false)+".json",new Blob([d],{type:"text/json"}),{ffmpeg:this.ffmpegOption});return;case"ffmpegFragments":{const t=await c.getRawItems(r);const a=new u(r,t[0].fragments);const{getBatchFragmentsList:i}=await e.importAsync("ffmpeg-support");const o=this.dash?[".mp4","m4a"]:[a.extension()];const l=i(t,o);if(!l){Toast.info("所有选择的分P都没有分段.","分段列表",3e3)}else{const t=new n;for(const[e,s]of l.entries()){t.add(e,s)}await t.emit(escapeFilename(`${s(false)}.zip`))}}break;case"ffmpegEpisodes":{const t=await c.getRawItems(r);const s=new u(r,t[0].fragments);const{getBatchEpisodesList:a}=await e.importAsync("ffmpeg-support");const i=this.dash?[".mp4","m4a"]:[s.extension()];const o=a(t,i);const l=new n;l.add("ffmpeg-files.txt",o);await l.emit()}break;default:return}}catch(t){logError(t)}finally{l.dismiss()}},async checkBatch(){const t=["/www.bilibili.com/bangumi","/www.bilibili.com/video/av"];if(!t.some(t=>document.URL.includes(t))){this.batch=false;this.episodeList=[];return}const{BatchExtractor:s}=await e.importAsync("batch-download");if(await s.test()!==true){this.batch=false;this.episodeList=[];return}const a=this.batchExtractor=new s;this.batch=true;this.episodeList=(await a.getItemList()).map((t,e)=>{return{aid:t.aid,cid:t.cid,title:t.title,index:e,checked:true}})},cancelDownload(){if(o){o.cancelDownload()}},async startDownload(){const t=this.getFormat();try{this.downloading=true;const e=await t.downloadInfo(this.dash);e.videoSpeed.speedUpdate=(t=>this.speed=t);e.progress=(t=>{this.progressPercent=Math.trunc(t*100)});o=e;await e.download();this.lastDirectDownloadLink=n.lastPackageUrl}catch(t){if(t!=="canceled"){logError(t)}this.progressPercent=0}finally{this.downloading=false;this.speed=""}},selectAllEpisodes(){this.episodeList.forEach(t=>t.checked=true)},unselectAllEpisodes(){this.episodeList.forEach(t=>t.checked=false)},inverseAllEpisodes(){this.episodeList.forEach(t=>t.checked=!t.checked)},toggleRpcSettings(){this.showRpcSettings=!this.showRpcSettings},saveRpcSettings(){if(this.rpcSettings.host===""){this.rpcSettings.host="127.0.0.1"}if(this.rpcSettings.port===""){this.rpcSettings.port="6800"}t.aria2RpcOption=this.rpcSettings;const e=t.aria2RpcOptionProfiles.find(e=>e.name===t.aria2RpcOptionSelectedProfile);if(e){Object.assign(e,this.rpcSettings);t.aria2RpcOptionProfiles=t.aria2RpcOptionProfiles}this.saveRpcSettingsText="已保存";setTimeout(()=>this.saveRpcSettingsText="保存配置",2e3)},updateProfile(e){t.aria2RpcOption=this.rpcSettings=_.omit(e,"name")}},async mounted(){}});Observer.videoChange(async()=>{r.close();r.batch=false;r.downloadSingle=true;const t=dq("#download-video");const e=await m();t.style.display=e?"flex":"none";if(!e){return}r.aid=c.aid;r.cid=c.cid;try{const t=new a(c.aid);await t.fetchInfo();r.coverUrl=t.coverUrl.replace("http:","https:")}catch(t){r.coverUrl=EmptyImageUrl}r.dashChange();await r.checkBatch()})}return{widget:{content:`\n`,condition:m,success:w}}}})();
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/dpi-img.vue.min.js"] = (()=>{return(t,s)=>{const e=`
`;return{export:Object.assign({template:e},{props:["size","src","blur","root","rootMargin","threshold"],data(){return{srcset:null,actualSrc:null}},methods:{calcSrc(){if(!this.src||!this.size){return null}const t=this.src.substring(this.src.lastIndexOf(".")+1);this.srcset=getDpiSourceSet(this.src,this.size,t);this.actualSrc=this.src}},mounted(){const t={root:this.root,rootMargin:this.rootMargin||"200px",threshold:this.threshold};const s=new IntersectionObserver(t=>{t.forEach(t=>{if(t.isIntersecting){this.calcSrc();s.disconnect()}})},t);s.observe(this.$el)},computed:{width(){if(typeof this.size==="object"&&"width"in this.size){return this.size.width}return null},height(){if(typeof this.size==="object"&&"height"in this.size){return this.size.height}return null}}})}}})();
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/expand-danmaku.min.js"] = (()=>{return(e,a)=>{if(typeof isEmbeddedPlayer!=="undefined"&&isEmbeddedPlayer()){return}Observer.videoChange(async()=>{const e=await SpinQuery.select(".bui-collapse-wrap");if(e&&e.classList.contains("bui-collapse-wrap-folded")){const e=await SpinQuery.select(".bui-collapse-header");e.click()}})}})();
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/expand-description.min.css"] = `.play-up-info .play-up-self,.video-desc .info{height:auto!important}.play-up-info .play-up-self-btn,.video-desc .btn{display:none!important}`;
@@ -1098,7 +1098,7 @@ onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/mi
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/feeds-apis.min.js"] = (()=>{return(e,t)=>{const a={repost:{id:1,name:"转发"},textWithImages:{id:2,name:"图文"},text:{id:4,name:"文字"},video:{id:8,name:"视频"},miniVideo:{id:16,name:"小视频"},column:{id:64,name:"专栏"},audio:{id:256,name:"音频"},bangumi:{id:512,name:"番剧"},share:{id:2048,name:"分享"}};class i extends EventTarget{constructor(){super(...arguments);this.cards=[]}addEventListener(e,t,a){super.addEventListener(e,t,a)}removeEventListener(e,t,a){super.removeEventListener(e,t,a)}async addCard(e){if(e instanceof HTMLElement&&e.classList.contains("card")){if(e.querySelector(".skeleton")!==null){const t=Observer.childList(e,()=>{if(e.querySelector(".skeleton")===null){t.stop();this.addCard(e)}})}else{const t=await this.parseCard(e);this.cards.push(t);const a=new CustomEvent("addCard",{detail:t});this.dispatchEvent(a)}}}async removeCard(e){if(e instanceof HTMLElement&&e.classList.contains("card")){const t=(await this.parseCard(e)).id;const a=this.cards.findIndex(e=>e.id===t);const i=this.cards[a];this.cards.splice(a,1);const n=new CustomEvent("removeCard",{detail:i});this.dispatchEvent(n)}}async parseCard(e){const t=async t=>{const a=await SpinQuery.condition(()=>e.querySelector(t),e=>e!==null);if(a===null){console.warn(e,t);return""}return a.innerText};const i=async e=>{const a=parseInt(await t(e));if(isNaN(a)){return 0}return a};const n=(()=>{if(e.querySelector(".repost")){return a.repost}if(e.querySelector(".imagesbox")){return a.textWithImages}if(e.querySelector(".video-container")){return a.video}if(e.querySelector(".bangumi-container")){return a.bangumi}if(e.querySelector(".article-container")){return a.column}if(e.querySelector(".music-container")){return a.audio}if(e.querySelector(".h5share-container")){return a.share}if(e.querySelector(".vc-ctnr")){return a.miniVideo}return a.text})();const r={id:e.getAttribute("data-did"),username:await t(".main-content .user-name"),text:await t(".card-content .text.description,.video-container .title,.bangumi-container .title"),reposts:await i(".button-bar .single-button:nth-child(1) .text-offset"),comments:await i(".button-bar .single-button:nth-child(2) .text-offset"),likes:await i(".button-bar .single-button:nth-child(3) .text-offset"),element:e,type:n};e.setAttribute("data-type",n.id.toString());return r}async startWatching(){const e=await SpinQuery.select(".card-list .content");if(!e){return false}const t=[...e.querySelectorAll(".content>.card")];t.forEach(e=>this.addCard(e));Observer.childList(e,e=>{e.forEach(e=>{e.addedNodes.forEach(e=>this.addCard(e));e.removedNodes.forEach(e=>this.removeCard(e))})});return true}}const n=new i;const r=async(e="video")=>{const a=await Ajax.getJsonWithCredentials(`https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_new?uid=${getUID()}&type_list=${e==="video"?8:512}`);if(a.code!==0){throw new Error(a.message)}if(e==="video"){const{getWatchlaterList:e}=await t.importAsync("watchlater-api");const i=await e();return a.data.cards.map(e=>{const t=JSON.parse(e.card);const a=_.get(e,"display.topic_info.topic_details",[]).map(e=>{return{id:e.topic_id,name:e.topic_name}});return{id:e.desc.dynamic_id_str,aid:t.aid,title:t.title,upID:e.desc.user_profile.info.uid,upName:e.desc.user_profile.info.uname,upFaceUrl:e.desc.user_profile.info.face,coverUrl:t.pic,description:t.desc,timestamp:e.timestamp,time:new Date(e.timestamp*1e3),topics:a,dynamic:t.dynamic,like:formatCount(e.desc.like),duration:t.duration,durationText:formatDuration(t.duration,0),playCount:formatCount(t.stat.view),danmakuCount:formatCount(t.stat.danmaku),watchlater:i.includes(t.aid)}})}else if(e==="bangumi"){return a.data.cards.map(e=>{const t=JSON.parse(e.card);return{id:e.desc.dynamic_id_str,aid:t.aid,epID:t.episode_id,title:t.new_desc,upName:t.apiSeasonInfo.title,upFaceUrl:t.apiSeasonInfo.cover,coverUrl:t.cover,description:"",timestamp:e.timestamp,time:new Date(e.timestamp*1e3),like:formatCount(e.desc.like),durationText:"",playCount:formatCount(t.play_count),danmakuCount:formatCount(t.bullet_count),watchlater:false}})}else{return[]}};return{export:{feedsCardsManager:n,feedsCardTypes:a,getVideoFeeds:r}}}})();
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/feeds-filter-card.vue.min.js"] = (()=>{return(e,t)=>{const i=``;t.applyStyleFromText(`body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-audio .feed-card .card[data-type="256"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-bangumi .feed-card .card[data-type="512"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-column .feed-card .card[data-type="64"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-miniVideo .feed-card .card[data-type="16"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-repost .feed-card .card[data-type="1"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-share .feed-card .card[data-type="2048"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-text .feed-card .card[data-type="4"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-textWithImages .feed-card .card[data-type="2"],body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-block-video .feed-card .card[data-type="8"]{display:none!important}body.enable-feeds-filter:not(.disable-feeds-filter) .left-panel>*,body.enable-feeds-filter:not(.disable-feeds-filter) .right-panel>*{margin:0 0 8px!important}body.enable-feeds-filter:not(.disable-feeds-filter) .feed-card .card.pattern-block,body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-side-block-following-tags .left-panel .tag-panel,body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-side-block-live .right-panel .live-panel,body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-side-block-notice .right-panel .notice-panel,body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-side-block-profile .left-panel .user-wrapper,body.enable-feeds-filter:not(.disable-feeds-filter).feeds-filter-side-block-trending-tags .right-panel .tag-panel{display:none!important}.feeds-filter{background-color:#fff;width:100%;padding:12px 16px;float:left;border-radius:4px;box-sizing:border-box;display:none;flex-direction:column}body.enable-feeds-filter:not(.disable-feeds-filter) .feeds-filter{display:flex}.feeds-filter,.feeds-filter *{transition:.2s ease-out}body.dark .feeds-filter{color:#eee;background-color:#444}.feeds-filter h1{font-weight:400;font-size:14px;margin:0 0 14px}.feeds-filter h2{font-weight:700;font-size:13px;margin:0 0 8px}.feeds-filter .feeds-filter-swtich:not(:last-child){margin-bottom:4px}.feeds-filter .feeds-filter-swtich label{cursor:pointer;margin:0;padding:4px 8px;border-radius:4px;background-color:#0001;display:flex;align-items:center;justify-content:space-between;border:1px solid transparent}.feeds-filter .feeds-filter-swtich label .name{font-size:12px}.feeds-filter .feeds-filter-swtich label .disabled{color:var(--theme-color)!important}.feeds-filter .feeds-filter-swtich label:hover{background-color:#0002}.feeds-filter .feeds-filter-swtich label input{display:none}.feeds-filter .feeds-filter-swtich label .be-icon{font-size:16px}.feeds-filter .feeds-filter-swtich label .be-icon.disabled{display:none}.feeds-filter .feeds-filter-swtich label.disabled{border-color:var(--theme-color)}.feeds-filter .feeds-filter-swtich label.disabled .be-icon{display:none}.feeds-filter .feeds-filter-swtich label.disabled .be-icon.disabled{display:block}.feeds-filter .filter-type-switch{flex:0 0 49%}.feeds-filter .filter-side-card-switch{flex:0 0 100%}.feeds-filter .filter-types{display:flex;flex-wrap:wrap;justify-content:space-between;margin-bottom:18px}.feeds-filter .filter-patterns:not(:empty){margin-bottom:8px}.feeds-filter .filter-patterns .pattern{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;border-radius:4px;background-color:#0001;font-size:12px}.feeds-filter .filter-patterns .pattern:not(:last-child){margin-bottom:4px}.feeds-filter .filter-patterns .pattern .be-icon{font-size:18px;cursor:pointer}.feeds-filter .add-pattern{display:flex;align-items:center;margin-bottom:18px}.feeds-filter .add-pattern input{color:inherit;background-color:transparent;font-size:12px;border:1px solid #8884;border-radius:4px;outline:0!important;padding:4px;flex:1 0 0;width:0}.feeds-filter .add-pattern input:focus{border-color:var(--theme-color)}.feeds-filter .add-pattern .be-icon{font-size:18px;cursor:pointer;margin-left:8px}`,"feeds-filter-card-style");const d={0:{className:"profile",displayName:"个人资料"},1:{className:"following-tags",displayName:"关注的话题"},2:{className:"notice",displayName:"公告栏"},3:{className:"live",displayName:"正在直播"},4:{className:"trending-tags",displayName:"热门话题"}};const s="feeds-filter-side-block-";return{export:Object.assign({template:i},{components:{FilterTypeSwitch:()=>t.importAsync("filter-type-switch.vue"),Icon:()=>t.importAsync("icon.vue")},methods:{updateCard(t){const i=(e,t)=>{if(e.startsWith("/")&&e.endsWith("/")){return new RegExp(e.slice(1,e.length-1)).test(t)}return t.includes(e)};const d=(()=>{return e.feedsFilterPatterns.some(e=>{const d=e.match(/(.+) up:([^ ]+)/);if(d){return i(d[1],t.text)&&i(d[2],t.username)}return i(e,t.text)})})();if(d){t.element.classList.add("pattern-block")}else{t.element.classList.remove("pattern-block")}},deletePattern(t){const i=e.feedsFilterPatterns.indexOf(t);if(i!==-1){this.patterns.splice(i,1)}},addPattern(e){if(e&&!this.patterns.includes(e)){this.patterns.push(e)}this.newPattern=""},updateBlockSide(){Object.entries(d).forEach(([e,t])=>{const i=s+t.className;document.body.classList[this.blockSideCards.includes(e)?"add":"remove"](i)})},toggleBlockSide(t){const i=this.blockSideCards.indexOf(t);const a=d[t];if(i!==-1){this.blockSideCards.splice(i,1);document.body.classList.remove(s+a.className)}else{this.blockSideCards.push(t);document.body.classList.add(s+a.className)}e.feedsFilterSideCards=this.blockSideCards},sideDisabled(e){return this.blockSideCards.includes(e)}},watch:{patterns(){e.feedsFilterPatterns=this.patterns;if(this.feedsCardsManager!==null){this.feedsCardsManager.cards.forEach(e=>this.updateCard(e))}}},data(){return{allTypes:[],patterns:[...e.feedsFilterPatterns],newPattern:"",feedsCardsManager:null,allSideCards:d,blockSideCards:[...e.feedsFilterSideCards]}},async mounted(){this.updateBlockSide();const e=await SpinQuery.select(".feed-card .tab-bar");if(!e){console.error("tabBar not found");return}const i=e.querySelector(".tab:nth-child(2) .tab-text");Observer.attributes(i,()=>{document.body.classList[i.classList.contains("selected")?"add":"remove"]("enable-feeds-filter")});const{feedsCardsManager:d,feedsCardTypes:s}=await t.importAsync("feeds-apis");const a=await d.startWatching();if(!a){console.error("feedsCardsManager.startWatching() failed");return}this.allTypes=Object.entries(s);d.cards.forEach(e=>this.updateCard(e));d.addEventListener("addCard",e=>{const t=e.detail;this.updateCard(t)});this.feedsCardsManager=d}})}}})();
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/feeds-filter.min.js"] = (()=>{return(e,t)=>{(async()=>{if(document.URL.replace(location.search,"")!=="https://t.bilibili.com/"){return}const e=await SpinQuery.select(".home-container .left-panel");if(e===null){return}e.insertAdjacentHTML("beforeend",html``);new Vue({el:"feeds-filter-card",components:{FeedsFilterCard:()=>t.importAsync("feeds-filter-card.vue")}})})();return{reload:()=>document.body.classList.remove("disable-feeds-filter"),unload:()=>document.body.classList.add("disable-feeds-filter")}}})();
-onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/ffmpeg-support.min.js"] = (()=>{return(e,t)=>{const n=(e,t,n)=>{if(e<2){return null}const r=[];for(let s=1;s<=e;s++){r.push(escapeFilename(`file '${t} - ${s}${n}'`))}return r.join("\n")};const r=(e,t)=>{const n=e=>e.fragments.length>1;const r=e.filter(n);if(r.length===0){return null}const s=new Map;r.forEach(e=>{s.set(escapeFilename(`ffmpeg-files-${e.title}.txt`),e.fragments.map((n,r)=>{return escapeFilename(`file '${e.title} - ${r+1}${t}'`)}).join("\n"))});return s};const s=(e,t)=>{const n=[];e.forEach(e=>{e.fragments.forEach((r,s)=>{let i="";if(e.fragments.length>1){i=` - ${s+1}`}n.push(escapeFilename(`file '${e.title}${i}${t}'`))})});return n.join("\n")};return{export:{getFragmentsList:n,getBatchFragmentsList:r,getBatchEpisodesList:s}}}})();
+onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/ffmpeg-support.min.js"] = (()=>{return(e,t)=>{const n=(e,t,n)=>{if(e<2){return null}const s=[];for(let r=1;r<=e;r++){let e=` - ${r}`;if(n.includes(".m4a")){e=""}s.push(escapeFilename(`file '${t}${e}${n[r-1]}'`))}return s.join("\n")};const s=(e,t)=>{const n=e=>e.fragments.length>1;const s=e.filter(n);if(s.length===0){return null}const r=new Map;s.forEach(e=>{r.set(escapeFilename(`ffmpeg-files-${e.title}.txt`),e.fragments.map((n,s)=>{return escapeFilename(`file '${e.title} - ${s+1}${t[s]}'`)}).join("\n"))});return r};const r=(e,t)=>{const n=[];e.forEach(e=>{e.fragments.forEach((s,r)=>{let i="";if(e.fragments.length>1&&!t.includes(".m4a")){i=` - ${r+1}`}n.push(escapeFilename(`file '${e.title}${i}${t[r]}'`))})});return n.join("\n")};return{export:{getFragmentsList:n,getBatchFragmentsList:s,getBatchEpisodesList:r}}}})();
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/fill-with-comments.min.js"] = (()=>{return(t,n)=>{const o="fill-with-comments-style";const i=t=>{if(t){n.applyStyleFromText(`\n .v-wrap { position: relative !important; }\n .v-wrap .l-con { width: 100% !important; }\n .v-wrap .r-con {\n position: absolute !important;\n top: 0 !important;\n right: 0 !important;\n }\n .video-desc .info { width: auto !important; }\n`,o)}else{dqa("#"+o).forEach(t=>t.remove())}};return{export:{fillWithComments:i}}}})();
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/filter-type-switch.vue.min.js"] = (()=>{return(e,s)=>{const i=``;return{export:Object.assign({template:i},{components:{Icon:()=>s.importAsync("icon.vue")},props:["name","type"],methods:{setFilter(s,i=true){document.body.classList[s?"add":"remove"](`feeds-filter-block-${this.name}`);if(!i){return}if(s){e.feedsFilterTypes.push(this.type.id)}else{const s=e.feedsFilterTypes.indexOf(this.type.id);if(s!==-1){e.feedsFilterTypes.splice(s,1)}}e.feedsFilterTypes=e.feedsFilterTypes}},data(){const s=e.feedsFilterTypes.includes(this.type.id);this.setFilter(s,false);return{disabled:s}},watch:{disabled(e){this.setFilter(e)}}})}}})();
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/fix-fullscreen.min.js"] = (()=>{return(e,n)=>{unsafeWindow.Element.ALLOW_KEYBOARD_INPUT={};const t=unsafeWindow.Element.prototype.requestFullscreen;unsafeWindow.Element.prototype.requestFullscreen=function(){t.call(this)}}})();
diff --git a/min/bundle.json b/min/bundle.json
index 184388d8f..1c8fd2070 100644
--- a/min/bundle.json
+++ b/min/bundle.json
@@ -47,7 +47,7 @@
"download-video-package.min.js": "B10FF11DE7DFBACEC38F195B8E836511E527215B5E177CB1D223D14F30EB1435",
"download-video.min.css": "95FF9DA3C1FFF1C1134D70AE3BB609049B7D5D3FBB71CAAAE84C8742C51AD841",
"download-video.min.html": "2727789E8423E8DBC8801FF6AC0D8181AC684A643A83CD446A5D69318DDBF9F6",
- "download-video.min.js": "2485F8AB5A4A4E5E7F40388ACD1657C9ABD1B2279C62BEA4AA3728E80F706C0F",
+ "download-video.min.js": "4013A2F8DB6B2859DF83EFEC32274158ABA1769536D8656537E2FCDF96560AD8",
"dpi-img.vue.min.js": "3D9D93079365DCABA8DC8970F051AD1A7F25C3EFFF850CD1000C4312E9B910DD",
"expand-danmaku.min.js": "B21658C40085AEA8DC49652AE62EB8610BB2EBEAF7A9C9AF69EF3B11E08EEC8D",
"expand-description.min.css": "58C7710A50521B80F7D872BDC4C652610D84C4FABC6874BA66DA37B4F8759224",
@@ -56,7 +56,7 @@
"feeds-apis.min.js": "ED1FFDEBC22680C5089F9D30CF667535FB99881C96A969DB47BC70BF095A99E8",
"feeds-filter-card.vue.min.js": "3A7F8F402EA46E43B718506329814953C9E358A8AF94088D4E5745D48296D80B",
"feeds-filter.min.js": "10557E498B8BADA3C1C03E8C1DCD6FB24DBA2DA27A5A03BD861054F7E2989D46",
- "ffmpeg-support.min.js": "E3D90A111457F7093BE2DBBC011B268B497351CCFF987394A34171F77146A9B2",
+ "ffmpeg-support.min.js": "CB33E150098394ABCACE6FC45CC1C6DA1B71012C77265D93F23C555A532016A1",
"fill-with-comments.min.js": "5D52ACB5057267C2EEBA5AA74EEE5D4086215645623560825C25AAA133536F2F",
"filter-type-switch.vue.min.js": "E06B00EF48F3CCFACC82B858A266CE0DF48F8332C5900B3AD579330D4C6D3125",
"fix-fullscreen.min.js": "C0628A7CABB4421FCBD7663700EF9965C96F6D79979B9F7523A9F9B0B009C8B6",
diff --git a/min/bundle.zip b/min/bundle.zip
index fedea8f61..a23afae1f 100644
Binary files a/min/bundle.zip and b/min/bundle.zip differ
diff --git a/min/download-video.min.js b/min/download-video.min.js
index ebb681039..2d4235fc9 100644
--- a/min/download-video.min.js
+++ b/min/download-video.min.js
@@ -1 +1 @@
-(()=>{return(t,e)=>{const{getFriendlyTitle:s}=e.import("title");const{VideoInfo:a,DanmakuInfo:i}=e.import("video-info");const{DownloadVideoPackage:n}=e.import("download-video-package");class o{async getDashUrl(t){if(t){return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&fnver=0&fnval=16`}else{return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&fnver=0&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&otype=json`}}}class r extends o{async getDashUrl(t){if(t){return`https://api.bilibili.com/pgc/player/web/playurl?avid=56995872&cid=99547543&qn=${t}&otype=json&fourk=1&fnval=16`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=56995872&cid=99547543&otype=json&fourk=1&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=&otype=json`}}}class l extends o{constructor(t){super();this.ep=t}async getDashUrl(t){if(t){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&ep_id=${this.ep}`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&ep_id=${this.ep}`}}}const c={entity:new o,aid:"",cid:""};let d=[];let p=null;class h{constructor(t,e,s){this.quality=t;this.internalName=e;this.displayName=s}async downloadInfo(t=false){const e=new u(this);await e.fetchVideoInfo(t);return e}static parseFormats(t){const e=t.accept_quality;const s=t.accept_format.split(",");const a=t.accept_description;const i=e.map((t,e)=>{return new h(t,s[e],a[e])});return i}static async getAvailableDashFormats(){const t=await c.entity.getDashUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}return h.parseFormats(e.data||e.result||e)}static async getAvailableFormats(){const t=await c.entity.getUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}const s=e.data||e.result||e;return h.parseFormats(s)}}class u{constructor(t,e){this.fragmentSplitFactor=6*2;this.workingXhr=null;this.progressMap=new Map;this.format=t;this.fragments=e||[];this.videoSpeed=new f(this)}get danmakuOption(){return t.downloadVideoDefaultDanmaku}get isDash(){return this.fragments.some(t=>t.url.includes(".m4s"))}get totalSize(){return this.fragments.map(t=>t.size).reduce((t,e)=>t+e)}async fetchVideoInfo(s=false){if(!s){const t=await c.entity.getUrl(this.format.quality);const e=await Ajax.getTextWithCredentials(t);const s=JSON.parse(e.replace(/http:/g,"https:"));const a=s.data||s.result||s;if(a.quality!==this.format.quality){throw new Error("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const i=a.durl;this.fragments=i.map(t=>{return{length:t.length,size:t.size,url:t.url,backupUrls:t.backup_url}})}else{const{dashToFragment:s,getDashInfo:a}=await e.importAsync("video-dash");const i=await a(await c.entity.getDashUrl(this.format.quality),this.format.quality);console.log(i.videoDashes);const n=(()=>{const e=e=>e.videoCodec===t.downloadVideoDashCodec;if(i.videoDashes.some(e)){return i.videoDashes.filter(e).sort(ascendingSort(t=>t.bandWidth))[0]}else{return i.videoDashes.sort(ascendingSort(t=>t.bandWidth))[0]}})();const o=i.audioDashes.sort(descendingSort(t=>t.bandWidth))[0];this.fragments=[s(n),s(o)]}return this.fragments}updateProgress(){const t=this.progressMap?[...this.progressMap.values()].reduce((t,e)=>t+e,0)/this.totalSize:0;if(t>1||t<0){console.error(`[下载视频] 进度异常: ${t}`,this.progressMap.values())}this.progress&&this.progress(t)}cancelDownload(){this.videoSpeed.stopMeasure();if(this.workingXhr!==null){this.workingXhr.forEach(t=>t.abort())}else{logError("Cancel Download Failed: forEach in this.workingXhr not found.")}}downloadFragment(t){const e=[];const s=this.isDash?4*1024*1024:16*1024*1024;let a;if(t.size<=s*6){a=t.size/this.fragmentSplitFactor}else{a=s}let i=0;const n=t=>[...this.progressMap.keys()].indexOf(t)+1;while(i{const a=new XMLHttpRequest;a.open("GET",t.url);a.responseType="arraybuffer";a.withCredentials=false;a.addEventListener("progress",t=>{console.log(`[下载视频] 视频片段${n(a)}下载进度: ${t.loaded}/${r} bytes loaded, ${o}`);this.progressMap.set(a,t.loaded);this.updateProgress()});a.addEventListener("load",()=>{if((""+a.status)[0]==="2"){console.log(`[下载视频] 视频片段${n(a)}下载完成`);e(a.response)}else{s(`视频片段${n(a)}请求失败, response = ${a.status}`)}});a.addEventListener("abort",()=>s("canceled"));a.addEventListener("error",()=>{console.error(`[下载视频] 视频片段${n(a)}下载失败: ${o}`);this.progressMap.set(a,0);this.updateProgress();a.open("GET",t.url);a.setRequestHeader("Range",o);a.send()});a.setRequestHeader("Range",o);this.progressMap.set(a,0);a.send();this.workingXhr.push(a)}));i=Math.round(i+a)+1}return Promise.all(e)}async copyUrl(){const t=this.fragments.map(t=>t.url).reduce((t,e)=>t+"\r\n"+e);GM.setClipboard(t,"text")}async showUrl(){const t=this.fragments.map(t=>`\n${t.url}\n`).reduce((t,e)=>t+"\r\n"+e);Toast.success(t+`复制全部`,"显示链接");const e=await SpinQuery.select("#copy-link");e.addEventListener("click",async()=>{await this.copyUrl()})}async exportData(t=false){const e=JSON.stringify([{fragments:this.fragments,title:s(),totalSize:this.fragments.map(t=>t.size).reduce((t,e)=>t+e),referer:document.URL.replace(window.location.search,"")}]);if(t){GM.setClipboard(e,"text")}else{const t=new Blob([e],{type:"text/json"});const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.json`,t);i.add(s()+"."+this.danmakuOption.toLowerCase(),a);await i.emit(`${s()}.zip`)}}async exportAria2(a=false){if(a){const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.${this.danmakuOption==="ASS"?"ass":"xml"}`,a);await i.emit();const o=t.aria2RpcOption;const r=this.fragments.map((t,e)=>{let a="";if(this.fragments.length>1){a=" - "+(e+1)}const i=[];if(o.secretKey!==""){i.push(`token:${o.secretKey}`)}i.push([t.url]);i.push({referer:document.URL.replace(window.location.search,""),"user-agent":UserAgent,out:`${s()}${a}${this.extension(t)}`,split:this.fragmentSplitFactor,dir:o.baseDir+o.dir||undefined,"max-download-limit":o.maxDownloadLimit||undefined});const n=encodeURIComponent(`${s()}${a}`);return{params:i,id:n}});const{sendRpc:l}=await e.importAsync("aria2-rpc");await l(r)}else{const t=`\n# Generated by Bilibili Evolved Video Export\n# https://github.com/the1812/Bilibili-Evolved/\n${this.fragments.map((t,e)=>{let a="";if(this.fragments.length>1){a=" - "+(e+1)}return`\n${t.url}\n referer=${document.URL.replace(window.location.search,"")}\n user-agent=${UserAgent}\n out=${s()}${a}${this.extension(t)}\n split=${this.fragmentSplitFactor}\n`.trim()}).join("\n")}\n`.trim();const e=new Blob([t],{type:"text/plain"});const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.txt`,e);i.add(s()+"."+this.danmakuOption.toLowerCase(),a);await i.emit(`${s()}.zip`)}}extension(t){const e=t||this.fragments[0];const s=[".flv",".mp4",".m4s"].find(t=>e.url.includes(t));if(s){return s}else{console.warn("No extension detected.");return".flv"}}async downloadDanmaku(){if(this.danmakuOption!=="无"){const t=new i(c.cid);await t.fetchInfo();if(this.danmakuOption==="XML"){return t.rawXML}else{const{convertToAss:s}=await e.importAsync("download-danmaku");return s(t.rawXML)}}else{return null}}async download(){this.workingXhr=[];this.progressMap=new Map;this.updateProgress();const t=[];this.videoSpeed.startMeasure();for(const e of this.fragments){const s=await this.downloadFragment(e);t.push(s)}if(t.length<1){throw new Error("下载失败.")}const e=s();const a=new n;t.forEach((s,i)=>{let n;const o=this.fragments[i];if(t.length>1){n=`${e} - ${i+1}${this.extension(o)}`}else{n=`${e}${this.extension(o)}`}a.add(n,new Blob(Array.isArray(s)?s:[s],{type:this.extension(o)===".flv"?"video/x-flv":"video/mp4"}))});const i=await this.downloadDanmaku();a.add(`${s()}.${this.danmakuOption==="ASS"?"ass":"xml"}`,i);await a.emit(e+".zip");this.progress&&this.progress(0);this.videoSpeed.stopMeasure()}}class f{constructor(t){this.lastProgress=0;this.measureInterval=1e3;this.workingDownloader=t}startMeasure(){this.intervalTimer=setInterval(()=>{const t=this.workingDownloader.progressMap?[...this.workingDownloader.progressMap.values()].reduce((t,e)=>t+e,0):0;const e=t-this.lastProgress;if(this.speedUpdate!==undefined){this.speedUpdate(formatFileSize(e)+"/s")}this.lastProgress=t},this.measureInterval)}stopMeasure(){clearInterval(this.intervalTimer)}}async function m(){const t=await SpinQuery.select(()=>(unsafeWindow||window).aid);const e=await SpinQuery.select(()=>(unsafeWindow||window).cid);if(!(t&&e)){return false}c.aid=t;c.cid=e;if(document.URL.includes("bangumi")){c.entity=new r}else if(document.URL.includes("cheese")){const t=document.URL.match(/cheese\/play\/ep([\d]+)/);c.entity=new l(t[1])}else{c.entity=new o}try{d=await h.getAvailableFormats()}catch(t){return false}return true}async function w(){p=d[0];e.applyStyle("downloadVideoStyle");const t=dq("#download-video");t.addEventListener("click",()=>{const t=dq(".download-video");t.classList.toggle("opened");window.scroll(0,0);dq(".gui-settings-mask").click()});t.addEventListener("mouseover",()=>{document.body.insertAdjacentHTML("beforeend",e.import("downloadVideoHtml"));g()},{once:true})}async function g(){let o;const r=new Vue({el:".download-video",components:{VDropdown:()=>e.importAsync("v-dropdown.vue"),VCheckbox:()=>e.importAsync("v-checkbox.vue"),RpcProfiles:()=>e.importAsync("aria2-rpc-profiles.vue")},data:{downloadSingle:true,coverUrl:EmptyImageUrl,aid:c.aid,cid:c.cid,dashModel:{value:t.downloadVideoFormat,items:["flv","dash"]},qualityModel:{value:p.displayName,items:d.map(t=>t.displayName)},danmakuModel:{value:t.downloadVideoDefaultDanmaku,items:["无","XML","ASS"]},codecModel:{value:t.downloadVideoDashCodec,items:["AVC/H.264","HEVC/H.265"]},progressPercent:0,size:"获取大小中",blobUrl:"",episodeList:[],downloading:false,speed:"",batch:false,rpcSettings:t.aria2RpcOption,showRpcSettings:false,busy:false,saveRpcSettingsText:"保存配置",enableDash:t.enableDashDownload,lastDirectDownloadLink:""},computed:{displaySize(){if(typeof this.size==="string"){return this.size}return formatFileSize(this.size)},sizeWarning(){if(typeof this.size==="string"){return false}return this.size>1073741824},selectedEpisodeCount(){return this.episodeList.filter(t=>t.checked).length},dash(){return this.dashModel.value==="dash"}},methods:{close(){this.$el.classList.remove("opened")},danmakuOptionChange(){t.downloadVideoDefaultDanmaku=this.danmakuModel.value},async codecChange(){t.downloadVideoDashCodec=this.codecModel.value;await this.formatChange()},async dashChange(){console.log("dash change");t.downloadVideoFormat=this.dashModel.value;const e=this.dashModel.value;let s=[];if(e==="flv"){s=await h.getAvailableFormats()}else{s=await h.getAvailableDashFormats()}d=s;[p]=e;this.qualityModel.items=s.map(t=>t.displayName);[this.qualityModel.value]=this.qualityModel.items;await this.formatChange()},async formatChange(){console.log("format change");const t=this.getFormat();try{this.size="获取大小中";const e=await t.downloadInfo(this.dash);this.size=e.totalSize}catch(t){this.size="获取大小失败";throw t}},getFormat(){const t=d.find(t=>t.displayName===this.qualityModel.value);if(!t){console.error(`No format found. model value = ${this.qualityModel.value}`);return null}return t},async exportData(t){if(this.busy===true){return}try{this.busy=true;if(!this.downloadSingle){await this.exportBatchData(t);return}const a=this.getFormat();const i=await a.downloadInfo(this.dash);switch(t){case"copyLink":await i.copyUrl();Toast.success("已复制链接到剪贴板.","下载视频",3e3);break;case"showLink":await i.showUrl();break;case"aria2":await i.exportAria2(false);break;case"aria2RPC":await i.exportAria2(true);break;case"copyVLD":await i.exportData(true);Toast.success("已复制VLD数据到剪贴板.","下载视频",3e3);break;case"exportVLD":await i.exportData(false);break;case"ffmpegFragments":if(i.fragments.length<2){Toast.info("当前视频没有分段.","分段列表",3e3)}else{const{getFragmentsList:t}=await e.importAsync("ffmpeg-support");const a=new n;a.add("ffmpeg-files.txt",t(i.fragments.length,s(),i.extension(i.fragments[0])));await a.emit()}break;default:break}}catch(t){logError(t)}finally{this.busy=false}},async exportBatchData(t){const a=this.episodeList;if(a.every(t=>t.checked===false)){Toast.info("请至少选择1集或以上的数量!","批量导出",3e3);return}const o=t=>{const e=a.find(e=>e.cid===t.cid);if(e===undefined){return false}return e.checked};const r=this.getFormat();if(this.danmakuModel.value!=="无"){const t=Toast.info("下载弹幕中...","批量导出");const s=new n;try{if(this.danmakuModel.value==="XML"){for(const t of a.filter(o)){const e=new i(t.cid);await e.fetchInfo();s.add(t.title+".xml",e.rawXML)}}else{const{convertToAss:t}=await e.importAsync("download-danmaku");for(const e of a.filter(o)){const a=new i(e.cid);await a.fetchInfo();s.add(e.title+".ass",await t(a.rawXML))}}await s.emit(this.cid+".danmakus.zip")}catch(t){logError(`弹幕下载失败`)}finally{t.dismiss()}}const l=Toast.info("获取链接中...","批量导出");const c=this.batchExtractor;c.itemFilter=o;let d;try{switch(t){case"aria2":d=await c.collectAria2(r,l,false);await n.single(s(false)+".txt",new Blob([d],{type:"text/plain"}),{ffmpeg:this.ffmpegOption});return;case"aria2RPC":await c.collectAria2(r,l,true);Toast.success(`成功发送了批量请求.`,"aria2 RPC",3e3);return;case"copyVLD":GM.setClipboard(await c.collectData(r,l),{mimetype:"text/plain"});Toast.success("已复制批量vld数据到剪贴板.","批量导出",3e3);return;case"exportVLD":d=await c.collectData(r,l);await n.single(s(false)+".json",new Blob([d],{type:"text/json"}),{ffmpeg:this.ffmpegOption});return;case"ffmpegFragments":{const t=await c.getRawItems(r);const a=new u(r,t[0].fragments);const{getBatchFragmentsList:i}=await e.importAsync("ffmpeg-support");const o=i(t,a.extension());if(!o){Toast.info("所有选择的分P都没有分段.","分段列表",3e3)}else{const t=new n;for(const[e,s]of o.entries()){t.add(e,s)}await t.emit(escapeFilename(`${s(false)}.zip`))}}break;case"ffmpegEpisodes":{const t=await c.getRawItems(r);const s=new u(r,t[0].fragments);const{getBatchEpisodesList:a}=await e.importAsync("ffmpeg-support");const i=a(t,s.extension());const o=new n;o.add("ffmpeg-files.txt",i);await o.emit()}break;default:return}}catch(t){logError(t)}finally{l.dismiss()}},async checkBatch(){const t=["/www.bilibili.com/bangumi","/www.bilibili.com/video/av"];if(!t.some(t=>document.URL.includes(t))){this.batch=false;this.episodeList=[];return}const{BatchExtractor:s}=await e.importAsync("batch-download");if(await s.test()!==true){this.batch=false;this.episodeList=[];return}const a=this.batchExtractor=new s;this.batch=true;this.episodeList=(await a.getItemList()).map((t,e)=>{return{aid:t.aid,cid:t.cid,title:t.title,index:e,checked:true}})},cancelDownload(){if(o){o.cancelDownload()}},async startDownload(){const t=this.getFormat();try{this.downloading=true;const e=await t.downloadInfo(this.dash);e.videoSpeed.speedUpdate=(t=>this.speed=t);e.progress=(t=>{this.progressPercent=Math.trunc(t*100)});o=e;await e.download();this.lastDirectDownloadLink=n.lastPackageUrl}catch(t){if(t!=="canceled"){logError(t)}this.progressPercent=0}finally{this.downloading=false;this.speed=""}},selectAllEpisodes(){this.episodeList.forEach(t=>t.checked=true)},unselectAllEpisodes(){this.episodeList.forEach(t=>t.checked=false)},inverseAllEpisodes(){this.episodeList.forEach(t=>t.checked=!t.checked)},toggleRpcSettings(){this.showRpcSettings=!this.showRpcSettings},saveRpcSettings(){if(this.rpcSettings.host===""){this.rpcSettings.host="127.0.0.1"}if(this.rpcSettings.port===""){this.rpcSettings.port="6800"}t.aria2RpcOption=this.rpcSettings;const e=t.aria2RpcOptionProfiles.find(e=>e.name===t.aria2RpcOptionSelectedProfile);if(e){Object.assign(e,this.rpcSettings);t.aria2RpcOptionProfiles=t.aria2RpcOptionProfiles}this.saveRpcSettingsText="已保存";setTimeout(()=>this.saveRpcSettingsText="保存配置",2e3)},updateProfile(e){t.aria2RpcOption=this.rpcSettings=_.omit(e,"name")}},async mounted(){}});Observer.videoChange(async()=>{r.close();r.batch=false;r.downloadSingle=true;const t=dq("#download-video");const e=await m();t.style.display=e?"flex":"none";if(!e){return}r.aid=c.aid;r.cid=c.cid;try{const t=new a(c.aid);await t.fetchInfo();r.coverUrl=t.coverUrl.replace("http:","https:")}catch(t){r.coverUrl=EmptyImageUrl}r.dashChange();await r.checkBatch()})}return{widget:{content:`\n`,condition:m,success:w}}}})();
\ No newline at end of file
+(()=>{return(t,e)=>{const{getFriendlyTitle:s}=e.import("title");const{VideoInfo:a,DanmakuInfo:i}=e.import("video-info");const{DownloadVideoPackage:n}=e.import("download-video-package");class o{async getDashUrl(t){if(t){return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&fnver=0&fnval=16`}else{return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&fnver=0&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${c.aid}&cid=${c.cid}&otype=json`}}}class r extends o{async getDashUrl(t){if(t){return`https://api.bilibili.com/pgc/player/web/playurl?avid=56995872&cid=99547543&qn=${t}&otype=json&fourk=1&fnval=16`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=56995872&cid=99547543&otype=json&fourk=1&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=&otype=json`}}}class l extends o{constructor(t){super();this.ep=t}async getDashUrl(t){if(t){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}}async getUrl(t){if(t){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&qn=${t}&otype=json&ep_id=${this.ep}`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${c.aid}&cid=${c.cid}&otype=json&ep_id=${this.ep}`}}}const c={entity:new o,aid:"",cid:""};let d=[];let p=null;class h{constructor(t,e,s){this.quality=t;this.internalName=e;this.displayName=s}async downloadInfo(t=false){const e=new u(this);await e.fetchVideoInfo(t);return e}static parseFormats(t){const e=t.accept_quality;const s=t.accept_format.split(",");const a=t.accept_description;const i=e.map((t,e)=>{return new h(t,s[e],a[e])});return i}static async getAvailableDashFormats(){const t=await c.entity.getDashUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}return h.parseFormats(e.data||e.result||e)}static async getAvailableFormats(){const t=await c.entity.getUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}const s=e.data||e.result||e;return h.parseFormats(s)}}class u{constructor(t,e){this.fragmentSplitFactor=6*2;this.workingXhr=null;this.progressMap=new Map;this.format=t;this.fragments=e||[];this.videoSpeed=new f(this)}get danmakuOption(){return t.downloadVideoDefaultDanmaku}get isDash(){return this.fragments.some(t=>t.url.includes(".m4s"))}get totalSize(){return this.fragments.map(t=>t.size).reduce((t,e)=>t+e)}async fetchVideoInfo(s=false){if(!s){const t=await c.entity.getUrl(this.format.quality);const e=await Ajax.getTextWithCredentials(t);const s=JSON.parse(e.replace(/http:/g,"https:"));const a=s.data||s.result||s;if(a.quality!==this.format.quality){throw new Error("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const i=a.durl;this.fragments=i.map(t=>{return{length:t.length,size:t.size,url:t.url,backupUrls:t.backup_url}})}else{const{dashToFragment:s,getDashInfo:a}=await e.importAsync("video-dash");const i=await a(await c.entity.getDashUrl(this.format.quality),this.format.quality);console.log(i.videoDashes);const n=(()=>{const e=e=>e.videoCodec===t.downloadVideoDashCodec;if(i.videoDashes.some(e)){return i.videoDashes.filter(e).sort(ascendingSort(t=>t.bandWidth))[0]}else{return i.videoDashes.sort(ascendingSort(t=>t.bandWidth))[0]}})();const o=i.audioDashes.sort(descendingSort(t=>t.bandWidth))[0];this.fragments=[s(n),s(o)]}return this.fragments}updateProgress(){const t=this.progressMap?[...this.progressMap.values()].reduce((t,e)=>t+e,0)/this.totalSize:0;if(t>1||t<0){console.error(`[下载视频] 进度异常: ${t}`,this.progressMap.values())}this.progress&&this.progress(t)}cancelDownload(){this.videoSpeed.stopMeasure();if(this.workingXhr!==null){this.workingXhr.forEach(t=>t.abort())}else{logError("Cancel Download Failed: forEach in this.workingXhr not found.")}}downloadFragment(t){const e=[];const s=this.isDash?4*1024*1024:16*1024*1024;let a;if(t.size<=s*6){a=t.size/this.fragmentSplitFactor}else{a=s}let i=0;const n=t=>[...this.progressMap.keys()].indexOf(t)+1;while(i{const a=new XMLHttpRequest;a.open("GET",t.url);a.responseType="arraybuffer";a.withCredentials=false;a.addEventListener("progress",t=>{console.log(`[下载视频] 视频片段${n(a)}下载进度: ${t.loaded}/${r} bytes loaded, ${o}`);this.progressMap.set(a,t.loaded);this.updateProgress()});a.addEventListener("load",()=>{if((""+a.status)[0]==="2"){console.log(`[下载视频] 视频片段${n(a)}下载完成`);e(a.response)}else{s(`视频片段${n(a)}请求失败, response = ${a.status}`)}});a.addEventListener("abort",()=>s("canceled"));a.addEventListener("error",()=>{console.error(`[下载视频] 视频片段${n(a)}下载失败: ${o}`);this.progressMap.set(a,0);this.updateProgress();a.open("GET",t.url);a.setRequestHeader("Range",o);a.send()});a.setRequestHeader("Range",o);this.progressMap.set(a,0);a.send();this.workingXhr.push(a)}));i=Math.round(i+a)+1}return Promise.all(e)}async copyUrl(){const t=this.fragments.map(t=>t.url).reduce((t,e)=>t+"\r\n"+e);GM.setClipboard(t,"text")}async showUrl(){const t=this.fragments.map(t=>`\n${t.url}\n`).reduce((t,e)=>t+"\r\n"+e);Toast.success(t+`复制全部`,"显示链接");const e=await SpinQuery.select("#copy-link");e.addEventListener("click",async()=>{await this.copyUrl()})}async exportData(t=false){const e=JSON.stringify([{fragments:this.fragments,title:s(),totalSize:this.fragments.map(t=>t.size).reduce((t,e)=>t+e),referer:document.URL.replace(window.location.search,"")}]);if(t){GM.setClipboard(e,"text")}else{const t=new Blob([e],{type:"text/json"});const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.json`,t);i.add(s()+"."+this.danmakuOption.toLowerCase(),a);await i.emit(`${s()}.zip`)}}async exportAria2(a=false){if(a){const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.${this.danmakuOption==="ASS"?"ass":"xml"}`,a);await i.emit();const o=t.aria2RpcOption;const r=this.fragments.map((t,e)=>{let a="";if(this.fragments.length>1&&!this.isDash){a=" - "+(e+1)}const i=[];if(o.secretKey!==""){i.push(`token:${o.secretKey}`)}i.push([t.url]);i.push({referer:document.URL.replace(window.location.search,""),"user-agent":UserAgent,out:`${s()}${a}${this.extension(t)}`,split:this.fragmentSplitFactor,dir:o.baseDir+o.dir||undefined,"max-download-limit":o.maxDownloadLimit||undefined});const n=encodeURIComponent(`${s()}${a}`);return{params:i,id:n}});const{sendRpc:l}=await e.importAsync("aria2-rpc");await l(r)}else{const t=`\n# Generated by Bilibili Evolved Video Export\n# https://github.com/the1812/Bilibili-Evolved/\n${this.fragments.map((t,e)=>{let a="";if(this.fragments.length>1&&!this.isDash){a=" - "+(e+1)}return`\n${t.url}\n referer=${document.URL.replace(window.location.search,"")}\n user-agent=${UserAgent}\n out=${s()}${a}${this.extension(t)}\n split=${this.fragmentSplitFactor}\n`.trim()}).join("\n")}\n`.trim();const e=new Blob([t],{type:"text/plain"});const a=await this.downloadDanmaku();const i=new n;i.add(`${s()}.txt`,e);i.add(s()+"."+this.danmakuOption.toLowerCase(),a);await i.emit(`${s()}.zip`)}}extension(t){const e=t||this.fragments[0];const s=[".flv",".mp4"].find(t=>e.url.includes(t));if(s){return s}else if(e.url.includes(".m4s")){return this.fragments.indexOf(e)===0?".mp4":".m4a"}else{console.warn("No extension detected.");return".flv"}}async downloadDanmaku(){if(this.danmakuOption!=="无"){const t=new i(c.cid);await t.fetchInfo();if(this.danmakuOption==="XML"){return t.rawXML}else{const{convertToAss:s}=await e.importAsync("download-danmaku");return s(t.rawXML)}}else{return null}}async download(){this.workingXhr=[];this.progressMap=new Map;this.updateProgress();const t=[];this.videoSpeed.startMeasure();for(const e of this.fragments){const s=await this.downloadFragment(e);t.push(s)}if(t.length<1){throw new Error("下载失败.")}const e=s();const a=new n;t.forEach((s,i)=>{let n;const o=this.fragments[i];if(t.length>1&&!this.isDash){n=`${e} - ${i+1}${this.extension(o)}`}else{n=`${e}${this.extension(o)}`}a.add(n,new Blob(Array.isArray(s)?s:[s]))});const i=await this.downloadDanmaku();a.add(`${s()}.${this.danmakuOption==="ASS"?"ass":"xml"}`,i);await a.emit(e+".zip");this.progress&&this.progress(0);this.videoSpeed.stopMeasure()}}class f{constructor(t){this.lastProgress=0;this.measureInterval=1e3;this.workingDownloader=t}startMeasure(){this.intervalTimer=setInterval(()=>{const t=this.workingDownloader.progressMap?[...this.workingDownloader.progressMap.values()].reduce((t,e)=>t+e,0):0;const e=t-this.lastProgress;if(this.speedUpdate!==undefined){this.speedUpdate(formatFileSize(e)+"/s")}this.lastProgress=t},this.measureInterval)}stopMeasure(){clearInterval(this.intervalTimer)}}async function m(){const t=await SpinQuery.select(()=>(unsafeWindow||window).aid);const e=await SpinQuery.select(()=>(unsafeWindow||window).cid);if(!(t&&e)){return false}c.aid=t;c.cid=e;if(document.URL.includes("bangumi")){c.entity=new r}else if(document.URL.includes("cheese")){const t=document.URL.match(/cheese\/play\/ep([\d]+)/);c.entity=new l(t[1])}else{c.entity=new o}try{d=await h.getAvailableFormats()}catch(t){return false}return true}async function w(){p=d[0];e.applyStyle("downloadVideoStyle");const t=dq("#download-video");t.addEventListener("click",()=>{const t=dq(".download-video");t.classList.toggle("opened");window.scroll(0,0);dq(".gui-settings-mask").click()});t.addEventListener("mouseover",()=>{document.body.insertAdjacentHTML("beforeend",e.import("downloadVideoHtml"));g()},{once:true})}async function g(){let o;const r=new Vue({el:".download-video",components:{VDropdown:()=>e.importAsync("v-dropdown.vue"),VCheckbox:()=>e.importAsync("v-checkbox.vue"),RpcProfiles:()=>e.importAsync("aria2-rpc-profiles.vue")},data:{downloadSingle:true,coverUrl:EmptyImageUrl,aid:c.aid,cid:c.cid,dashModel:{value:t.downloadVideoFormat,items:["flv","dash"]},qualityModel:{value:p.displayName,items:d.map(t=>t.displayName)},danmakuModel:{value:t.downloadVideoDefaultDanmaku,items:["无","XML","ASS"]},codecModel:{value:t.downloadVideoDashCodec,items:["AVC/H.264","HEVC/H.265"]},progressPercent:0,size:"获取大小中",blobUrl:"",episodeList:[],downloading:false,speed:"",batch:false,rpcSettings:t.aria2RpcOption,showRpcSettings:false,busy:false,saveRpcSettingsText:"保存配置",enableDash:t.enableDashDownload,lastDirectDownloadLink:""},computed:{displaySize(){if(typeof this.size==="string"){return this.size}return formatFileSize(this.size)},sizeWarning(){if(typeof this.size==="string"){return false}return this.size>1073741824},selectedEpisodeCount(){return this.episodeList.filter(t=>t.checked).length},dash(){return this.dashModel.value==="dash"}},methods:{close(){this.$el.classList.remove("opened")},danmakuOptionChange(){t.downloadVideoDefaultDanmaku=this.danmakuModel.value},async codecChange(){t.downloadVideoDashCodec=this.codecModel.value;await this.formatChange()},async dashChange(){console.log("dash change");t.downloadVideoFormat=this.dashModel.value;const e=this.dashModel.value;let s=[];if(e==="flv"){s=await h.getAvailableFormats()}else{s=await h.getAvailableDashFormats()}d=s;[p]=e;this.qualityModel.items=s.map(t=>t.displayName);[this.qualityModel.value]=this.qualityModel.items;await this.formatChange()},async formatChange(){console.log("format change");const t=this.getFormat();try{this.size="获取大小中";const e=await t.downloadInfo(this.dash);this.size=e.totalSize}catch(t){this.size="获取大小失败";throw t}},getFormat(){const t=d.find(t=>t.displayName===this.qualityModel.value);if(!t){console.error(`No format found. model value = ${this.qualityModel.value}`);return null}return t},async exportData(t){if(this.busy===true){return}try{this.busy=true;if(!this.downloadSingle){await this.exportBatchData(t);return}const a=this.getFormat();const i=await a.downloadInfo(this.dash);switch(t){case"copyLink":await i.copyUrl();Toast.success("已复制链接到剪贴板.","下载视频",3e3);break;case"showLink":await i.showUrl();break;case"aria2":await i.exportAria2(false);break;case"aria2RPC":await i.exportAria2(true);break;case"copyVLD":await i.exportData(true);Toast.success("已复制VLD数据到剪贴板.","下载视频",3e3);break;case"exportVLD":await i.exportData(false);break;case"ffmpegFragments":if(i.fragments.length<2){Toast.info("当前视频没有分段.","分段列表",3e3)}else{const{getFragmentsList:t}=await e.importAsync("ffmpeg-support");const a=new n;a.add("ffmpeg-files.txt",t(i.fragments.length,s(),i.fragments.map(t=>i.extension(t))));await a.emit()}break;default:break}}catch(t){logError(t)}finally{this.busy=false}},async exportBatchData(t){const a=this.episodeList;if(a.every(t=>t.checked===false)){Toast.info("请至少选择1集或以上的数量!","批量导出",3e3);return}const o=t=>{const e=a.find(e=>e.cid===t.cid);if(e===undefined){return false}return e.checked};const r=this.getFormat();if(this.danmakuModel.value!=="无"){const t=Toast.info("下载弹幕中...","批量导出");const s=new n;try{if(this.danmakuModel.value==="XML"){for(const t of a.filter(o)){const e=new i(t.cid);await e.fetchInfo();s.add(t.title+".xml",e.rawXML)}}else{const{convertToAss:t}=await e.importAsync("download-danmaku");for(const e of a.filter(o)){const a=new i(e.cid);await a.fetchInfo();s.add(e.title+".ass",await t(a.rawXML))}}await s.emit(this.cid+".danmakus.zip")}catch(t){logError(`弹幕下载失败`)}finally{t.dismiss()}}const l=Toast.info("获取链接中...","批量导出");const c=this.batchExtractor;c.itemFilter=o;let d;try{switch(t){case"aria2":d=await c.collectAria2(r,l,false);await n.single(s(false)+".txt",new Blob([d],{type:"text/plain"}),{ffmpeg:this.ffmpegOption});return;case"aria2RPC":await c.collectAria2(r,l,true);Toast.success(`成功发送了批量请求.`,"aria2 RPC",3e3);return;case"copyVLD":GM.setClipboard(await c.collectData(r,l),{mimetype:"text/plain"});Toast.success("已复制批量vld数据到剪贴板.","批量导出",3e3);return;case"exportVLD":d=await c.collectData(r,l);await n.single(s(false)+".json",new Blob([d],{type:"text/json"}),{ffmpeg:this.ffmpegOption});return;case"ffmpegFragments":{const t=await c.getRawItems(r);const a=new u(r,t[0].fragments);const{getBatchFragmentsList:i}=await e.importAsync("ffmpeg-support");const o=this.dash?[".mp4","m4a"]:[a.extension()];const l=i(t,o);if(!l){Toast.info("所有选择的分P都没有分段.","分段列表",3e3)}else{const t=new n;for(const[e,s]of l.entries()){t.add(e,s)}await t.emit(escapeFilename(`${s(false)}.zip`))}}break;case"ffmpegEpisodes":{const t=await c.getRawItems(r);const s=new u(r,t[0].fragments);const{getBatchEpisodesList:a}=await e.importAsync("ffmpeg-support");const i=this.dash?[".mp4","m4a"]:[s.extension()];const o=a(t,i);const l=new n;l.add("ffmpeg-files.txt",o);await l.emit()}break;default:return}}catch(t){logError(t)}finally{l.dismiss()}},async checkBatch(){const t=["/www.bilibili.com/bangumi","/www.bilibili.com/video/av"];if(!t.some(t=>document.URL.includes(t))){this.batch=false;this.episodeList=[];return}const{BatchExtractor:s}=await e.importAsync("batch-download");if(await s.test()!==true){this.batch=false;this.episodeList=[];return}const a=this.batchExtractor=new s;this.batch=true;this.episodeList=(await a.getItemList()).map((t,e)=>{return{aid:t.aid,cid:t.cid,title:t.title,index:e,checked:true}})},cancelDownload(){if(o){o.cancelDownload()}},async startDownload(){const t=this.getFormat();try{this.downloading=true;const e=await t.downloadInfo(this.dash);e.videoSpeed.speedUpdate=(t=>this.speed=t);e.progress=(t=>{this.progressPercent=Math.trunc(t*100)});o=e;await e.download();this.lastDirectDownloadLink=n.lastPackageUrl}catch(t){if(t!=="canceled"){logError(t)}this.progressPercent=0}finally{this.downloading=false;this.speed=""}},selectAllEpisodes(){this.episodeList.forEach(t=>t.checked=true)},unselectAllEpisodes(){this.episodeList.forEach(t=>t.checked=false)},inverseAllEpisodes(){this.episodeList.forEach(t=>t.checked=!t.checked)},toggleRpcSettings(){this.showRpcSettings=!this.showRpcSettings},saveRpcSettings(){if(this.rpcSettings.host===""){this.rpcSettings.host="127.0.0.1"}if(this.rpcSettings.port===""){this.rpcSettings.port="6800"}t.aria2RpcOption=this.rpcSettings;const e=t.aria2RpcOptionProfiles.find(e=>e.name===t.aria2RpcOptionSelectedProfile);if(e){Object.assign(e,this.rpcSettings);t.aria2RpcOptionProfiles=t.aria2RpcOptionProfiles}this.saveRpcSettingsText="已保存";setTimeout(()=>this.saveRpcSettingsText="保存配置",2e3)},updateProfile(e){t.aria2RpcOption=this.rpcSettings=_.omit(e,"name")}},async mounted(){}});Observer.videoChange(async()=>{r.close();r.batch=false;r.downloadSingle=true;const t=dq("#download-video");const e=await m();t.style.display=e?"flex":"none";if(!e){return}r.aid=c.aid;r.cid=c.cid;try{const t=new a(c.aid);await t.fetchInfo();r.coverUrl=t.coverUrl.replace("http:","https:")}catch(t){r.coverUrl=EmptyImageUrl}r.dashChange();await r.checkBatch()})}return{widget:{content:`\n`,condition:m,success:w}}}})();
\ No newline at end of file
diff --git a/min/ffmpeg-support.min.js b/min/ffmpeg-support.min.js
index 54c4d3af6..9fc11a419 100644
--- a/min/ffmpeg-support.min.js
+++ b/min/ffmpeg-support.min.js
@@ -1 +1 @@
-(()=>{return(e,t)=>{const n=(e,t,n)=>{if(e<2){return null}const r=[];for(let s=1;s<=e;s++){r.push(escapeFilename(`file '${t} - ${s}${n}'`))}return r.join("\n")};const r=(e,t)=>{const n=e=>e.fragments.length>1;const r=e.filter(n);if(r.length===0){return null}const s=new Map;r.forEach(e=>{s.set(escapeFilename(`ffmpeg-files-${e.title}.txt`),e.fragments.map((n,r)=>{return escapeFilename(`file '${e.title} - ${r+1}${t}'`)}).join("\n"))});return s};const s=(e,t)=>{const n=[];e.forEach(e=>{e.fragments.forEach((r,s)=>{let i="";if(e.fragments.length>1){i=` - ${s+1}`}n.push(escapeFilename(`file '${e.title}${i}${t}'`))})});return n.join("\n")};return{export:{getFragmentsList:n,getBatchFragmentsList:r,getBatchEpisodesList:s}}}})();
\ No newline at end of file
+(()=>{return(e,t)=>{const n=(e,t,n)=>{if(e<2){return null}const s=[];for(let r=1;r<=e;r++){let e=` - ${r}`;if(n.includes(".m4a")){e=""}s.push(escapeFilename(`file '${t}${e}${n[r-1]}'`))}return s.join("\n")};const s=(e,t)=>{const n=e=>e.fragments.length>1;const s=e.filter(n);if(s.length===0){return null}const r=new Map;s.forEach(e=>{r.set(escapeFilename(`ffmpeg-files-${e.title}.txt`),e.fragments.map((n,s)=>{return escapeFilename(`file '${e.title} - ${s+1}${t[s]}'`)}).join("\n"))});return r};const r=(e,t)=>{const n=[];e.forEach(e=>{e.fragments.forEach((s,r)=>{let i="";if(e.fragments.length>1&&!t.includes(".m4a")){i=` - ${r+1}`}n.push(escapeFilename(`file '${e.title}${i}${t[r]}'`))})});return n.join("\n")};return{export:{getFragmentsList:n,getBatchFragmentsList:s,getBatchEpisodesList:r}}}})();
\ No newline at end of file
diff --git a/src/video/download-video/download-video.ts b/src/video/download-video/download-video.ts
index 285d501e6..e7b5eff33 100644
--- a/src/video/download-video/download-video.ts
+++ b/src/video/download-video/download-video.ts
@@ -325,7 +325,7 @@ class VideoDownloader {
const option = settings.aria2RpcOption
const params = this.fragments.map((fragment, index) => {
let indexNumber = ''
- if (this.fragments.length > 1) {
+ if (this.fragments.length > 1 && !this.isDash) {
indexNumber = ' - ' + (index + 1)
}
const params = []
@@ -355,7 +355,7 @@ class VideoDownloader {
# https://github.com/the1812/Bilibili-Evolved/
${this.fragments.map((it, index) => {
let indexNumber = ''
- if (this.fragments.length > 1) {
+ if (this.fragments.length > 1 && !this.isDash) {
indexNumber = ' - ' + (index + 1)
}
return `
@@ -380,10 +380,11 @@ ${it.url}
const match = [
'.flv',
'.mp4',
- '.m4s',
].find(it => f.url.includes(it))
if (match) {
return match
+ } else if (f.url.includes('.m4s')) {
+ return this.fragments.indexOf(f) === 0 ? '.mp4' : '.m4a'
} else {
console.warn('No extension detected.')
return '.flv'
@@ -488,14 +489,12 @@ ${it.url}
downloadedData.forEach((data, index) => {
let filename: string
const fragment = this.fragments[index]
- if (downloadedData.length > 1) {
+ if (downloadedData.length > 1 && !this.isDash) {
filename = `${title} - ${index + 1}${this.extension(fragment)}`
} else {
filename = `${title}${this.extension(fragment)}`
}
- pack.add(filename, new Blob(Array.isArray(data) ? data : [data], {
- type: this.extension(fragment) === '.flv' ? 'video/x-flv' : 'video/mp4'
- }))
+ pack.add(filename, new Blob(Array.isArray(data) ? data : [data]))
})
const danmaku = await this.downloadDanmaku()
pack.add(
@@ -746,7 +745,7 @@ async function loadPanel() {
} else {
const { getFragmentsList } = await import('./ffmpeg-support')
const pack = new DownloadVideoPackage()
- pack.add('ffmpeg-files.txt', getFragmentsList(videoDownloader.fragments.length, getFriendlyTitle(), videoDownloader.extension(videoDownloader.fragments[0])))
+ pack.add('ffmpeg-files.txt', getFragmentsList(videoDownloader.fragments.length, getFriendlyTitle(), videoDownloader.fragments.map(f => videoDownloader.extension(f))))
await pack.emit()
}
break
@@ -833,7 +832,8 @@ async function loadPanel() {
const items = await batchExtractor.getRawItems(format)
const videoDownloader = new VideoDownloader(format, items[0].fragments)
const { getBatchFragmentsList } = await import('./ffmpeg-support')
- const map = getBatchFragmentsList(items, videoDownloader.extension())
+ const extensions = this.dash ? ['.mp4', 'm4a'] : [videoDownloader.extension()]
+ const map = getBatchFragmentsList(items, extensions)
if (!map) {
Toast.info('所有选择的分P都没有分段.', '分段列表', 3000)
} else {
@@ -850,7 +850,8 @@ async function loadPanel() {
const items = await batchExtractor.getRawItems(format)
const videoDownloader = new VideoDownloader(format, items[0].fragments)
const { getBatchEpisodesList } = await import('./ffmpeg-support')
- const content = getBatchEpisodesList(items, videoDownloader.extension())
+ const extensions = this.dash ? ['.mp4', 'm4a'] : [videoDownloader.extension()]
+ const content = getBatchEpisodesList(items, extensions)
const pack = new DownloadVideoPackage()
pack.add('ffmpeg-files.txt', content)
await pack.emit()
diff --git a/src/video/download-video/ffmpeg-support.ts b/src/video/download-video/ffmpeg-support.ts
index cd13c2a32..13c78829e 100644
--- a/src/video/download-video/ffmpeg-support.ts
+++ b/src/video/download-video/ffmpeg-support.ts
@@ -1,16 +1,20 @@
import { RawItem } from './batch-download'
-export const getFragmentsList = (count: number, originalTitle: string, extension: string) => {
+export const getFragmentsList = (count: number, originalTitle: string, extensions: string[]) => {
if (count < 2) {
return null
}
const names = []
for (let index = 1; index <= count; index++) {
- names.push(escapeFilename(`file '${originalTitle} - ${index}${extension}'`))
+ let indexNumber = ` - ${index}`
+ if (extensions.includes('.m4a')) {
+ indexNumber = ''
+ }
+ names.push(escapeFilename(`file '${originalTitle}${indexNumber}${extensions[index - 1]}'`))
}
return names.join('\n')
}
-export const getBatchFragmentsList = (items: RawItem[], extension: string) => {
+export const getBatchFragmentsList = (items: RawItem[], extensions: string[]) => {
const multipleFragments = (item: RawItem) => item.fragments.length > 1
const fragmentsItems = items.filter(multipleFragments)
if (fragmentsItems.length === 0) {
@@ -19,20 +23,20 @@ export const getBatchFragmentsList = (items: RawItem[], extension: string) => {
const names = new Map()
fragmentsItems.forEach(item => {
names.set(escapeFilename(`ffmpeg-files-${item.title}.txt`), item.fragments.map((_, index) => {
- return escapeFilename(`file '${item.title} - ${index + 1}${extension}'`)
+ return escapeFilename(`file '${item.title} - ${index + 1}${extensions[index]}'`)
}).join('\n'))
})
return names
}
-export const getBatchEpisodesList = (items: RawItem[], extension: string) => {
+export const getBatchEpisodesList = (items: RawItem[], extensions: string[]) => {
const names: string[] = []
items.forEach(item => {
- item.fragments.forEach((f, index) => {
+ item.fragments.forEach((_, index) => {
let indexNumber = ''
- if (item.fragments.length > 1) {
+ if (item.fragments.length > 1 && !extensions.includes('.m4a')) {
indexNumber = ` - ${index + 1}`
}
- names.push(escapeFilename(`file '${item.title}${indexNumber}${extension}'`))
+ names.push(escapeFilename(`file '${item.title}${indexNumber}${extensions[index]}'`))
})
})
return names.join('\n')