mirror of
https://github.com/the1812/Bilibili-Evolved.git
synced 2025-11-04 21:22:45 +08:00
1 line
5.4 KiB
JavaScript
1 line
5.4 KiB
JavaScript
(()=>{return(t,e)=>{const i=12;const s=[".mp4",".m4a"];class n{constructor(t){this.config=t;this.itemList=[]}async getRawItems(t){return JSON.parse(await this.collectData(t))}extension(t,e){const i=[".flv",".mp4"].find(e=>t.includes(e));if(i){return i}else if(t.includes(".m4s")){return s[e]}else{return".flv"}}async collectAria2(s,n){const r=await this.getRawItems(s);if(n){const s=t.aria2RpcOption;const{sendRpc:n}=await e.importAsync("aria2-rpc");for(const t of r){const e=t.fragments.map((e,n)=>{let r="";if(t.fragments.length>1&&!e.url.includes(".m4s")){r=" - "+(n+1)}const a=[];if(s.secretKey!==""){a.push(`token:${s.secretKey}`)}a.push([e.url]);a.push({referer:document.URL.replace(window.location.search,""),"user-agent":UserAgent,out:`${t.title}${r}${this.extension(e.url,n)}`,split:i,dir:s.baseDir+s.dir||undefined,"max-download-limit":s.maxDownloadLimit||undefined});const o=encodeURIComponent(`${t.title}${r}`);return{params:a,id:o}});await n(e,true)}}else{return`\n# Generated by Bilibili Evolved Video Export\n# https://github.com/the1812/Bilibili-Evolved/\n${r.map(t=>{return t.fragments.map((e,s)=>{let n="";if(t.fragments.length>1&&!e.url.includes(".m4s")){n=` - ${s+1}`}return`\n${e.url}\n referer=${t.referer}\n user-agent=${UserAgent}\n out=${t.title}${n}${this.extension(e.url,s)}\n split=${i}\n`.trim()}).join("\n")}).join("\n")}\n`.trim()}}}class r extends n{static async test(){if(!document.URL.includes("/www.bilibili.com/video/av")){return false}return await SpinQuery.select("#multi_page")!==null}async getItemList(){if(this.itemList.length>0){return this.itemList}const t=`https://api.bilibili.com/x/web-interface/view?aid=${unsafeWindow.aid}`;const e=await Ajax.getJson(t);if(e.code!==0){Toast.error(`获取视频选集列表失败, message=${e.message}`,"批量下载");return[]}const i=e.data.pages;if(i===undefined){Toast.error(`获取视频选集列表失败, 没有找到选集信息.`,"批量下载");return[]}this.itemList=i.map(t=>{return{title:`P${t.page} ${t.part}`,cid:t.cid,aid:unsafeWindow.aid}});return this.itemList}async collectData(t){const i=[];for(const s of(await this.getItemList()).filter(this.config.itemFilter)){const n=this.config.api?this.config.api(s.aid,s.cid,t):`https://api.bilibili.com/x/player/playurl?avid=${s.aid}&cid=${s.cid}&qn=${t}&otype=json`;const r=await Ajax.getJsonWithCredentials(n);const a=r.data||r.result||r;if(a.quality!==t){console.warn(`${s.title} 不支持所选画质, 已回退到较低画质. (quality=${a.quality})`)}let o;if(a.durl){o=a.durl.map(t=>{return{length:t.length,size:t.size,url:t.url}})}else{const{getDashInfo:i,dashToFragments:s}=await e.importAsync("video-dash");const r=await i(n,typeof t==="string"?parseInt(t):t);o=s(r)}i.push({fragments:o,title:s.title.replace(/[\/\\:\*\?"<>\|]/g," "),totalSize:o.map(t=>t.size).reduce((t,e)=>t+e),cid:s.cid,referer:document.URL.replace(window.location.search,"")})}return JSON.stringify(i)}}class a extends n{static async test(){return document.URL.includes("/www.bilibili.com/bangumi")}async getItemList(){if(this.itemList.length>0){return this.itemList}const t=document.querySelector("meta[property='og:url']");if(t===null){Toast.error("获取番剧数据失败: 无法找到 Season ID","批量下载");return[]}const e=t.getAttribute("content").match(/play\/ss(\d+)/)[1];if(e===undefined){Toast.error("获取番剧数据失败: 无法解析 Season ID","批量下载");return[]}const i=await Ajax.getJson(`https://api.bilibili.com/pgc/web/season/section?season_id=${e}`);if(i.code!==0){Toast.error(`获取番剧数据失败: 无法获取番剧集数列表, message=${i.message}`,"批量下载");return[]}this.itemList=i.result.main_section.episodes.map((t,e)=>{return{aid:t.aid,cid:t.cid,title:t.long_title?`${t.title} - ${t.long_title}`:`${e+1} - ${t.title}`}});return this.itemList}async collectData(t){const i=[];for(const s of(await this.getItemList()).filter(this.config.itemFilter)){const n=this.config.api?this.config.api(s.aid,s.cid,t):`https://api.bilibili.com/pgc/player/web/playurl?avid=${s.aid}&cid=${s.cid}&qn=${t}&otype=json`;const r=await Ajax.getJsonWithCredentials(n);const a=r.data||r.result||r;if(a.quality!==t){console.warn(`${s.title} 不支持所选画质, 已回退到较低画质. (quality=${a.quality})`)}let o;if(a.durl){o=a.durl.map(t=>{return{length:t.length,size:t.size,url:t.url}})}else{const{getDashInfo:i,dashToFragments:s}=await e.importAsync("video-dash");const r=await i(n,typeof t==="string"?parseInt(t):t);o=s(r)}i.push({fragments:o,title:s.title.replace(/[\/\\:\*\?"<>\|]/g," "),totalSize:o.map(t=>t.size).reduce((t,e)=>t+e),cid:s.cid,referer:document.URL.replace(window.location.search,"")})}return JSON.stringify(i)}}const o=[a,r];let c;class l{constructor(t){this.config=Object.assign({itemFilter:()=>true},t)}static async test(){for(const t of o){if(await t.test()===true){c=t;return true}}return false}getExtractor(){if(c===null){logError("[批量下载] 未找到合适的解析模块.");throw new Error(`[Batch Download] module not found.`)}const t=new c(this.config);return t}async getItemList(){const t=this.getExtractor();return await t.getItemList()}async getRawItems(t){const e=this.getExtractor();return await e.getRawItems(t.quality)}async collectData(t,e){const i=this.getExtractor();const s=await i.collectData(t.quality);e.dismiss();return s}async collectAria2(t,e,i=false){const s=this.getExtractor();const n=await s.collectAria2(t.quality,i);e.dismiss();return n}}return{export:{BatchExtractor:l}}}})(); |