mirror of
https://github.com/the1812/Bilibili-Evolved.git
synced 2025-11-04 21:22:45 +08:00
1 line
3.8 KiB
JavaScript
1 line
3.8 KiB
JavaScript
(()=>{return(e,t)=>{const s=(unsafeWindow||window).aid;const o=(unsafeWindow||window).cid;if(s===undefined||o===undefined){return}class a{constructor(e,t,s){this.quality=e;this.internalName=t;this.displayName=s}async download(){const e=new r(this);await e.fetchVideoInfo();e.progress=(e=>{$(".download-progress-value").text(`${fixed(e*100)}`);$(".download-progress-foreground").css("transform",`scaleX(${e})`)});return e.download()}static get availableFormats(){return new Promise((e,t)=>{const n=`https://api.bilibili.com/x/player/playurl?avid=${s}&cid=${o}&otype=json`;const r=new XMLHttpRequest;r.addEventListener("load",()=>{const t=JSON.parse(r.responseText).data;const s=t.accept_quality;const o=t.accept_format.split(",");const n=t.accept_description;const i=[];while(s.length>0){const e=new a(s.pop(),o.pop(),n.pop());i.push(e)}e(i)});r.addEventListener("error",()=>t(`获取清晰度信息失败.`));r.withCredentials=true;r.open("GET",n);r.send()})}}class n{constructor(e,t,s,o){this.length=e;this.size=t;this.url=s;this.backupUrls=o}}class r{constructor(e,t){this.format=e;this.fragments=t||[];this.progress=null;this.loaded=0;this.totalSize=null}fetchVideoInfo(){return new Promise((e,t)=>{const a=`https://api.bilibili.com/x/player/playurl?avid=${s}&cid=${o}&qn=${this.format.quality}&otype=json`;const r=new XMLHttpRequest;r.addEventListener("load",()=>{const s=JSON.parse(r.responseText.replace(/http:/g,"https:")).data;if(s.quality!==this.format.quality){t("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const o=s.durl;this.fragments=o.map(e=>new n(e.length,e.size,e.url,e.backup_url));e(this.fragments)});r.withCredentials=true;r.open("GET",a);r.send()})}downloadUrl(e){return new Promise((t,s)=>{const o=new XMLHttpRequest;o.open("GET",e);o.responseType="arraybuffer";o.withCredentials=false;o.addEventListener("progress",e=>{this.progress&&this.progress((this.loaded+e.loaded)/this.totalSize)});o.addEventListener("load",()=>{if(o.status===200){t(o.response)}else{s(`请求失败.`)}});o.addEventListener("error",()=>{s(`下载失败.`)});o.send()})}async download(){const e=[];this.loaded=0;this.totalSize=this.fragments.map(e=>e.size).reduce((e,t)=>e+t);for(const t of this.fragments){const s=await this.downloadUrl(t.url);this.loaded+=t.size;e.push(s)}if(e.length<1){throw new Error("下载失败.")}let t=null;let s=null;const o=e=>(e||this.fragments[0]).url.indexOf(".flv")!==-1?".flv":".mp4";if(e.length===1){const[a]=e;t=new Blob([a],{type:o()===".flv"?"video/x-flv":"video/mp4"});s=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","")+o()}else{const a=new JSZip;const n=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","");e.forEach((e,t)=>{a.file(`${n} - ${t}${o(this.fragments[t])}`,e)});t=await a.generateAsync({type:"blob"});s=n+".zip"}const a=URL.createObjectURL(t);const n=$("a#video-complete").attr("href");if(n){URL.revokeObjectURL(n)}$("a#video-complete").attr("href",a).attr("download",s);this.progress&&this.progress(0);document.getElementById("video-complete").click();return a}}return{settingsWidget:{category:"视频与直播",content:t.data.downloadVideoDom.text,success:()=>{a.availableFormats.then(e=>{e.forEach(e=>{async function t(){$(".download-video-panel").removeClass("quality").addClass("progress");await e.download().catch(e=>{$(".download-video-panel").addClass("error");$(".video-error").text(e)});$(".download-video-panel").removeClass("progress").addClass("quality")}$(`<li>${e.displayName}</li>`).on("click",t).prependTo("ol.video-quality")});t.applyStyle("downloadVideoStyle");$("#download-video").on("click",()=>{$(".download-video-panel").toggleClass("opened")}).parent().removeClass("hidden")});$(".video-error").on("click",()=>{$(".video-error").text("");$(".download-video-panel").removeClass("error").removeClass("progress").addClass("quality")})}}}}})(); |