diff --git a/bilibili-evolved.offline.user.js b/bilibili-evolved.offline.user.js
index db8059c0c..810bee8c6 100644
--- a/bilibili-evolved.offline.user.js
+++ b/bilibili-evolved.offline.user.js
@@ -1,6 +1,6 @@
// ==UserScript==
// @name Bilibili Evolved (Offline)
-// @version 581.21
+// @version 581.26
// @description Bilibili Evolved 的离线版, 所有功能都已内置于脚本中.
// @author Grant Howard, Coulomb-G
// @copyright 2020, Grant Howard (https://github.com/the1812) & Coulomb-G (https://github.com/Coulomb-G)
@@ -1207,7 +1207,7 @@ offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/m
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-subtitle.min.js"] = (()=>{return(t,e)=>{let i;const o=(t,e)=>{const o=document.createElement("a");const n=URL.createObjectURL(new Blob([t]));if(i){URL.revokeObjectURL(i)}i=n;o.setAttribute("href",n);o.setAttribute("download",escapeFilename(e));document.body.appendChild(o);o.click();o.remove()};return{widget:{content:`\n`,condition:videoCondition,success:()=>{const t=dq("#download-subtitle");t.addEventListener("click",async i=>{try{t.disabled=true;const{aid:n,cid:s}=unsafeWindow;if(!n||!s){logError("未找到视频AID和CID");return}const{VideoInfo:l}=await e.importAsync("video-info");const{getFriendlyTitle:c}=await e.importAsync("title");const r=new l(n);r.cid=parseInt(s);await r.fetchInfo();const a=r.subtitles;if(a.length===0){Toast.info("当前视频没有字幕.","下载字幕",3e3);return}const d=await loadSubtitleSettingsPanel();if(!d){logError("未找到字幕设置");return}const u=d.querySelector(".bilibili-player-video-subtitle-setting-lan .bui-select-result").innerHTML;const b=a.find(t=>t.language===u)||a[0];const f=await Ajax.getJson(b.url);const p=f.body;const y=c(true);if(i.shiftKey){const{SubtitleConverter:t,SubtitleSize:i,SubtitleLocation:n}=await e.importAsync("subtitle-converter");const s=d.querySelector(".bilibili-player-video-subtitle-setting-fontsize .bui-thumb");const l=parseFloat(s.style.transform.replace(/translateX\(([\d\.]+)/,"$1"));const c={214:i.VeryLarge,163.5:i.Large,107:i.Medium,50.5:i.Small,0:i.VerySmall};const r=c[l];const a=d.querySelector(".bilibili-player-video-subtitle-setting-color .bui-select-result span:first-child");const u=a.getAttribute("style").match(/background:[ ]*(.+);/)[1];const b=d.querySelector(".bilibili-player-video-subtitle-setting-opacity .bui-bar");const f=parseFloat(b.style.transform.replace(/scaleX\(([\d\.]+)/,"$1"));const g=dq(".subtitle-position");const m={bc:n.BottomCenter,bl:n.BottomLeft,br:n.BottomRight,tc:n.TopCenter,tl:n.TopLeft,tr:n.TopRight};const h=Object.entries(m).filter(([t])=>{return g.classList.contains(`subtitle-position-${t}`)}).map(([,t])=>t).shift();const w=dq("video");const v={title:y,height:w.videoHeight,width:w.videoWidth,color:u,location:h,opacity:f,size:r};const S=new t(v);const L=await S.convertToAss(p);o(L,y+".ass")}else{o(JSON.stringify(p),y+".json")}}catch(t){logError(t)}finally{t.disabled=false}})}}}}})();
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;box-sizing:content-box;line-height:normal}.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 .size-warning-tip,.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;font-size:12px}.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;white-space:nowrap}.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;font-size:12px;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{white-space:normal;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 getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&fnver=0&fnval=16`}else{return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&otype=json&fnver=0&fnval=16`}}else{if(a){return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&otype=json`}}}return e.bind(this)}async getDashUrl(t){return(await this.getApiGenerator(true))(c.aid,c.cid,t)}async getUrl(t){return(await this.getApiGenerator())(c.aid,c.cid,t)}}class r extends o{async getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&fourk=1&fnval=16`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&otype=json&fourk=1&fnval=16`}}else{if(a){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=&otype=json`}}}return e.bind(this)}}class l extends o{constructor(t){super();this.ep=t}async getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}}else{if(a){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&ep_id=${this.ep}`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&otype=json&ep_id=${this.ep}`}}}return e.bind(this)}}const c={entity:new o,aid:"",cid:""};let d=[];let p=null;let h=null;class u{constructor(t,e,s){this.quality=t;this.internalName=e;this.displayName=s}async downloadInfo(t=false){const e=new f(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 u(t,s[e],a[e])});return i}static async filterFormats(t){if(h===null){h=await Ajax.getJsonWithCredentials("https://api.bilibili.com/x/web-interface/nav")}_.remove(t,t=>{const e=t.quality;if(!h.isLogin){return e>=64}if(h.vipStatus!==1){return e===116||e===112||e===74}return false});return t}static async getAvailableDashFormats(){const t=await c.entity.getDashUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}const s=e.data||e.result||e;return await u.filterFormats(u.parseFormats(s))}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 await u.filterFormats(u.parseFormats(s))}}class f{constructor(t,e){this.fragmentSplitFactor=6*2;this.workingXhr=null;this.progressMap=new Map;this.format=t;this.fragments=e||[];this.videoSpeed=new m(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(t=false){if(!t){const t=await c.entity.getUrl(this.format.quality);const s=await Ajax.getTextWithCredentials(t);const a=JSON.parse(s.replace(/http:/g,"https:"));const i=a.data||a.result||a;const n=this.format.quality;if(i.quality!==n){const{throwQualityError:t}=await e.importAsync("quality-errors");t(n)}const o=i.durl;this.fragments=o.map(t=>{return{length:t.length,size:t.size,url:t.url,backupUrls:t.backup_url}})}else{const{dashToFragments:t,getDashInfo:s}=await e.importAsync("video-dash");const a=await s(await c.entity.getDashUrl(this.format.quality),this.format.quality);this.fragments=t(a)}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 m{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 w(){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 u.getAvailableFormats()}catch(t){return false}return true}const g=e=>{const s=t.downloadVideoQuality;const a=e.find(t=>t.quality===s);if(a){return a}const i=e.filter(t=>t.quality{const t=dq(".download-video");t.classList.toggle("opened");window.scroll(0,0);dq(".gui-settings-mask").click()});document.body.insertAdjacentHTML("beforeend",e.import("downloadVideoHtml"));b()}async function b(){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");const e=t.downloadVideoFormat=this.dashModel.value;let s=[];if(e==="flv"){s=await u.getAvailableFormats()}else{s=await u.getAvailableDashFormats()}d=s;p=g(d);this.qualityModel.items=s.map(t=>t.displayName);this.qualityModel.value=this.qualityModel.items[d.indexOf(p)];await this.formatChange()},async formatChange(e=false){console.log("format change");const s=this.getFormat();if(e){t.downloadVideoQuality=s.quality}try{this.size="获取大小中";const t=await s.downloadInfo(this.dash);this.size=t.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.batchExtractor;const l=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(r.formatTitle(t.titleParameters)+".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(r.formatTitle(e.titleParameters)+".ass",await t(a.rawXML))}}await s.emit(this.cid+".danmakus.zip")}catch(t){logError(`弹幕下载失败`);throw t}finally{t.dismiss()}}const d=Toast.info("获取链接中...","批量导出");r.config.itemFilter=o;r.config.api=await c.entity.getApiGenerator(this.dash);let p;try{switch(t){case"aria2":p=await r.collectAria2(l,d,false);await n.single(s(false)+".txt",new Blob([p],{type:"text/plain"}),{ffmpeg:this.ffmpegOption});return;case"aria2RPC":await r.collectAria2(l,d,true);Toast.success(`成功发送了批量请求.`,"aria2 RPC",3e3);return;case"copyVLD":GM.setClipboard(await r.collectData(l,d),{mimetype:"text/plain"});Toast.success("已复制批量vld数据到剪贴板.","批量导出",3e3);return;case"exportVLD":p=await r.collectData(l,d);await n.single(s(false)+".json",new Blob([p],{type:"text/json"}),{ffmpeg:this.ffmpegOption});return;case"ffmpegFragments":{const t=await r.getRawItems(l);const a=new f(l,t[0].fragments);const{getBatchFragmentsList:i}=await e.importAsync("ffmpeg-support");const o=i(t,this.dash||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 r.getRawItems(l);const s=new f(l,t[0].fragments);const{getBatchEpisodesList:a}=await e.importAsync("ffmpeg-support");const i=a(t,this.dash||s.extension());const o=new n;o.add("ffmpeg-files.txt",i);await o.emit()}break;default:return}}catch(t){logError(t)}finally{d.dismiss()}},async checkBatch(){const t=["//www.bilibili.com/bangumi","//www.bilibili.com/video/av","//www.bilibili.com/blackboard/bnj2020.html"];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,titleParameters:t.titleParameters,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 w();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:w,success:y}}}})();
+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 getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&fnver=0&fnval=16`}else{return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&otype=json&fnver=0&fnval=16`}}else{if(a){return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&otype=json`}}}return e.bind(this)}async getDashUrl(t){return(await this.getApiGenerator(true))(c.aid,c.cid,t)}async getUrl(t){return(await this.getApiGenerator())(c.aid,c.cid,t)}}class r extends o{async getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&fourk=1&fnval=16`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&otype=json&fourk=1&fnval=16`}}else{if(a){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=&otype=json`}}}return e.bind(this)}}class l extends o{constructor(t){super();this.ep=t}async getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}}else{if(a){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&ep_id=${this.ep}`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&otype=json&ep_id=${this.ep}`}}}return e.bind(this)}}const c={entity:new o,aid:"",cid:""};let d=[];let p=null;let h=null;class u{constructor(t,e,s){this.quality=t;this.internalName=e;this.displayName=s}async downloadInfo(t=false){const e=new f(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 u(t,s[e],a[e])});return i}static async filterFormats(t){if(h===null){h=(await Ajax.getJsonWithCredentials("https://api.bilibili.com/x/web-interface/nav")).data}_.remove(t,t=>{const e=t.quality;if(h.isLogin===false){return e>=64}if(h.vipStatus!==1){return e===116||e===112||e===74}return false});return t}static async getAvailableDashFormats(){const t=await c.entity.getDashUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}const s=e.data||e.result||e;return await u.filterFormats(u.parseFormats(s))}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 await u.filterFormats(u.parseFormats(s))}}class f{constructor(t,e){this.fragmentSplitFactor=6*2;this.workingXhr=null;this.progressMap=new Map;this.format=t;this.fragments=e||[];this.videoSpeed=new m(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(t=false){if(!t){const t=await c.entity.getUrl(this.format.quality);const s=await Ajax.getTextWithCredentials(t);const a=JSON.parse(s.replace(/http:/g,"https:"));const i=a.data||a.result||a;const n=this.format.quality;if(i.quality!==n){const{throwQualityError:t}=await e.importAsync("quality-errors");t(n)}const o=i.durl;this.fragments=o.map(t=>{return{length:t.length,size:t.size,url:t.url,backupUrls:t.backup_url}})}else{const{dashToFragments:t,getDashInfo:s}=await e.importAsync("video-dash");const a=await s(await c.entity.getDashUrl(this.format.quality),this.format.quality);this.fragments=t(a)}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 m{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 w(){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 u.getAvailableFormats()}catch(t){return false}return true}const g=e=>{const s=t.downloadVideoQuality;const a=e.find(t=>t.quality===s);if(a){return a}const i=e.filter(t=>t.quality{const t=dq(".download-video");t.classList.toggle("opened");window.scroll(0,0);dq(".gui-settings-mask").click()});document.body.insertAdjacentHTML("beforeend",e.import("downloadVideoHtml"));b()}async function b(){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");const e=t.downloadVideoFormat=this.dashModel.value;let s=[];if(e==="flv"){s=await u.getAvailableFormats()}else{s=await u.getAvailableDashFormats()}d=s;p=g(d);this.qualityModel.items=s.map(t=>t.displayName);this.qualityModel.value=this.qualityModel.items[d.indexOf(p)];await this.formatChange()},async formatChange(e=false){console.log("format change");const s=this.getFormat();if(e){t.downloadVideoQuality=s.quality}try{this.size="获取大小中";const t=await s.downloadInfo(this.dash);this.size=t.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.batchExtractor;const l=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(r.formatTitle(t.titleParameters)+".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(r.formatTitle(e.titleParameters)+".ass",await t(a.rawXML))}}await s.emit(this.cid+".danmakus.zip")}catch(t){logError(`弹幕下载失败`);throw t}finally{t.dismiss()}}const d=Toast.info("获取链接中...","批量导出");r.config.itemFilter=o;r.config.api=await c.entity.getApiGenerator(this.dash);let p;try{switch(t){case"aria2":p=await r.collectAria2(l,d,false);await n.single(s(false)+".txt",new Blob([p],{type:"text/plain"}),{ffmpeg:this.ffmpegOption});return;case"aria2RPC":await r.collectAria2(l,d,true);Toast.success(`成功发送了批量请求.`,"aria2 RPC",3e3);return;case"copyVLD":GM.setClipboard(await r.collectData(l,d),{mimetype:"text/plain"});Toast.success("已复制批量vld数据到剪贴板.","批量导出",3e3);return;case"exportVLD":p=await r.collectData(l,d);await n.single(s(false)+".json",new Blob([p],{type:"text/json"}),{ffmpeg:this.ffmpegOption});return;case"ffmpegFragments":{const t=await r.getRawItems(l);const a=new f(l,t[0].fragments);const{getBatchFragmentsList:i}=await e.importAsync("ffmpeg-support");const o=i(t,this.dash||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 r.getRawItems(l);const s=new f(l,t[0].fragments);const{getBatchEpisodesList:a}=await e.importAsync("ffmpeg-support");const i=a(t,this.dash||s.extension());const o=new n;o.add("ffmpeg-files.txt",i);await o.emit()}break;default:return}}catch(t){logError(t)}finally{d.dismiss()}},async checkBatch(){const t=["//www.bilibili.com/bangumi","//www.bilibili.com/video/av","//www.bilibili.com/blackboard/bnj2020.html"];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,titleParameters:t.titleParameters,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 w();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:w,success:y}}}})();
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/dpi-img.vue.min.js"] = (()=>{return(t,e)=>{const s=`
`;return{export:Object.assign({template:s},{props:{size:[Object,Number],src:String,blur:Number,root:HTMLElement,rootMargin:String,threshold:Number,placeholderImage:Boolean},data(){return{srcset:null,actualSrc:null,isPlaceholderActive:false}},watch:{size(){this.sourceChange()},src(){this.sourceChange()}},methods:{sourceChange(){if(this.actualSrc===null||this.srcset===null){return}this.calcSrc()},calcSrc(){const t=!this.src||!this.size;this.isPlaceholderActive=t&&this.placeholderImage;if(t){this.srcset=null;if(this.placeholderImage){this.actualSrc=`https://s1.hdslb.com/bfs/static/blive/live-web-center/static/img/no-cover.1ebe4d5.jpg`}else{this.actualSrc=null}return}let e=this.src;if(e.startsWith("http:")){e=e.replace("http:","https:")}if(e.includes("//static.hdslb.com/images/member/noface.gif")){this.srcset=e;this.actualSrc=e;return}const s=e.substring(e.lastIndexOf(".")+1);this.srcset=getDpiSourceSet(e,this.size,s);this.actualSrc=e}},mounted(){const t={root:this.root,rootMargin:this.rootMargin||"200px",threshold:this.threshold};const e=new IntersectionObserver(t=>{t.forEach(t=>{if(t.isIntersecting){this.calcSrc();e.disconnect()}})},t);e.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},filter(){const t=[];if(this.blur){t.push(`blur(${this.blur}px)`)}return t.join(" ")}}})}}})();
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()}})}})();
diff --git a/bilibili-evolved.preview-offline.user.js b/bilibili-evolved.preview-offline.user.js
index bb525fd09..939a94c30 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 581.21
+// @version 581.26
// @description Bilibili Evolved 的预览离线版, 可以抢先体验新功能, 并且所有功能都已内置于脚本中.
// @author Grant Howard, Coulomb-G
// @copyright 2020, Grant Howard (https://github.com/the1812) & Coulomb-G (https://github.com/Coulomb-G)
@@ -1207,7 +1207,7 @@ offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/m
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-subtitle.min.js"] = (()=>{return(t,e)=>{let i;const o=(t,e)=>{const o=document.createElement("a");const n=URL.createObjectURL(new Blob([t]));if(i){URL.revokeObjectURL(i)}i=n;o.setAttribute("href",n);o.setAttribute("download",escapeFilename(e));document.body.appendChild(o);o.click();o.remove()};return{widget:{content:`\n`,condition:videoCondition,success:()=>{const t=dq("#download-subtitle");t.addEventListener("click",async i=>{try{t.disabled=true;const{aid:n,cid:s}=unsafeWindow;if(!n||!s){logError("未找到视频AID和CID");return}const{VideoInfo:l}=await e.importAsync("video-info");const{getFriendlyTitle:c}=await e.importAsync("title");const r=new l(n);r.cid=parseInt(s);await r.fetchInfo();const a=r.subtitles;if(a.length===0){Toast.info("当前视频没有字幕.","下载字幕",3e3);return}const d=await loadSubtitleSettingsPanel();if(!d){logError("未找到字幕设置");return}const u=d.querySelector(".bilibili-player-video-subtitle-setting-lan .bui-select-result").innerHTML;const b=a.find(t=>t.language===u)||a[0];const f=await Ajax.getJson(b.url);const p=f.body;const y=c(true);if(i.shiftKey){const{SubtitleConverter:t,SubtitleSize:i,SubtitleLocation:n}=await e.importAsync("subtitle-converter");const s=d.querySelector(".bilibili-player-video-subtitle-setting-fontsize .bui-thumb");const l=parseFloat(s.style.transform.replace(/translateX\(([\d\.]+)/,"$1"));const c={214:i.VeryLarge,163.5:i.Large,107:i.Medium,50.5:i.Small,0:i.VerySmall};const r=c[l];const a=d.querySelector(".bilibili-player-video-subtitle-setting-color .bui-select-result span:first-child");const u=a.getAttribute("style").match(/background:[ ]*(.+);/)[1];const b=d.querySelector(".bilibili-player-video-subtitle-setting-opacity .bui-bar");const f=parseFloat(b.style.transform.replace(/scaleX\(([\d\.]+)/,"$1"));const g=dq(".subtitle-position");const m={bc:n.BottomCenter,bl:n.BottomLeft,br:n.BottomRight,tc:n.TopCenter,tl:n.TopLeft,tr:n.TopRight};const h=Object.entries(m).filter(([t])=>{return g.classList.contains(`subtitle-position-${t}`)}).map(([,t])=>t).shift();const w=dq("video");const v={title:y,height:w.videoHeight,width:w.videoWidth,color:u,location:h,opacity:f,size:r};const S=new t(v);const L=await S.convertToAss(p);o(L,y+".ass")}else{o(JSON.stringify(p),y+".json")}}catch(t){logError(t)}finally{t.disabled=false}})}}}}})();
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;box-sizing:content-box;line-height:normal}.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 .size-warning-tip,.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;font-size:12px}.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;white-space:nowrap}.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;font-size:12px;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{white-space:normal;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 getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&fnver=0&fnval=16`}else{return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&otype=json&fnver=0&fnval=16`}}else{if(a){return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&otype=json`}}}return e.bind(this)}async getDashUrl(t){return(await this.getApiGenerator(true))(c.aid,c.cid,t)}async getUrl(t){return(await this.getApiGenerator())(c.aid,c.cid,t)}}class r extends o{async getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&fourk=1&fnval=16`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&otype=json&fourk=1&fnval=16`}}else{if(a){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=&otype=json`}}}return e.bind(this)}}class l extends o{constructor(t){super();this.ep=t}async getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}}else{if(a){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&ep_id=${this.ep}`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&otype=json&ep_id=${this.ep}`}}}return e.bind(this)}}const c={entity:new o,aid:"",cid:""};let d=[];let p=null;let h=null;class u{constructor(t,e,s){this.quality=t;this.internalName=e;this.displayName=s}async downloadInfo(t=false){const e=new f(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 u(t,s[e],a[e])});return i}static async filterFormats(t){if(h===null){h=await Ajax.getJsonWithCredentials("https://api.bilibili.com/x/web-interface/nav")}_.remove(t,t=>{const e=t.quality;if(!h.isLogin){return e>=64}if(h.vipStatus!==1){return e===116||e===112||e===74}return false});return t}static async getAvailableDashFormats(){const t=await c.entity.getDashUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}const s=e.data||e.result||e;return await u.filterFormats(u.parseFormats(s))}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 await u.filterFormats(u.parseFormats(s))}}class f{constructor(t,e){this.fragmentSplitFactor=6*2;this.workingXhr=null;this.progressMap=new Map;this.format=t;this.fragments=e||[];this.videoSpeed=new m(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(t=false){if(!t){const t=await c.entity.getUrl(this.format.quality);const s=await Ajax.getTextWithCredentials(t);const a=JSON.parse(s.replace(/http:/g,"https:"));const i=a.data||a.result||a;const n=this.format.quality;if(i.quality!==n){const{throwQualityError:t}=await e.importAsync("quality-errors");t(n)}const o=i.durl;this.fragments=o.map(t=>{return{length:t.length,size:t.size,url:t.url,backupUrls:t.backup_url}})}else{const{dashToFragments:t,getDashInfo:s}=await e.importAsync("video-dash");const a=await s(await c.entity.getDashUrl(this.format.quality),this.format.quality);this.fragments=t(a)}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 m{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 w(){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 u.getAvailableFormats()}catch(t){return false}return true}const g=e=>{const s=t.downloadVideoQuality;const a=e.find(t=>t.quality===s);if(a){return a}const i=e.filter(t=>t.quality{const t=dq(".download-video");t.classList.toggle("opened");window.scroll(0,0);dq(".gui-settings-mask").click()});document.body.insertAdjacentHTML("beforeend",e.import("downloadVideoHtml"));b()}async function b(){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");const e=t.downloadVideoFormat=this.dashModel.value;let s=[];if(e==="flv"){s=await u.getAvailableFormats()}else{s=await u.getAvailableDashFormats()}d=s;p=g(d);this.qualityModel.items=s.map(t=>t.displayName);this.qualityModel.value=this.qualityModel.items[d.indexOf(p)];await this.formatChange()},async formatChange(e=false){console.log("format change");const s=this.getFormat();if(e){t.downloadVideoQuality=s.quality}try{this.size="获取大小中";const t=await s.downloadInfo(this.dash);this.size=t.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.batchExtractor;const l=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(r.formatTitle(t.titleParameters)+".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(r.formatTitle(e.titleParameters)+".ass",await t(a.rawXML))}}await s.emit(this.cid+".danmakus.zip")}catch(t){logError(`弹幕下载失败`);throw t}finally{t.dismiss()}}const d=Toast.info("获取链接中...","批量导出");r.config.itemFilter=o;r.config.api=await c.entity.getApiGenerator(this.dash);let p;try{switch(t){case"aria2":p=await r.collectAria2(l,d,false);await n.single(s(false)+".txt",new Blob([p],{type:"text/plain"}),{ffmpeg:this.ffmpegOption});return;case"aria2RPC":await r.collectAria2(l,d,true);Toast.success(`成功发送了批量请求.`,"aria2 RPC",3e3);return;case"copyVLD":GM.setClipboard(await r.collectData(l,d),{mimetype:"text/plain"});Toast.success("已复制批量vld数据到剪贴板.","批量导出",3e3);return;case"exportVLD":p=await r.collectData(l,d);await n.single(s(false)+".json",new Blob([p],{type:"text/json"}),{ffmpeg:this.ffmpegOption});return;case"ffmpegFragments":{const t=await r.getRawItems(l);const a=new f(l,t[0].fragments);const{getBatchFragmentsList:i}=await e.importAsync("ffmpeg-support");const o=i(t,this.dash||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 r.getRawItems(l);const s=new f(l,t[0].fragments);const{getBatchEpisodesList:a}=await e.importAsync("ffmpeg-support");const i=a(t,this.dash||s.extension());const o=new n;o.add("ffmpeg-files.txt",i);await o.emit()}break;default:return}}catch(t){logError(t)}finally{d.dismiss()}},async checkBatch(){const t=["//www.bilibili.com/bangumi","//www.bilibili.com/video/av","//www.bilibili.com/blackboard/bnj2020.html"];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,titleParameters:t.titleParameters,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 w();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:w,success:y}}}})();
+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 getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&fnver=0&fnval=16`}else{return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&otype=json&fnver=0&fnval=16`}}else{if(a){return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&otype=json`}}}return e.bind(this)}async getDashUrl(t){return(await this.getApiGenerator(true))(c.aid,c.cid,t)}async getUrl(t){return(await this.getApiGenerator())(c.aid,c.cid,t)}}class r extends o{async getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&fourk=1&fnval=16`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&otype=json&fourk=1&fnval=16`}}else{if(a){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=&otype=json`}}}return e.bind(this)}}class l extends o{constructor(t){super();this.ep=t}async getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}}else{if(a){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&ep_id=${this.ep}`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&otype=json&ep_id=${this.ep}`}}}return e.bind(this)}}const c={entity:new o,aid:"",cid:""};let d=[];let p=null;let h=null;class u{constructor(t,e,s){this.quality=t;this.internalName=e;this.displayName=s}async downloadInfo(t=false){const e=new f(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 u(t,s[e],a[e])});return i}static async filterFormats(t){if(h===null){h=(await Ajax.getJsonWithCredentials("https://api.bilibili.com/x/web-interface/nav")).data}_.remove(t,t=>{const e=t.quality;if(h.isLogin===false){return e>=64}if(h.vipStatus!==1){return e===116||e===112||e===74}return false});return t}static async getAvailableDashFormats(){const t=await c.entity.getDashUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}const s=e.data||e.result||e;return await u.filterFormats(u.parseFormats(s))}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 await u.filterFormats(u.parseFormats(s))}}class f{constructor(t,e){this.fragmentSplitFactor=6*2;this.workingXhr=null;this.progressMap=new Map;this.format=t;this.fragments=e||[];this.videoSpeed=new m(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(t=false){if(!t){const t=await c.entity.getUrl(this.format.quality);const s=await Ajax.getTextWithCredentials(t);const a=JSON.parse(s.replace(/http:/g,"https:"));const i=a.data||a.result||a;const n=this.format.quality;if(i.quality!==n){const{throwQualityError:t}=await e.importAsync("quality-errors");t(n)}const o=i.durl;this.fragments=o.map(t=>{return{length:t.length,size:t.size,url:t.url,backupUrls:t.backup_url}})}else{const{dashToFragments:t,getDashInfo:s}=await e.importAsync("video-dash");const a=await s(await c.entity.getDashUrl(this.format.quality),this.format.quality);this.fragments=t(a)}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 m{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 w(){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 u.getAvailableFormats()}catch(t){return false}return true}const g=e=>{const s=t.downloadVideoQuality;const a=e.find(t=>t.quality===s);if(a){return a}const i=e.filter(t=>t.quality{const t=dq(".download-video");t.classList.toggle("opened");window.scroll(0,0);dq(".gui-settings-mask").click()});document.body.insertAdjacentHTML("beforeend",e.import("downloadVideoHtml"));b()}async function b(){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");const e=t.downloadVideoFormat=this.dashModel.value;let s=[];if(e==="flv"){s=await u.getAvailableFormats()}else{s=await u.getAvailableDashFormats()}d=s;p=g(d);this.qualityModel.items=s.map(t=>t.displayName);this.qualityModel.value=this.qualityModel.items[d.indexOf(p)];await this.formatChange()},async formatChange(e=false){console.log("format change");const s=this.getFormat();if(e){t.downloadVideoQuality=s.quality}try{this.size="获取大小中";const t=await s.downloadInfo(this.dash);this.size=t.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.batchExtractor;const l=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(r.formatTitle(t.titleParameters)+".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(r.formatTitle(e.titleParameters)+".ass",await t(a.rawXML))}}await s.emit(this.cid+".danmakus.zip")}catch(t){logError(`弹幕下载失败`);throw t}finally{t.dismiss()}}const d=Toast.info("获取链接中...","批量导出");r.config.itemFilter=o;r.config.api=await c.entity.getApiGenerator(this.dash);let p;try{switch(t){case"aria2":p=await r.collectAria2(l,d,false);await n.single(s(false)+".txt",new Blob([p],{type:"text/plain"}),{ffmpeg:this.ffmpegOption});return;case"aria2RPC":await r.collectAria2(l,d,true);Toast.success(`成功发送了批量请求.`,"aria2 RPC",3e3);return;case"copyVLD":GM.setClipboard(await r.collectData(l,d),{mimetype:"text/plain"});Toast.success("已复制批量vld数据到剪贴板.","批量导出",3e3);return;case"exportVLD":p=await r.collectData(l,d);await n.single(s(false)+".json",new Blob([p],{type:"text/json"}),{ffmpeg:this.ffmpegOption});return;case"ffmpegFragments":{const t=await r.getRawItems(l);const a=new f(l,t[0].fragments);const{getBatchFragmentsList:i}=await e.importAsync("ffmpeg-support");const o=i(t,this.dash||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 r.getRawItems(l);const s=new f(l,t[0].fragments);const{getBatchEpisodesList:a}=await e.importAsync("ffmpeg-support");const i=a(t,this.dash||s.extension());const o=new n;o.add("ffmpeg-files.txt",i);await o.emit()}break;default:return}}catch(t){logError(t)}finally{d.dismiss()}},async checkBatch(){const t=["//www.bilibili.com/bangumi","//www.bilibili.com/video/av","//www.bilibili.com/blackboard/bnj2020.html"];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,titleParameters:t.titleParameters,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 w();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:w,success:y}}}})();
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/dpi-img.vue.min.js"] = (()=>{return(t,e)=>{const s=`
`;return{export:Object.assign({template:s},{props:{size:[Object,Number],src:String,blur:Number,root:HTMLElement,rootMargin:String,threshold:Number,placeholderImage:Boolean},data(){return{srcset:null,actualSrc:null,isPlaceholderActive:false}},watch:{size(){this.sourceChange()},src(){this.sourceChange()}},methods:{sourceChange(){if(this.actualSrc===null||this.srcset===null){return}this.calcSrc()},calcSrc(){const t=!this.src||!this.size;this.isPlaceholderActive=t&&this.placeholderImage;if(t){this.srcset=null;if(this.placeholderImage){this.actualSrc=`https://s1.hdslb.com/bfs/static/blive/live-web-center/static/img/no-cover.1ebe4d5.jpg`}else{this.actualSrc=null}return}let e=this.src;if(e.startsWith("http:")){e=e.replace("http:","https:")}if(e.includes("//static.hdslb.com/images/member/noface.gif")){this.srcset=e;this.actualSrc=e;return}const s=e.substring(e.lastIndexOf(".")+1);this.srcset=getDpiSourceSet(e,this.size,s);this.actualSrc=e}},mounted(){const t={root:this.root,rootMargin:this.rootMargin||"200px",threshold:this.threshold};const e=new IntersectionObserver(t=>{t.forEach(t=>{if(t.isIntersecting){this.calcSrc();e.disconnect()}})},t);e.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},filter(){const t=[];if(this.blur){t.push(`blur(${this.blur}px)`)}return t.join(" ")}}})}}})();
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()}})}})();
diff --git a/bilibili-evolved.preview.user.js b/bilibili-evolved.preview.user.js
index d2f714435..94396ea2d 100644
--- a/bilibili-evolved.preview.user.js
+++ b/bilibili-evolved.preview.user.js
@@ -1206,7 +1206,7 @@ onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/m
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/min/download-subtitle.min.js"] = (()=>{return(t,e)=>{let i;const o=(t,e)=>{const o=document.createElement("a");const n=URL.createObjectURL(new Blob([t]));if(i){URL.revokeObjectURL(i)}i=n;o.setAttribute("href",n);o.setAttribute("download",escapeFilename(e));document.body.appendChild(o);o.click();o.remove()};return{widget:{content:`\n`,condition:videoCondition,success:()=>{const t=dq("#download-subtitle");t.addEventListener("click",async i=>{try{t.disabled=true;const{aid:n,cid:s}=unsafeWindow;if(!n||!s){logError("未找到视频AID和CID");return}const{VideoInfo:l}=await e.importAsync("video-info");const{getFriendlyTitle:c}=await e.importAsync("title");const r=new l(n);r.cid=parseInt(s);await r.fetchInfo();const a=r.subtitles;if(a.length===0){Toast.info("当前视频没有字幕.","下载字幕",3e3);return}const d=await loadSubtitleSettingsPanel();if(!d){logError("未找到字幕设置");return}const u=d.querySelector(".bilibili-player-video-subtitle-setting-lan .bui-select-result").innerHTML;const b=a.find(t=>t.language===u)||a[0];const f=await Ajax.getJson(b.url);const p=f.body;const y=c(true);if(i.shiftKey){const{SubtitleConverter:t,SubtitleSize:i,SubtitleLocation:n}=await e.importAsync("subtitle-converter");const s=d.querySelector(".bilibili-player-video-subtitle-setting-fontsize .bui-thumb");const l=parseFloat(s.style.transform.replace(/translateX\(([\d\.]+)/,"$1"));const c={214:i.VeryLarge,163.5:i.Large,107:i.Medium,50.5:i.Small,0:i.VerySmall};const r=c[l];const a=d.querySelector(".bilibili-player-video-subtitle-setting-color .bui-select-result span:first-child");const u=a.getAttribute("style").match(/background:[ ]*(.+);/)[1];const b=d.querySelector(".bilibili-player-video-subtitle-setting-opacity .bui-bar");const f=parseFloat(b.style.transform.replace(/scaleX\(([\d\.]+)/,"$1"));const g=dq(".subtitle-position");const m={bc:n.BottomCenter,bl:n.BottomLeft,br:n.BottomRight,tc:n.TopCenter,tl:n.TopLeft,tr:n.TopRight};const h=Object.entries(m).filter(([t])=>{return g.classList.contains(`subtitle-position-${t}`)}).map(([,t])=>t).shift();const w=dq("video");const v={title:y,height:w.videoHeight,width:w.videoWidth,color:u,location:h,opacity:f,size:r};const S=new t(v);const L=await S.convertToAss(p);o(L,y+".ass")}else{o(JSON.stringify(p),y+".json")}}catch(t){logError(t)}finally{t.disabled=false}})}}}}})();
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;box-sizing:content-box;line-height:normal}.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 .size-warning-tip,.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;font-size:12px}.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;white-space:nowrap}.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;font-size:12px;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{white-space:normal;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 getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&fnver=0&fnval=16`}else{return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&otype=json&fnver=0&fnval=16`}}else{if(a){return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&otype=json`}}}return e.bind(this)}async getDashUrl(t){return(await this.getApiGenerator(true))(c.aid,c.cid,t)}async getUrl(t){return(await this.getApiGenerator())(c.aid,c.cid,t)}}class r extends o{async getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&fourk=1&fnval=16`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&otype=json&fourk=1&fnval=16`}}else{if(a){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=&otype=json`}}}return e.bind(this)}}class l extends o{constructor(t){super();this.ep=t}async getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}}else{if(a){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&ep_id=${this.ep}`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&otype=json&ep_id=${this.ep}`}}}return e.bind(this)}}const c={entity:new o,aid:"",cid:""};let d=[];let p=null;let h=null;class u{constructor(t,e,s){this.quality=t;this.internalName=e;this.displayName=s}async downloadInfo(t=false){const e=new f(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 u(t,s[e],a[e])});return i}static async filterFormats(t){if(h===null){h=await Ajax.getJsonWithCredentials("https://api.bilibili.com/x/web-interface/nav")}_.remove(t,t=>{const e=t.quality;if(!h.isLogin){return e>=64}if(h.vipStatus!==1){return e===116||e===112||e===74}return false});return t}static async getAvailableDashFormats(){const t=await c.entity.getDashUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}const s=e.data||e.result||e;return await u.filterFormats(u.parseFormats(s))}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 await u.filterFormats(u.parseFormats(s))}}class f{constructor(t,e){this.fragmentSplitFactor=6*2;this.workingXhr=null;this.progressMap=new Map;this.format=t;this.fragments=e||[];this.videoSpeed=new m(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(t=false){if(!t){const t=await c.entity.getUrl(this.format.quality);const s=await Ajax.getTextWithCredentials(t);const a=JSON.parse(s.replace(/http:/g,"https:"));const i=a.data||a.result||a;const n=this.format.quality;if(i.quality!==n){const{throwQualityError:t}=await e.importAsync("quality-errors");t(n)}const o=i.durl;this.fragments=o.map(t=>{return{length:t.length,size:t.size,url:t.url,backupUrls:t.backup_url}})}else{const{dashToFragments:t,getDashInfo:s}=await e.importAsync("video-dash");const a=await s(await c.entity.getDashUrl(this.format.quality),this.format.quality);this.fragments=t(a)}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 m{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 w(){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 u.getAvailableFormats()}catch(t){return false}return true}const g=e=>{const s=t.downloadVideoQuality;const a=e.find(t=>t.quality===s);if(a){return a}const i=e.filter(t=>t.quality{const t=dq(".download-video");t.classList.toggle("opened");window.scroll(0,0);dq(".gui-settings-mask").click()});document.body.insertAdjacentHTML("beforeend",e.import("downloadVideoHtml"));b()}async function b(){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");const e=t.downloadVideoFormat=this.dashModel.value;let s=[];if(e==="flv"){s=await u.getAvailableFormats()}else{s=await u.getAvailableDashFormats()}d=s;p=g(d);this.qualityModel.items=s.map(t=>t.displayName);this.qualityModel.value=this.qualityModel.items[d.indexOf(p)];await this.formatChange()},async formatChange(e=false){console.log("format change");const s=this.getFormat();if(e){t.downloadVideoQuality=s.quality}try{this.size="获取大小中";const t=await s.downloadInfo(this.dash);this.size=t.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.batchExtractor;const l=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(r.formatTitle(t.titleParameters)+".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(r.formatTitle(e.titleParameters)+".ass",await t(a.rawXML))}}await s.emit(this.cid+".danmakus.zip")}catch(t){logError(`弹幕下载失败`);throw t}finally{t.dismiss()}}const d=Toast.info("获取链接中...","批量导出");r.config.itemFilter=o;r.config.api=await c.entity.getApiGenerator(this.dash);let p;try{switch(t){case"aria2":p=await r.collectAria2(l,d,false);await n.single(s(false)+".txt",new Blob([p],{type:"text/plain"}),{ffmpeg:this.ffmpegOption});return;case"aria2RPC":await r.collectAria2(l,d,true);Toast.success(`成功发送了批量请求.`,"aria2 RPC",3e3);return;case"copyVLD":GM.setClipboard(await r.collectData(l,d),{mimetype:"text/plain"});Toast.success("已复制批量vld数据到剪贴板.","批量导出",3e3);return;case"exportVLD":p=await r.collectData(l,d);await n.single(s(false)+".json",new Blob([p],{type:"text/json"}),{ffmpeg:this.ffmpegOption});return;case"ffmpegFragments":{const t=await r.getRawItems(l);const a=new f(l,t[0].fragments);const{getBatchFragmentsList:i}=await e.importAsync("ffmpeg-support");const o=i(t,this.dash||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 r.getRawItems(l);const s=new f(l,t[0].fragments);const{getBatchEpisodesList:a}=await e.importAsync("ffmpeg-support");const i=a(t,this.dash||s.extension());const o=new n;o.add("ffmpeg-files.txt",i);await o.emit()}break;default:return}}catch(t){logError(t)}finally{d.dismiss()}},async checkBatch(){const t=["//www.bilibili.com/bangumi","//www.bilibili.com/video/av","//www.bilibili.com/blackboard/bnj2020.html"];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,titleParameters:t.titleParameters,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 w();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:w,success:y}}}})();
+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 getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&fnver=0&fnval=16`}else{return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&otype=json&fnver=0&fnval=16`}}else{if(a){return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&otype=json`}}}return e.bind(this)}async getDashUrl(t){return(await this.getApiGenerator(true))(c.aid,c.cid,t)}async getUrl(t){return(await this.getApiGenerator())(c.aid,c.cid,t)}}class r extends o{async getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&fourk=1&fnval=16`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&otype=json&fourk=1&fnval=16`}}else{if(a){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=&otype=json`}}}return e.bind(this)}}class l extends o{constructor(t){super();this.ep=t}async getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}}else{if(a){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&ep_id=${this.ep}`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&otype=json&ep_id=${this.ep}`}}}return e.bind(this)}}const c={entity:new o,aid:"",cid:""};let d=[];let p=null;let h=null;class u{constructor(t,e,s){this.quality=t;this.internalName=e;this.displayName=s}async downloadInfo(t=false){const e=new f(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 u(t,s[e],a[e])});return i}static async filterFormats(t){if(h===null){h=(await Ajax.getJsonWithCredentials("https://api.bilibili.com/x/web-interface/nav")).data}_.remove(t,t=>{const e=t.quality;if(h.isLogin===false){return e>=64}if(h.vipStatus!==1){return e===116||e===112||e===74}return false});return t}static async getAvailableDashFormats(){const t=await c.entity.getDashUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}const s=e.data||e.result||e;return await u.filterFormats(u.parseFormats(s))}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 await u.filterFormats(u.parseFormats(s))}}class f{constructor(t,e){this.fragmentSplitFactor=6*2;this.workingXhr=null;this.progressMap=new Map;this.format=t;this.fragments=e||[];this.videoSpeed=new m(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(t=false){if(!t){const t=await c.entity.getUrl(this.format.quality);const s=await Ajax.getTextWithCredentials(t);const a=JSON.parse(s.replace(/http:/g,"https:"));const i=a.data||a.result||a;const n=this.format.quality;if(i.quality!==n){const{throwQualityError:t}=await e.importAsync("quality-errors");t(n)}const o=i.durl;this.fragments=o.map(t=>{return{length:t.length,size:t.size,url:t.url,backupUrls:t.backup_url}})}else{const{dashToFragments:t,getDashInfo:s}=await e.importAsync("video-dash");const a=await s(await c.entity.getDashUrl(this.format.quality),this.format.quality);this.fragments=t(a)}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 m{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 w(){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 u.getAvailableFormats()}catch(t){return false}return true}const g=e=>{const s=t.downloadVideoQuality;const a=e.find(t=>t.quality===s);if(a){return a}const i=e.filter(t=>t.quality{const t=dq(".download-video");t.classList.toggle("opened");window.scroll(0,0);dq(".gui-settings-mask").click()});document.body.insertAdjacentHTML("beforeend",e.import("downloadVideoHtml"));b()}async function b(){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");const e=t.downloadVideoFormat=this.dashModel.value;let s=[];if(e==="flv"){s=await u.getAvailableFormats()}else{s=await u.getAvailableDashFormats()}d=s;p=g(d);this.qualityModel.items=s.map(t=>t.displayName);this.qualityModel.value=this.qualityModel.items[d.indexOf(p)];await this.formatChange()},async formatChange(e=false){console.log("format change");const s=this.getFormat();if(e){t.downloadVideoQuality=s.quality}try{this.size="获取大小中";const t=await s.downloadInfo(this.dash);this.size=t.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.batchExtractor;const l=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(r.formatTitle(t.titleParameters)+".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(r.formatTitle(e.titleParameters)+".ass",await t(a.rawXML))}}await s.emit(this.cid+".danmakus.zip")}catch(t){logError(`弹幕下载失败`);throw t}finally{t.dismiss()}}const d=Toast.info("获取链接中...","批量导出");r.config.itemFilter=o;r.config.api=await c.entity.getApiGenerator(this.dash);let p;try{switch(t){case"aria2":p=await r.collectAria2(l,d,false);await n.single(s(false)+".txt",new Blob([p],{type:"text/plain"}),{ffmpeg:this.ffmpegOption});return;case"aria2RPC":await r.collectAria2(l,d,true);Toast.success(`成功发送了批量请求.`,"aria2 RPC",3e3);return;case"copyVLD":GM.setClipboard(await r.collectData(l,d),{mimetype:"text/plain"});Toast.success("已复制批量vld数据到剪贴板.","批量导出",3e3);return;case"exportVLD":p=await r.collectData(l,d);await n.single(s(false)+".json",new Blob([p],{type:"text/json"}),{ffmpeg:this.ffmpegOption});return;case"ffmpegFragments":{const t=await r.getRawItems(l);const a=new f(l,t[0].fragments);const{getBatchFragmentsList:i}=await e.importAsync("ffmpeg-support");const o=i(t,this.dash||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 r.getRawItems(l);const s=new f(l,t[0].fragments);const{getBatchEpisodesList:a}=await e.importAsync("ffmpeg-support");const i=a(t,this.dash||s.extension());const o=new n;o.add("ffmpeg-files.txt",i);await o.emit()}break;default:return}}catch(t){logError(t)}finally{d.dismiss()}},async checkBatch(){const t=["//www.bilibili.com/bangumi","//www.bilibili.com/video/av","//www.bilibili.com/blackboard/bnj2020.html"];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,titleParameters:t.titleParameters,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 w();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:w,success:y}}}})();
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/dpi-img.vue.min.js"] = (()=>{return(t,e)=>{const s=`
`;return{export:Object.assign({template:s},{props:{size:[Object,Number],src:String,blur:Number,root:HTMLElement,rootMargin:String,threshold:Number,placeholderImage:Boolean},data(){return{srcset:null,actualSrc:null,isPlaceholderActive:false}},watch:{size(){this.sourceChange()},src(){this.sourceChange()}},methods:{sourceChange(){if(this.actualSrc===null||this.srcset===null){return}this.calcSrc()},calcSrc(){const t=!this.src||!this.size;this.isPlaceholderActive=t&&this.placeholderImage;if(t){this.srcset=null;if(this.placeholderImage){this.actualSrc=`https://s1.hdslb.com/bfs/static/blive/live-web-center/static/img/no-cover.1ebe4d5.jpg`}else{this.actualSrc=null}return}let e=this.src;if(e.startsWith("http:")){e=e.replace("http:","https:")}if(e.includes("//static.hdslb.com/images/member/noface.gif")){this.srcset=e;this.actualSrc=e;return}const s=e.substring(e.lastIndexOf(".")+1);this.srcset=getDpiSourceSet(e,this.size,s);this.actualSrc=e}},mounted(){const t={root:this.root,rootMargin:this.rootMargin||"200px",threshold:this.threshold};const e=new IntersectionObserver(t=>{t.forEach(t=>{if(t.isIntersecting){this.calcSrc();e.disconnect()}})},t);e.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},filter(){const t=[];if(this.blur){t.push(`blur(${this.blur}px)`)}return t.join(" ")}}})}}})();
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()}})}})();
diff --git a/bilibili-evolved.user.js b/bilibili-evolved.user.js
index 02d1cc4ca..413f413f9 100644
--- a/bilibili-evolved.user.js
+++ b/bilibili-evolved.user.js
@@ -1206,7 +1206,7 @@ onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/mi
onlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-subtitle.min.js"] = (()=>{return(t,e)=>{let i;const o=(t,e)=>{const o=document.createElement("a");const n=URL.createObjectURL(new Blob([t]));if(i){URL.revokeObjectURL(i)}i=n;o.setAttribute("href",n);o.setAttribute("download",escapeFilename(e));document.body.appendChild(o);o.click();o.remove()};return{widget:{content:`\n`,condition:videoCondition,success:()=>{const t=dq("#download-subtitle");t.addEventListener("click",async i=>{try{t.disabled=true;const{aid:n,cid:s}=unsafeWindow;if(!n||!s){logError("未找到视频AID和CID");return}const{VideoInfo:l}=await e.importAsync("video-info");const{getFriendlyTitle:c}=await e.importAsync("title");const r=new l(n);r.cid=parseInt(s);await r.fetchInfo();const a=r.subtitles;if(a.length===0){Toast.info("当前视频没有字幕.","下载字幕",3e3);return}const d=await loadSubtitleSettingsPanel();if(!d){logError("未找到字幕设置");return}const u=d.querySelector(".bilibili-player-video-subtitle-setting-lan .bui-select-result").innerHTML;const b=a.find(t=>t.language===u)||a[0];const f=await Ajax.getJson(b.url);const p=f.body;const y=c(true);if(i.shiftKey){const{SubtitleConverter:t,SubtitleSize:i,SubtitleLocation:n}=await e.importAsync("subtitle-converter");const s=d.querySelector(".bilibili-player-video-subtitle-setting-fontsize .bui-thumb");const l=parseFloat(s.style.transform.replace(/translateX\(([\d\.]+)/,"$1"));const c={214:i.VeryLarge,163.5:i.Large,107:i.Medium,50.5:i.Small,0:i.VerySmall};const r=c[l];const a=d.querySelector(".bilibili-player-video-subtitle-setting-color .bui-select-result span:first-child");const u=a.getAttribute("style").match(/background:[ ]*(.+);/)[1];const b=d.querySelector(".bilibili-player-video-subtitle-setting-opacity .bui-bar");const f=parseFloat(b.style.transform.replace(/scaleX\(([\d\.]+)/,"$1"));const g=dq(".subtitle-position");const m={bc:n.BottomCenter,bl:n.BottomLeft,br:n.BottomRight,tc:n.TopCenter,tl:n.TopLeft,tr:n.TopRight};const h=Object.entries(m).filter(([t])=>{return g.classList.contains(`subtitle-position-${t}`)}).map(([,t])=>t).shift();const w=dq("video");const v={title:y,height:w.videoHeight,width:w.videoWidth,color:u,location:h,opacity:f,size:r};const S=new t(v);const L=await S.convertToAss(p);o(L,y+".ass")}else{o(JSON.stringify(p),y+".json")}}catch(t){logError(t)}finally{t.disabled=false}})}}}}})();
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;box-sizing:content-box;line-height:normal}.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 .size-warning-tip,.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;font-size:12px}.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;white-space:nowrap}.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;font-size:12px;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{white-space:normal;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 getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&fnver=0&fnval=16`}else{return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&otype=json&fnver=0&fnval=16`}}else{if(a){return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&otype=json`}}}return e.bind(this)}async getDashUrl(t){return(await this.getApiGenerator(true))(c.aid,c.cid,t)}async getUrl(t){return(await this.getApiGenerator())(c.aid,c.cid,t)}}class r extends o{async getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&fourk=1&fnval=16`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&otype=json&fourk=1&fnval=16`}}else{if(a){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=&otype=json`}}}return e.bind(this)}}class l extends o{constructor(t){super();this.ep=t}async getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}}else{if(a){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&ep_id=${this.ep}`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&otype=json&ep_id=${this.ep}`}}}return e.bind(this)}}const c={entity:new o,aid:"",cid:""};let d=[];let p=null;let h=null;class u{constructor(t,e,s){this.quality=t;this.internalName=e;this.displayName=s}async downloadInfo(t=false){const e=new f(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 u(t,s[e],a[e])});return i}static async filterFormats(t){if(h===null){h=await Ajax.getJsonWithCredentials("https://api.bilibili.com/x/web-interface/nav")}_.remove(t,t=>{const e=t.quality;if(!h.isLogin){return e>=64}if(h.vipStatus!==1){return e===116||e===112||e===74}return false});return t}static async getAvailableDashFormats(){const t=await c.entity.getDashUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}const s=e.data||e.result||e;return await u.filterFormats(u.parseFormats(s))}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 await u.filterFormats(u.parseFormats(s))}}class f{constructor(t,e){this.fragmentSplitFactor=6*2;this.workingXhr=null;this.progressMap=new Map;this.format=t;this.fragments=e||[];this.videoSpeed=new m(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(t=false){if(!t){const t=await c.entity.getUrl(this.format.quality);const s=await Ajax.getTextWithCredentials(t);const a=JSON.parse(s.replace(/http:/g,"https:"));const i=a.data||a.result||a;const n=this.format.quality;if(i.quality!==n){const{throwQualityError:t}=await e.importAsync("quality-errors");t(n)}const o=i.durl;this.fragments=o.map(t=>{return{length:t.length,size:t.size,url:t.url,backupUrls:t.backup_url}})}else{const{dashToFragments:t,getDashInfo:s}=await e.importAsync("video-dash");const a=await s(await c.entity.getDashUrl(this.format.quality),this.format.quality);this.fragments=t(a)}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 m{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 w(){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 u.getAvailableFormats()}catch(t){return false}return true}const g=e=>{const s=t.downloadVideoQuality;const a=e.find(t=>t.quality===s);if(a){return a}const i=e.filter(t=>t.quality{const t=dq(".download-video");t.classList.toggle("opened");window.scroll(0,0);dq(".gui-settings-mask").click()});document.body.insertAdjacentHTML("beforeend",e.import("downloadVideoHtml"));b()}async function b(){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");const e=t.downloadVideoFormat=this.dashModel.value;let s=[];if(e==="flv"){s=await u.getAvailableFormats()}else{s=await u.getAvailableDashFormats()}d=s;p=g(d);this.qualityModel.items=s.map(t=>t.displayName);this.qualityModel.value=this.qualityModel.items[d.indexOf(p)];await this.formatChange()},async formatChange(e=false){console.log("format change");const s=this.getFormat();if(e){t.downloadVideoQuality=s.quality}try{this.size="获取大小中";const t=await s.downloadInfo(this.dash);this.size=t.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.batchExtractor;const l=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(r.formatTitle(t.titleParameters)+".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(r.formatTitle(e.titleParameters)+".ass",await t(a.rawXML))}}await s.emit(this.cid+".danmakus.zip")}catch(t){logError(`弹幕下载失败`);throw t}finally{t.dismiss()}}const d=Toast.info("获取链接中...","批量导出");r.config.itemFilter=o;r.config.api=await c.entity.getApiGenerator(this.dash);let p;try{switch(t){case"aria2":p=await r.collectAria2(l,d,false);await n.single(s(false)+".txt",new Blob([p],{type:"text/plain"}),{ffmpeg:this.ffmpegOption});return;case"aria2RPC":await r.collectAria2(l,d,true);Toast.success(`成功发送了批量请求.`,"aria2 RPC",3e3);return;case"copyVLD":GM.setClipboard(await r.collectData(l,d),{mimetype:"text/plain"});Toast.success("已复制批量vld数据到剪贴板.","批量导出",3e3);return;case"exportVLD":p=await r.collectData(l,d);await n.single(s(false)+".json",new Blob([p],{type:"text/json"}),{ffmpeg:this.ffmpegOption});return;case"ffmpegFragments":{const t=await r.getRawItems(l);const a=new f(l,t[0].fragments);const{getBatchFragmentsList:i}=await e.importAsync("ffmpeg-support");const o=i(t,this.dash||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 r.getRawItems(l);const s=new f(l,t[0].fragments);const{getBatchEpisodesList:a}=await e.importAsync("ffmpeg-support");const i=a(t,this.dash||s.extension());const o=new n;o.add("ffmpeg-files.txt",i);await o.emit()}break;default:return}}catch(t){logError(t)}finally{d.dismiss()}},async checkBatch(){const t=["//www.bilibili.com/bangumi","//www.bilibili.com/video/av","//www.bilibili.com/blackboard/bnj2020.html"];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,titleParameters:t.titleParameters,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 w();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:w,success:y}}}})();
+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 getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&fnver=0&fnval=16`}else{return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&otype=json&fnver=0&fnval=16`}}else{if(a){return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&otype=json`}}}return e.bind(this)}async getDashUrl(t){return(await this.getApiGenerator(true))(c.aid,c.cid,t)}async getUrl(t){return(await this.getApiGenerator())(c.aid,c.cid,t)}}class r extends o{async getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&fourk=1&fnval=16`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&otype=json&fourk=1&fnval=16`}}else{if(a){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=&otype=json`}}}return e.bind(this)}}class l extends o{constructor(t){super();this.ep=t}async getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}}else{if(a){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&ep_id=${this.ep}`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&otype=json&ep_id=${this.ep}`}}}return e.bind(this)}}const c={entity:new o,aid:"",cid:""};let d=[];let p=null;let h=null;class u{constructor(t,e,s){this.quality=t;this.internalName=e;this.displayName=s}async downloadInfo(t=false){const e=new f(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 u(t,s[e],a[e])});return i}static async filterFormats(t){if(h===null){h=(await Ajax.getJsonWithCredentials("https://api.bilibili.com/x/web-interface/nav")).data}_.remove(t,t=>{const e=t.quality;if(h.isLogin===false){return e>=64}if(h.vipStatus!==1){return e===116||e===112||e===74}return false});return t}static async getAvailableDashFormats(){const t=await c.entity.getDashUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}const s=e.data||e.result||e;return await u.filterFormats(u.parseFormats(s))}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 await u.filterFormats(u.parseFormats(s))}}class f{constructor(t,e){this.fragmentSplitFactor=6*2;this.workingXhr=null;this.progressMap=new Map;this.format=t;this.fragments=e||[];this.videoSpeed=new m(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(t=false){if(!t){const t=await c.entity.getUrl(this.format.quality);const s=await Ajax.getTextWithCredentials(t);const a=JSON.parse(s.replace(/http:/g,"https:"));const i=a.data||a.result||a;const n=this.format.quality;if(i.quality!==n){const{throwQualityError:t}=await e.importAsync("quality-errors");t(n)}const o=i.durl;this.fragments=o.map(t=>{return{length:t.length,size:t.size,url:t.url,backupUrls:t.backup_url}})}else{const{dashToFragments:t,getDashInfo:s}=await e.importAsync("video-dash");const a=await s(await c.entity.getDashUrl(this.format.quality),this.format.quality);this.fragments=t(a)}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 m{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 w(){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 u.getAvailableFormats()}catch(t){return false}return true}const g=e=>{const s=t.downloadVideoQuality;const a=e.find(t=>t.quality===s);if(a){return a}const i=e.filter(t=>t.quality{const t=dq(".download-video");t.classList.toggle("opened");window.scroll(0,0);dq(".gui-settings-mask").click()});document.body.insertAdjacentHTML("beforeend",e.import("downloadVideoHtml"));b()}async function b(){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");const e=t.downloadVideoFormat=this.dashModel.value;let s=[];if(e==="flv"){s=await u.getAvailableFormats()}else{s=await u.getAvailableDashFormats()}d=s;p=g(d);this.qualityModel.items=s.map(t=>t.displayName);this.qualityModel.value=this.qualityModel.items[d.indexOf(p)];await this.formatChange()},async formatChange(e=false){console.log("format change");const s=this.getFormat();if(e){t.downloadVideoQuality=s.quality}try{this.size="获取大小中";const t=await s.downloadInfo(this.dash);this.size=t.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.batchExtractor;const l=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(r.formatTitle(t.titleParameters)+".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(r.formatTitle(e.titleParameters)+".ass",await t(a.rawXML))}}await s.emit(this.cid+".danmakus.zip")}catch(t){logError(`弹幕下载失败`);throw t}finally{t.dismiss()}}const d=Toast.info("获取链接中...","批量导出");r.config.itemFilter=o;r.config.api=await c.entity.getApiGenerator(this.dash);let p;try{switch(t){case"aria2":p=await r.collectAria2(l,d,false);await n.single(s(false)+".txt",new Blob([p],{type:"text/plain"}),{ffmpeg:this.ffmpegOption});return;case"aria2RPC":await r.collectAria2(l,d,true);Toast.success(`成功发送了批量请求.`,"aria2 RPC",3e3);return;case"copyVLD":GM.setClipboard(await r.collectData(l,d),{mimetype:"text/plain"});Toast.success("已复制批量vld数据到剪贴板.","批量导出",3e3);return;case"exportVLD":p=await r.collectData(l,d);await n.single(s(false)+".json",new Blob([p],{type:"text/json"}),{ffmpeg:this.ffmpegOption});return;case"ffmpegFragments":{const t=await r.getRawItems(l);const a=new f(l,t[0].fragments);const{getBatchFragmentsList:i}=await e.importAsync("ffmpeg-support");const o=i(t,this.dash||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 r.getRawItems(l);const s=new f(l,t[0].fragments);const{getBatchEpisodesList:a}=await e.importAsync("ffmpeg-support");const i=a(t,this.dash||s.extension());const o=new n;o.add("ffmpeg-files.txt",i);await o.emit()}break;default:return}}catch(t){logError(t)}finally{d.dismiss()}},async checkBatch(){const t=["//www.bilibili.com/bangumi","//www.bilibili.com/video/av","//www.bilibili.com/blackboard/bnj2020.html"];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,titleParameters:t.titleParameters,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 w();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:w,success:y}}}})();
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/dpi-img.vue.min.js"] = (()=>{return(t,e)=>{const s=`
`;return{export:Object.assign({template:s},{props:{size:[Object,Number],src:String,blur:Number,root:HTMLElement,rootMargin:String,threshold:Number,placeholderImage:Boolean},data(){return{srcset:null,actualSrc:null,isPlaceholderActive:false}},watch:{size(){this.sourceChange()},src(){this.sourceChange()}},methods:{sourceChange(){if(this.actualSrc===null||this.srcset===null){return}this.calcSrc()},calcSrc(){const t=!this.src||!this.size;this.isPlaceholderActive=t&&this.placeholderImage;if(t){this.srcset=null;if(this.placeholderImage){this.actualSrc=`https://s1.hdslb.com/bfs/static/blive/live-web-center/static/img/no-cover.1ebe4d5.jpg`}else{this.actualSrc=null}return}let e=this.src;if(e.startsWith("http:")){e=e.replace("http:","https:")}if(e.includes("//static.hdslb.com/images/member/noface.gif")){this.srcset=e;this.actualSrc=e;return}const s=e.substring(e.lastIndexOf(".")+1);this.srcset=getDpiSourceSet(e,this.size,s);this.actualSrc=e}},mounted(){const t={root:this.root,rootMargin:this.rootMargin||"200px",threshold:this.threshold};const e=new IntersectionObserver(t=>{t.forEach(t=>{if(t.isIntersecting){this.calcSrc();e.disconnect()}})},t);e.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},filter(){const t=[];if(this.blur){t.push(`blur(${this.blur}px)`)}return t.join(" ")}}})}}})();
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()}})}})();
diff --git a/min/bundle.json b/min/bundle.json
index 4c6761352..909cf19fa 100644
--- a/min/bundle.json
+++ b/min/bundle.json
@@ -69,7 +69,7 @@
"download-subtitle.min.js": "4B99A00FEEA40C6D577AC8BD8DFFD34D91B75E150C7848B965D58B0096DF762C",
"download-video.min.css": "9B7FFAC852999B11DB62B6467CDBA1AEE53B7F3FA6C592185281542B25AF527A",
"download-video.min.html": "B7EC01DF01DBA78A7B009BDA78865891A974F84A1D72964B7393A07E50D5E5F5",
- "download-video.min.js": "17106554EA0409FD3653BDEE674D8BCF12AA88C2E321C71E000A54BBEEC372C9",
+ "download-video.min.js": "B61A2ADB1FF7490CED38E05F9B468733E5058B2BCB3BC21DBF40FB8CA252A517",
"download-video-package.min.js": "B10FF11DE7DFBACEC38F195B8E836511E527215B5E177CB1D223D14F30EB1435",
"dpi-img.vue.min.js": "11DF7577B754D8C01E8331E4FDAC9494E72523099845A0D6B0D897849CD841D6",
"expand-danmaku.min.js": "B21658C40085AEA8DC49652AE62EB8610BB2EBEAF7A9C9AF69EF3B11E08EEC8D",
diff --git a/min/bundle.zip b/min/bundle.zip
index 993cf22e9..3038a66ce 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 e071c65a3..a58ec45bc 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 getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&fnver=0&fnval=16`}else{return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&otype=json&fnver=0&fnval=16`}}else{if(a){return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&otype=json`}}}return e.bind(this)}async getDashUrl(t){return(await this.getApiGenerator(true))(c.aid,c.cid,t)}async getUrl(t){return(await this.getApiGenerator())(c.aid,c.cid,t)}}class r extends o{async getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&fourk=1&fnval=16`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&otype=json&fourk=1&fnval=16`}}else{if(a){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=&otype=json`}}}return e.bind(this)}}class l extends o{constructor(t){super();this.ep=t}async getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}}else{if(a){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&ep_id=${this.ep}`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&otype=json&ep_id=${this.ep}`}}}return e.bind(this)}}const c={entity:new o,aid:"",cid:""};let d=[];let p=null;let h=null;class u{constructor(t,e,s){this.quality=t;this.internalName=e;this.displayName=s}async downloadInfo(t=false){const e=new f(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 u(t,s[e],a[e])});return i}static async filterFormats(t){if(h===null){h=await Ajax.getJsonWithCredentials("https://api.bilibili.com/x/web-interface/nav")}_.remove(t,t=>{const e=t.quality;if(!h.isLogin){return e>=64}if(h.vipStatus!==1){return e===116||e===112||e===74}return false});return t}static async getAvailableDashFormats(){const t=await c.entity.getDashUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}const s=e.data||e.result||e;return await u.filterFormats(u.parseFormats(s))}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 await u.filterFormats(u.parseFormats(s))}}class f{constructor(t,e){this.fragmentSplitFactor=6*2;this.workingXhr=null;this.progressMap=new Map;this.format=t;this.fragments=e||[];this.videoSpeed=new m(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(t=false){if(!t){const t=await c.entity.getUrl(this.format.quality);const s=await Ajax.getTextWithCredentials(t);const a=JSON.parse(s.replace(/http:/g,"https:"));const i=a.data||a.result||a;const n=this.format.quality;if(i.quality!==n){const{throwQualityError:t}=await e.importAsync("quality-errors");t(n)}const o=i.durl;this.fragments=o.map(t=>{return{length:t.length,size:t.size,url:t.url,backupUrls:t.backup_url}})}else{const{dashToFragments:t,getDashInfo:s}=await e.importAsync("video-dash");const a=await s(await c.entity.getDashUrl(this.format.quality),this.format.quality);this.fragments=t(a)}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 m{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 w(){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 u.getAvailableFormats()}catch(t){return false}return true}const g=e=>{const s=t.downloadVideoQuality;const a=e.find(t=>t.quality===s);if(a){return a}const i=e.filter(t=>t.quality{const t=dq(".download-video");t.classList.toggle("opened");window.scroll(0,0);dq(".gui-settings-mask").click()});document.body.insertAdjacentHTML("beforeend",e.import("downloadVideoHtml"));b()}async function b(){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");const e=t.downloadVideoFormat=this.dashModel.value;let s=[];if(e==="flv"){s=await u.getAvailableFormats()}else{s=await u.getAvailableDashFormats()}d=s;p=g(d);this.qualityModel.items=s.map(t=>t.displayName);this.qualityModel.value=this.qualityModel.items[d.indexOf(p)];await this.formatChange()},async formatChange(e=false){console.log("format change");const s=this.getFormat();if(e){t.downloadVideoQuality=s.quality}try{this.size="获取大小中";const t=await s.downloadInfo(this.dash);this.size=t.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.batchExtractor;const l=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(r.formatTitle(t.titleParameters)+".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(r.formatTitle(e.titleParameters)+".ass",await t(a.rawXML))}}await s.emit(this.cid+".danmakus.zip")}catch(t){logError(`弹幕下载失败`);throw t}finally{t.dismiss()}}const d=Toast.info("获取链接中...","批量导出");r.config.itemFilter=o;r.config.api=await c.entity.getApiGenerator(this.dash);let p;try{switch(t){case"aria2":p=await r.collectAria2(l,d,false);await n.single(s(false)+".txt",new Blob([p],{type:"text/plain"}),{ffmpeg:this.ffmpegOption});return;case"aria2RPC":await r.collectAria2(l,d,true);Toast.success(`成功发送了批量请求.`,"aria2 RPC",3e3);return;case"copyVLD":GM.setClipboard(await r.collectData(l,d),{mimetype:"text/plain"});Toast.success("已复制批量vld数据到剪贴板.","批量导出",3e3);return;case"exportVLD":p=await r.collectData(l,d);await n.single(s(false)+".json",new Blob([p],{type:"text/json"}),{ffmpeg:this.ffmpegOption});return;case"ffmpegFragments":{const t=await r.getRawItems(l);const a=new f(l,t[0].fragments);const{getBatchFragmentsList:i}=await e.importAsync("ffmpeg-support");const o=i(t,this.dash||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 r.getRawItems(l);const s=new f(l,t[0].fragments);const{getBatchEpisodesList:a}=await e.importAsync("ffmpeg-support");const i=a(t,this.dash||s.extension());const o=new n;o.add("ffmpeg-files.txt",i);await o.emit()}break;default:return}}catch(t){logError(t)}finally{d.dismiss()}},async checkBatch(){const t=["//www.bilibili.com/bangumi","//www.bilibili.com/video/av","//www.bilibili.com/blackboard/bnj2020.html"];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,titleParameters:t.titleParameters,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 w();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:w,success:y}}}})();
\ 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 getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&fnver=0&fnval=16`}else{return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&otype=json&fnver=0&fnval=16`}}else{if(a){return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${e}&cid=${s}&otype=json`}}}return e.bind(this)}async getDashUrl(t){return(await this.getApiGenerator(true))(c.aid,c.cid,t)}async getUrl(t){return(await this.getApiGenerator())(c.aid,c.cid,t)}}class r extends o{async getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&fourk=1&fnval=16`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&otype=json&fourk=1&fnval=16`}}else{if(a){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${e}&cid=${s}&qn=&otype=json`}}}return e.bind(this)}}class l extends o{constructor(t){super();this.ep=t}async getApiGenerator(t=false){function e(e,s,a){if(t){if(a){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&otype=json&ep_id=${this.ep}&fnver=0&fnval=16`}}else{if(a){return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&qn=${a}&otype=json&ep_id=${this.ep}`}else{return`https://api.bilibili.com/pugv/player/web/playurl?avid=${e}&cid=${s}&otype=json&ep_id=${this.ep}`}}}return e.bind(this)}}const c={entity:new o,aid:"",cid:""};let d=[];let p=null;let h=null;class u{constructor(t,e,s){this.quality=t;this.internalName=e;this.displayName=s}async downloadInfo(t=false){const e=new f(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 u(t,s[e],a[e])});return i}static async filterFormats(t){if(h===null){h=(await Ajax.getJsonWithCredentials("https://api.bilibili.com/x/web-interface/nav")).data}_.remove(t,t=>{const e=t.quality;if(h.isLogin===false){return e>=64}if(h.vipStatus!==1){return e===116||e===112||e===74}return false});return t}static async getAvailableDashFormats(){const t=await c.entity.getDashUrl();const e=await Ajax.getJsonWithCredentials(t);if(e.code!==0){throw new Error("获取清晰度信息失败.")}const s=e.data||e.result||e;return await u.filterFormats(u.parseFormats(s))}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 await u.filterFormats(u.parseFormats(s))}}class f{constructor(t,e){this.fragmentSplitFactor=6*2;this.workingXhr=null;this.progressMap=new Map;this.format=t;this.fragments=e||[];this.videoSpeed=new m(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(t=false){if(!t){const t=await c.entity.getUrl(this.format.quality);const s=await Ajax.getTextWithCredentials(t);const a=JSON.parse(s.replace(/http:/g,"https:"));const i=a.data||a.result||a;const n=this.format.quality;if(i.quality!==n){const{throwQualityError:t}=await e.importAsync("quality-errors");t(n)}const o=i.durl;this.fragments=o.map(t=>{return{length:t.length,size:t.size,url:t.url,backupUrls:t.backup_url}})}else{const{dashToFragments:t,getDashInfo:s}=await e.importAsync("video-dash");const a=await s(await c.entity.getDashUrl(this.format.quality),this.format.quality);this.fragments=t(a)}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 m{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 w(){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 u.getAvailableFormats()}catch(t){return false}return true}const g=e=>{const s=t.downloadVideoQuality;const a=e.find(t=>t.quality===s);if(a){return a}const i=e.filter(t=>t.quality{const t=dq(".download-video");t.classList.toggle("opened");window.scroll(0,0);dq(".gui-settings-mask").click()});document.body.insertAdjacentHTML("beforeend",e.import("downloadVideoHtml"));b()}async function b(){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");const e=t.downloadVideoFormat=this.dashModel.value;let s=[];if(e==="flv"){s=await u.getAvailableFormats()}else{s=await u.getAvailableDashFormats()}d=s;p=g(d);this.qualityModel.items=s.map(t=>t.displayName);this.qualityModel.value=this.qualityModel.items[d.indexOf(p)];await this.formatChange()},async formatChange(e=false){console.log("format change");const s=this.getFormat();if(e){t.downloadVideoQuality=s.quality}try{this.size="获取大小中";const t=await s.downloadInfo(this.dash);this.size=t.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.batchExtractor;const l=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(r.formatTitle(t.titleParameters)+".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(r.formatTitle(e.titleParameters)+".ass",await t(a.rawXML))}}await s.emit(this.cid+".danmakus.zip")}catch(t){logError(`弹幕下载失败`);throw t}finally{t.dismiss()}}const d=Toast.info("获取链接中...","批量导出");r.config.itemFilter=o;r.config.api=await c.entity.getApiGenerator(this.dash);let p;try{switch(t){case"aria2":p=await r.collectAria2(l,d,false);await n.single(s(false)+".txt",new Blob([p],{type:"text/plain"}),{ffmpeg:this.ffmpegOption});return;case"aria2RPC":await r.collectAria2(l,d,true);Toast.success(`成功发送了批量请求.`,"aria2 RPC",3e3);return;case"copyVLD":GM.setClipboard(await r.collectData(l,d),{mimetype:"text/plain"});Toast.success("已复制批量vld数据到剪贴板.","批量导出",3e3);return;case"exportVLD":p=await r.collectData(l,d);await n.single(s(false)+".json",new Blob([p],{type:"text/json"}),{ffmpeg:this.ffmpegOption});return;case"ffmpegFragments":{const t=await r.getRawItems(l);const a=new f(l,t[0].fragments);const{getBatchFragmentsList:i}=await e.importAsync("ffmpeg-support");const o=i(t,this.dash||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 r.getRawItems(l);const s=new f(l,t[0].fragments);const{getBatchEpisodesList:a}=await e.importAsync("ffmpeg-support");const i=a(t,this.dash||s.extension());const o=new n;o.add("ffmpeg-files.txt",i);await o.emit()}break;default:return}}catch(t){logError(t)}finally{d.dismiss()}},async checkBatch(){const t=["//www.bilibili.com/bangumi","//www.bilibili.com/video/av","//www.bilibili.com/blackboard/bnj2020.html"];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,titleParameters:t.titleParameters,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 w();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:w,success:y}}}})();
\ 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 7383700b2..2e533bdc6 100644
--- a/src/video/download-video/download-video.ts
+++ b/src/video/download-video/download-video.ts
@@ -129,11 +129,11 @@ class VideoFormat {
static async filterFormats(formats: VideoFormat[]) {
// return formats
if (userInfo === null) {
- userInfo = await Ajax.getJsonWithCredentials('https://api.bilibili.com/x/web-interface/nav')
+ userInfo = (await Ajax.getJsonWithCredentials('https://api.bilibili.com/x/web-interface/nav')).data
}
_.remove(formats, f => {
const q = f.quality
- if (!userInfo!.isLogin) {
+ if (userInfo!.isLogin === false) {
return q >= 64
}
if (userInfo!.vipStatus !== 1) {