From 473d7af711ff7e8d3bb72c9998ccd3bef596c960 Mon Sep 17 00:00:00 2001 From: the1812 Date: Wed, 20 Feb 2019 14:34:03 +0800 Subject: [PATCH] Read preserve subtitle settings in ass danmaku convert --- bilibili-evolved.offline.user.js | 4 ++-- bilibili-evolved.preview-offline.user.js | 4 ++-- min/download-danmaku.min.js | 2 +- video/download-danmaku.js | 9 +++++++-- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/bilibili-evolved.offline.user.js b/bilibili-evolved.offline.user.js index 1ee04386b..c97a367d1 100644 --- a/bilibili-evolved.offline.user.js +++ b/bilibili-evolved.offline.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name Bilibili Evolved (Offline) -// @version 218.94 +// @version 218.95 // @description Bilibili Evolved 的离线版, 所有功能都已内置于脚本中. // @author Grant Howard, Coulomb-G // @copyright 2019, Grant Howard (https://github.com/the1812) & Coulomb-G (https://github.com/Coulomb-G) @@ -1286,7 +1286,7 @@ offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/m offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/dark-schedule.min.js"] = (()=>{return(e,t)=>{class i{constructor(...e){if(e.length===0){const e=new Date;this.hour=e.getHours();this.minute=e.getMinutes()}else if(e.length===1){const[t]=e;[this.hour,this.minute]=t.split(":").slice(0,2).map(e=>this.validatePart(e));this.normalize()}else if(v.length===2){[this.hour,this.minute]=e}}validatePart(e){const t=parseInt(e);if(!isNaN(t)&&0<=t&&t<=59){return t}else{return null}}normalize(){while(this.minute<0){this.minute+=60;this.hour-=1}while(this.minute>=60){this.minute-=60;this.hour+=1}while(this.hour<0){this.hour+=24}while(this.hour>=24){this.hour-=24}}lessThan(e){if(this.houre.hour||this.hour===e.hour&&this.minute>e.minute){return true}return false}equals(e){return this.hour===e.hour&&this.minute===e.minute}isInRange(e,t){if(e.equals(t)){return false}let i=this.greaterThan(e)&&this.lessThan(t);if(e.greaterThan(t)){i=this.greaterThan(e)||this.lessThan(t)}const s=i||this.equals(e);return s}static millisecondsBefore(e){const t=new i;const s=(new Date).getSeconds();const r=1e3*(t.hour*3600+t.minute*60+s);const n=1e3*(e.hour*3600+e.minute*60);let h=n-r;if(t.greaterThan(e)||t.equals(e)&&s!==0){h+=24*3600*1e3}return h}}function s(){if(e.darkSchedule){const t=new i(e.darkScheduleStart);const r=new i(e.darkScheduleEnd);const n=new i;const h=n.isInRange(t,r);if(e.useDarkStyle!==h){e.useDarkStyle=h;saveSettings(e)}let u=0;if(h){u=i.millisecondsBefore(r)}else{u=i.millisecondsBefore(t)}if(u!==0){setTimeout(()=>s(),u)}}}s();return{export:{ScheduleTime:i}}}})(); offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/clear-cache.min.js"] = (()=>{return(n,c)=>{return{widget:{content:`\n \n \n 清除缓存\n `,condition:()=>typeof offlineData==="undefined",success:()=>{$("#clear-cache").on("click",()=>{n.cache={};saveSettings(n);Toast.success("已删除全部缓存.","清除缓存",5e3)})}}}}})(); offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.js"] = (()=>{return(e,t)=>{const{getFriendlyTitle:n}=t.import("title");const s={entity:null,aid:undefined,cid:undefined};class o{constructor(){this.menuClasses=["quality","action","progress"];this.currentMenuClass="quality"}get menuPanel(){return document.querySelector(".download-video-panel")}addMenuClass(){this.menuPanel.classList.remove(...this.menuClasses);this.menuPanel.classList.add(this.currentMenuClass);return this.currentMenuClass}resetMenuClass(){[this.currentMenuClass]=this.menuClasses;this.addMenuClass()}nextMenuClass(){const e=this.menuClasses.indexOf(this.currentMenuClass)+1;const t=this.menuClasses[e>=this.menuClasses.length?0:e];this.currentMenuClass=t;this.addMenuClass();return t}addError(){this.menuPanel.classList.add("error")}removeError(){this.menuPanel.classList.remove("error");this.resetMenuClass()}async getUrl(e){if(e){return`https://api.bilibili.com/x/player/playurl?avid=${s.aid}&cid=${s.cid}&qn=${e}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${s.aid}&cid=${s.cid}&otype=json`}}}class i extends o{async getUrl(e){if(e){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${s.aid}&cid=${s.cid}&qn=${e}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${s.aid}&cid=${s.cid}&qn=&otype=json`}}}class a{constructor(e,t,n){this.quality=e;this.internalName=t;this.displayName=n}async downloadInfo(){const e=new l(this);await e.fetchVideoInfo();return e}static get availableFormats(){return new Promise((e,t)=>{s.entity.getUrl().then(n=>{const s=new XMLHttpRequest;s.addEventListener("load",()=>{const n=JSON.parse(s.responseText);if(n.code!==0){t("获取清晰度信息失败.")}const o=n.data||n.result||n;const i=o.accept_quality;const r=o.accept_format.split(",");const l=o.accept_description;const d=[];while(i.length>0){const e=new a(i.pop(),r.pop(),l.pop());d.push(e)}e(d)});s.addEventListener("error",()=>t(`获取清晰度信息失败.`));s.withCredentials=true;s.open("GET",n);s.send()})})}}class r{constructor(e,t,n,s){this.length=e;this.size=t;this.url=n;this.backupUrls=s}}class l{constructor(e,t){this.format=e;this.fragments=t||[];this.progress=null;this.loaded=0;this.totalSize=null;this.workingXhr=null;this.fragmentSplitFactor=6*5}fetchVideoInfo(){return new Promise((e,t)=>{s.entity.getUrl(this.format.quality).then(n=>{const s=new XMLHttpRequest;s.addEventListener("load",()=>{const n=JSON.parse(s.responseText.replace(/http:/g,"https:"));const o=n.data||n.result||n;if(o.quality!==this.format.quality){t("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const i=o.durl;this.fragments=i.map(e=>new r(e.length,e.size,e.url,e.backup_url));e(this.fragments)});s.withCredentials=true;s.open("GET",n);s.send()})})}cancelDownload(){if("forEach"in this.workingXhr){this.workingXhr.forEach(e=>e.abort())}else{logError("Cancel Download Failed: forEach in this.workingXhr not found.")}}downloadFragment(e){const t=[];this.workingXhr=[];const n=Math.round(e.size/this.fragmentSplitFactor);let s=0;while(s{let s=0;const i=new XMLHttpRequest;i.open("GET",e.url);i.responseType="arraybuffer";i.withCredentials=false;i.addEventListener("progress",e=>{this.loaded+=e.loaded-s;s=e.loaded;this.progress&&this.progress(this.loaded/this.totalSize)});i.addEventListener("load",()=>{if((""+i.status)[0]==="2"){t(i.response)}else{n(`请求失败.`)}});i.addEventListener("abort",()=>n("下载已取消."));i.addEventListener("error",()=>{this.loaded-=s;s=0;i.open("GET",e.url);i.send()});i.setRequestHeader("Range",o);i.send();this.workingXhr.push(i)}));s=Math.round(s+n)+1}return Promise.all(t)}copyUrl(){const e=this.fragments.map(e=>e.url).reduce((e,t)=>e+"\r\n"+t);GM_setClipboard(e,"text")}extension(e){return(e||this.fragments[0]).url.indexOf(".flv")!==-1?".flv":".mp4"}makeBlob(e,t=null){return new Blob(Array.isArray(e)?e:[e],{type:this.extension(t)===".flv"?"video/x-flv":"video/mp4"})}cleanUpOldBlobUrl(){const e=$("a#video-complete").attr("href");if(e&&$(`.link[href=${e}]`).length===0){URL.revokeObjectURL(e)}}downloadSingle(e){const[t]=e;const s=this.makeBlob(t);const o=n()+this.extension();return[s,o]}async downloadMultiple(e){const t=new JSZip;const s=n();if(e.length>1){e.forEach((e,n)=>{const o=this.fragments[n];t.file(`${s} - ${n+1}${this.extension(o)}`,this.makeBlob(e,o))})}else{const[n]=e;t.file(`${s}${this.extension()}`,this.makeBlob(n))}const o=await t.generateAsync({type:"blob"});const i=s+".zip";return[o,i]}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 n=await this.downloadFragment(t);e.push(n)}if(e.length<1){throw new Error("下载失败.")}let t=null;let n=null;if(e.length===1){[t,n]=this.downloadSingle(e)}else{[t,n]=await this.downloadMultiple(e)}const s=URL.createObjectURL(t);this.cleanUpOldBlobUrl();this.progress&&this.progress(0);return{url:s,filename:n}}}async function d(){const e=await SpinQuery.select(()=>(unsafeWindow||window).aid);const t=await SpinQuery.select(()=>(unsafeWindow||window).cid);s.aid=e;s.cid=t;if(document.URL.indexOf("bangumi")!==-1){s.entity=new i}else{s.entity=new o}return Boolean(e&&t)}async function c(){let e=await a.availableFormats;let[n]=e;const o=async()=>{await d();e=await a.availableFormats;const t=$("ol.video-quality");t.html("");e.forEach(e=>{$(`
  • ${e.displayName}
  • `).on("click",()=>{n=e;s.entity.nextMenuClass()}).prependTo(t)})};if(Observer.videoChange){Observer.videoChange(o)}else{Observer.childList("#bofqi",o)}const i=()=>n.downloadInfo().catch(e=>{s.entity.addError();$(".video-error").text(e)});async function r(){if(!n){return}s.entity.nextMenuClass();const e=await i();e.progress=(e=>{$(".download-progress-value").text(`${fixed(e*100)}`);$(".download-progress-foreground").css("transform",`scaleX(${e})`)});document.querySelector(".download-progress-cancel>span").onclick=(()=>e.cancelDownload());const t=await e.download().catch(e=>{s.entity.addError();$(".video-error").text(e)});if(!t){return}const o=document.getElementById("video-complete");o.setAttribute("href",t.url);o.setAttribute("download",t.filename);o.click();const a=`下载完成. 再次保存`;Toast.success(a,"下载视频");s.entity.resetMenuClass()}async function l(){if(!n){return}const e=await i();e.copyUrl();Toast.success("已复制链接到剪贴板.","复制链接",3e3);s.entity.resetMenuClass()}$(".video-action>#video-action-download").on("click",r);$(".video-action>#video-action-copy").on("click",l);t.applyStyle("downloadVideoStyle");const c=document.querySelector(".download-video-panel");const u=()=>$(".download-video-panel").toggleClass("opened");$("#download-video").on("click",e=>{if(!c.contains(e.target)){u()}});$(".video-error").on("click",()=>{$(".video-error").text("");s.entity.removeError()});await SpinQuery.select(()=>document.querySelector(".download-video-panel"));s.entity.addMenuClass()}return{widget:{content:(t.data.downloadVideoDom||t.data.downloadVideoHtml).text,condition:d,success:c}}}})(); -offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-danmaku.min.js"] = (()=>{return(t,e)=>{const{getFriendlyTitle:n}=e.import("title");const{DanmakuInfo:i}=e.import("video-info");const{DanmakuConverter:o}=e.import("danmaku-converter");async function a(t,e){const a=n();const l=new i((unsafeWindow||window).cid);await l.fetchInfo();const r=await(async()=>{if(e===true){let t={title:a};try{await loadLazyPanel(".bilibili-player-video-danmaku-setting");const e=t=>{const e=parseFloat(document.querySelector(t).style.transform.replace(/translateX\(([\d\.]+)/,"$1"));const n={0:0,44:1,94:2,144:3,188:4}[e];return n};t.font=document.querySelector(".bilibili-player-video-danmaku-setting-right-font .bui-select-result").innerText;t.alpha=parseFloat(document.querySelector(".bilibili-player-setting-opacity .bui-bar").style.transform.replace(/scaleX\(([\d\.]+)\)/,"$1"));t.duration=(()=>{const t=[10,8,6,4,2][e(".bilibili-player-setting-speedplus .bui-thumb")];return e=>{switch(e.type){case 4:case 5:return 4;default:return t}}})();t.blockTypes=(()=>{let t=[];const e={".bilibili-player-block-filter-type[ftype=scroll]":[1,2,3],".bilibili-player-block-filter-type[ftype=top]":[5],".bilibili-player-block-filter-type[ftype=bottom]":[4],".bilibili-player-block-filter-type[ftype=color]":["color"]};for(const[n,i]of Object.entries(e)){if(document.querySelector(n).classList.contains("disabled")){t=t.concat(i)}}return t.concat(7,8)})();const n=[1.4,1.2,1,.8,.6][e(".bilibili-player-setting-fontsize .bui-thumb")];t.resolution={x:1920*n,y:1080*n};t.bottomMarginPercent=[.75,.5,.25,.15,.15][e(".bilibili-player-setting-area .bui-thumb")];t.bold=document.querySelector(".bilibili-player-video-danmaku-setting-right-font-bold input").checked}catch(e){t={font:"微软雅黑",alpha:.6,duration:t=>{switch(t.type){case 4:case 5:return 4;default:return 6}},blockTypes:[],resolution:{x:1920,y:1080},bottomMarginPercent:.15,bold:false}}const e=new o(t);const n=e.convertToAssDocument(l.rawXML);return new Blob([n.generateAss()],{type:"text/plain"})}else{return new Blob([l.rawXML],{type:"text/plain"})}})();const c=URL.createObjectURL(r);const s=$("#danmaku-link");const u=s.attr("href");if(u){URL.revokeObjectURL(u)}clearTimeout(t);document.querySelector("#download-danmaku>span").innerHTML="下载弹幕";s.attr("download",`${a}.${e?"ass":"xml"}`).attr("href",c).get(0).click()}return{widget:{content:`\n \n \n 下载弹幕\n \n `,condition:async()=>{let t=await SpinQuery.select(()=>(unsafeWindow||window).cid);return Boolean(t)},success:()=>{const t=document.querySelector("#danmaku-link");$("#download-danmaku").on("click",e=>{if(e.target!==t){const t=setTimeout(()=>document.querySelector("#download-danmaku>span").innerHTML="请稍侯...",200);a(t,e.shiftKey)}})}}}}})(); +offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-danmaku.min.js"] = (()=>{return(t,e)=>{const{getFriendlyTitle:n}=e.import("title");const{DanmakuInfo:i}=e.import("video-info");const{DanmakuConverter:o}=e.import("danmaku-converter");async function a(t,e){const a=n();const r=new i((unsafeWindow||window).cid);await r.fetchInfo();const l=await(async()=>{if(e===true){let t={title:a};try{await loadLazyPanel(".bilibili-player-video-danmaku-setting");const e=t=>{const e=parseFloat(document.querySelector(t).style.transform.replace(/translateX\(([\d\.]+)/,"$1"));const n={0:0,44:1,94:2,144:3,188:4}[e];return n};t.font=document.querySelector(".bilibili-player-video-danmaku-setting-right-font .bui-select-result").innerText;t.alpha=parseFloat(document.querySelector(".bilibili-player-setting-opacity .bui-bar").style.transform.replace(/scaleX\(([\d\.]+)\)/,"$1"));t.duration=(()=>{const t=[10,8,6,4,2][e(".bilibili-player-setting-speedplus .bui-thumb")];return e=>{switch(e.type){case 4:case 5:return 4;default:return t}}})();t.blockTypes=(()=>{let t=[];const e={".bilibili-player-block-filter-type[ftype=scroll]":[1,2,3],".bilibili-player-block-filter-type[ftype=top]":[5],".bilibili-player-block-filter-type[ftype=bottom]":[4],".bilibili-player-block-filter-type[ftype=color]":["color"]};for(const[n,i]of Object.entries(e)){if(document.querySelector(n).classList.contains("disabled")){t=t.concat(i)}}return t.concat(7,8)})();const n=[1.4,1.2,1,.8,.6][e(".bilibili-player-setting-fontsize .bui-thumb")];t.resolution={x:1920*n,y:1080*n};t.bottomMarginPercent=[.75,.5,.25,0,0][e(".bilibili-player-setting-area .bui-thumb")];if(t.bottomMarginPercent===0&&document.querySelector(".bilibili-player-video-danmaku-setting-left-preventshade input").checked){t.bottomMarginPercent=.15}t.bold=document.querySelector(".bilibili-player-video-danmaku-setting-right-font-bold input").checked}catch(e){t={font:"微软雅黑",alpha:.6,duration:t=>{switch(t.type){case 4:case 5:return 4;default:return 6}},blockTypes:[7,8],resolution:{x:1920,y:1080},bottomMarginPercent:.15,bold:false}}const e=new o(t);const n=e.convertToAssDocument(r.rawXML);return new Blob([n.generateAss()],{type:"text/plain"})}else{return new Blob([r.rawXML],{type:"text/plain"})}})();const c=URL.createObjectURL(l);const s=$("#danmaku-link");const u=s.attr("href");if(u){URL.revokeObjectURL(u)}clearTimeout(t);document.querySelector("#download-danmaku>span").innerHTML="下载弹幕";s.attr("download",`${a}.${e?"ass":"xml"}`).attr("href",c).get(0).click()}return{widget:{content:`\n \n \n 下载弹幕\n \n `,condition:async()=>{let t=await SpinQuery.select(()=>(unsafeWindow||window).cid);return Boolean(t)},success:()=>{const t=document.querySelector("#danmaku-link");$("#download-danmaku").on("click",e=>{if(e.target!==t){const t=setTimeout(()=>document.querySelector("#download-danmaku>span").innerHTML="请稍侯...",200);a(t,e.shiftKey)}})}}}}})(); offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/danmaku-converter.min.js"] = (()=>{return(t,e)=>{class i{constructor(t,e,i,s,n){this.content=t;this.time=e;this.type=parseInt(i);this.fontSize=parseFloat(s);this.color=parseInt(n)}}class s extends i{constructor({content:t,time:e,type:i,fontSize:s,color:n,timeStamp:r,pool:a,userHash:o,rowId:c}){super(t,e,i,s,n);this.timeStamp=parseInt(r);this.pool=parseInt(a);this.userHash=o;this.rowId=parseInt(c);this.time=parseFloat(this.time);this.pDataArray=[e,i,s,n,r,a,o,c]}text(){const t=this.pDataArray.join(",");return`${this.content}`}static parse(t){const e=t.getAttribute("p");const[i,n,r,a,o,c,h,l]=e.split(",");const u=t.innerHTML;return new s({content:u,time:i,type:n,fontSize:r,color:a,timeStamp:o,pool:c,userHash:h,rowId:l})}}class n{constructor(t){this.xml=t;const e=(new DOMParser).parseFromString(t,"application/xml").documentElement;this.danmakus=[...e.querySelectorAll("d[p]")].map(t=>s.parse(t))}}class r extends i{constructor({content:t,time:e,type:i,fontSize:s,color:n,typeTag:r,colorTag:a,endTime:o}){super(t,e,i,s,n);this.typeTag=r;this.colorTag=a;this.endTime=o}text(t){const e=t[this.fontSize].match(/Style:(.*?),/)[1].trim();return`Dialogue: 0,${this.time},${this.endTime},${e},,0,0,0,,{${this.typeTag}${this.colorTag}}${this.content}`}}class a{constructor({danmakus:t,title:e,fontStyles:i,blockTypes:s,resolution:n}){this.danmakus=t;this.title=e;this.fontStyles=i;this.blockTypes=s;this.resolution=n}generateAss(){const t=`\n[Script Info]\n; Script generated by Bilibili Evolved Danmaku Converter\n; https://github.com/the1812/Bilibili-Evolved/\nTitle: ${this.title}\nScriptType: v4.00+\nPlayResX: ${this.resolution.x}\nPlayResY: ${this.resolution.y}\nTimer: 10.0000\nWrapStyle: 2\nScaledBorderAndShadow: no\n\n[V4+ Styles]\nFormat: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\n${Object.values(this.fontStyles).join("\n")}\n\n[Events]\nFormat: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\n `.trim();return t+"\n"+this.danmakus.map(t=>t.text(this.fontStyles,this.blockTypes)).filter(t=>t!=="").join("\n")}}class o{constructor(t,e,i,s){this.horizontalDanmakus=[];this.horizontalTrack=[];this.verticalDanmakus=[];this.verticalTrack=[];this.resolution=e;this.duration=i;this.canvas=document.createElement("canvas");this.context=this.canvas.getContext("2d");this.fontSizes={25:`52px ${t}`,18:`36px ${t}`};this.danmakuType={1:"normal",2:"normal",3:"normal",4:"bottom",5:"top",6:"reversed",7:"special",8:"special"};this.bottomMarginPercent=s;this.margin=4;this.nextDanmakuDelay=.05;this.generateTracks()}generateTracks(){const t=52;this.danmakuHeight=t;this.trackHeight=this.margin*2+t;this.trackCount=parseInt(fixed(this.resolution.y*(1-this.bottomMarginPercent)/this.trackHeight,0))}getTextSize(t){this.context.font=this.fontSizes[t.fontSize];const e=this.context.measureText(t.content);const i=e.width/2;return[i,this.danmakuHeight/2]}getTags(t,{targetTrack:e,initTrack:i,nextTrack:s,isClosestDanmaku:n,getTrackItem:r,getTag:a}){const[o,c]=this.getTextSize(t);const h=o*2;const l=this.duration(t)*h/(this.resolution.x+h)+this.nextDanmakuDelay;let u=i;let m=null;do{m=e.find(t=>n({it:t,track:u,width:h}));u+=s}while(m&&u<=this.trackCount&&u>=0);if(u>this.trackCount||u<0){return`\\pos(0,-999)`}u-=s;e.push(r({track:u,width:h,visibleTime:l}));return a({track:u,x:o,y:c})}getHorizontalTags(t){return this.getTags(t,{targetTrack:this.horizontalTrack,initTrack:0,nextTrack:1,isClosestDanmaku:({it:e,track:i,width:s})=>{if(e.track!==i){return false}if(e.widtht.time}},getTrackItem:({track:e,width:i,visibleTime:s})=>{return{width:i,start:t.time,visible:t.time+s,end:t.time+this.duration(t),track:e}},getTag:({track:e,x:i,y:s})=>{return`\\move(${this.resolution.x+i},${e*this.trackHeight+this.margin+s},${-i},${e*this.trackHeight+this.margin+s},0,${this.duration(t)*1e3})`}})}getVerticalTags(t){const e=this.danmakuType[t.type]==="top";return this.getTags(t,{targetTrack:this.verticalTrack,initTrack:e?0:this.trackCount-1,nextTrack:e?1:-1,isClosestDanmaku:({it:e,track:i})=>{if(e.track!==i){return false}return e.end>t.time},getTrackItem:({track:e})=>{return{start:t.time,end:t.time+this.duration(t),track:e}},getTag:({track:t,y:i})=>{if(e){return`\\pos(${this.resolution.x/2},${t*this.trackHeight+this.margin+i})`}else{return`\\pos(${this.resolution.x/2},${this.resolution.y-this.margin-i-(this.trackCount-1-t)*this.trackHeight})`}}})}push(t){let e=null;let i=null;switch(this.danmakuType[t.type]){case"normal":case"reversed":{e=this.getHorizontalTags(t);i=this.horizontalDanmakus;break}case"top":case"bottom":{e=this.getVerticalTags(t);i=this.verticalDanmakus;break}case"special":default:{return{tags:`\\pos(0,-999)`}}}const s={tags:e};i.push(s);return s}}class c{constructor({title:t,font:e,alpha:i,duration:s,blockTypes:n,resolution:r,bottomMarginPercent:a,bold:c}){this.title=t;this.font=e;this.alpha=Math.round(i*100).toString(16).toUpperCase();this.duration=s;this.blockTypes=n;this.resolution=r;this.bold=c;this.white=16777215;this.danmakuStack=new o(e,r,s,a)}get fontStyles(){return{25:`Style: Medium,${this.font},52,&H${this.alpha}FFFFFF,&H${this.alpha}FFFFFF,&H${this.alpha}000000,&H${this.alpha}000000,${this.bold?"1":"0"},0,0,0,100,100,0,0,1,1.2,0,5,0,0,0,0`,18:`Style: Small,${this.font},36,&H${this.alpha}FFFFFF,&H${this.alpha}FFFFFF,&H${this.alpha}000000,&H${this.alpha}000000,${this.bold?"1":"0"},0,0,0,100,100,0,0,1,1.2,0,5,0,0,0,0`}}convertToAssDocument(t){const e=new n(t);const i=[];for(const t of e.danmakus.sort((t,e)=>t.time-e.time)){if(this.blockTypes.indexOf(t.type)!==-1||this.blockTypes.indexOf("color")!==-1&&t.color!==this.white){continue}const[e,s]=this.convertTime(t.time,this.duration(t));i.push(new r({content:this.convertText(t.content),time:e,endTime:s,type:t.type,fontSize:t.fontSize,color:t.color,typeTag:this.convertType(t),colorTag:this.convertColor(t.color)}))}return new a({danmakus:i,title:this.title,blockTypes:this.blockTypes,fontStyles:this.fontStyles,resolution:this.resolution})}convertText(t){const e={"{":"{","}":"}","&":"&","<":"<",">":">",""":'"',"'":"'"};for(const[i,s]of Object.entries(e)){t=t.replace(new RegExp(i,"g"),s)}return t}convertType(t){return this.danmakuStack.push(t).tags}convertColor(t){if(t===this.white){return""}const e=t.toString(16);const i=e.substring(0,2);const s=e.substring(2,4);const n=e.substring(4,6);return`\\c&H${n}${s}${i}&`}convertTime(t,e){function i(t){const[e,i="00"]=String(t).split(".");return`${e.padStart(2,"0")}.${i.substr(0,2).padEnd(2,"0")}`}function s(t){let e=0;let s=0;while(t>=60){t-=60;s++}while(s>=60){s-=60;e++}return`${e}:${String(s).padStart(2,"0")}:${i(t)}`}return[s(t),s(t+e)]}}return{export:{AssDanmaku:r,AssDanmakuDocument:a,Danmaku:i,DanmakuConverter:c,DanmakuStack:o,XmlDanmaku:s,XmlDanmakuDocument:n}}}})(); offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/video-info.min.js"] = (()=>{return(t,i)=>{class e{constructor(t){this.aid=t}async fetchInfo(){const t=JSON.parse(await downloadText(`https://api.bilibili.com/x/web-interface/view?aid=${this.aid}`));if(t.code!==0){throw new Error(t.message)}const i=t.data;this.cid=i.cid;this.pageCount=i.videos;this.coverUrl=i.pic;this.tagId=i.tid;this.tagName=i.tname;this.title=i.title;this.description=i.desc;this.up={uid:i.owner.mid,name:i.owner.name,faceUrl:i.owner.face};this.pages=i.pages.map(t=>{return{cid:t.cid,title:t.part,pageNumber:t.page}});return this}async fetchDanmaku(){this.danmaku=new s(this.cid);return this.danmaku.fetchInfo()}}class a{constructor(t,i){this.text=t;this.p=i}}class s{constructor(t){this.cid=t}async fetchInfo(){const t=await downloadText(`https://api.bilibili.com/x/v1/dm/list.so?oid=${this.cid}`);this.rawXML=t;const i=(new DOMParser).parseFromString(t,"application/xml").documentElement;this.xml=i;this.danmakus=[].map.call(i.querySelectorAll("d[p]"),t=>{return new a(t.innerHTML,t.getAttribute("p"))})}}class n{constructor(t){this.ep=t;this.videos=[]}async fetchInfo(){const t=await downloadText(`https://www.bilibili.com/bangumi/play/ep${this.ep}/`);const i=JSON.parse(t.match(/window\.__INITIAL_STATE__=(.*);\(function\(\){/)[1]);this.title=i.mediaInfo.title;this.cover=i.mediaInfo.cover;this.squareCover=i.mediaInfo.square_cover;this.aid=i.epInfo.aid;this.cid=i.epInfo.cid;this.videos=i.epList.map(async t=>{return{title:t.index_title,aid:t.aid,cid:t.cid,info:await new e(t.aid).fetchInfo()}});return this}}return{export:{VideoInfo:e,BangumiInfo:n,Danmaku:a,DanmakuInfo:s}}}})(); offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/about.min.html"] = `

    Bilibili Evolved

    开源组件

      `; diff --git a/bilibili-evolved.preview-offline.user.js b/bilibili-evolved.preview-offline.user.js index 12ba3dea5..7b9860f83 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 218.94 +// @version 218.95 // @description Bilibili Evolved 的预览离线版, 可以抢先体验新功能, 并且所有功能都已内置于脚本中. // @author Grant Howard, Coulomb-G // @copyright 2019, Grant Howard (https://github.com/the1812) & Coulomb-G (https://github.com/Coulomb-G) @@ -1286,7 +1286,7 @@ offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/m offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/dark-schedule.min.js"] = (()=>{return(e,t)=>{class i{constructor(...e){if(e.length===0){const e=new Date;this.hour=e.getHours();this.minute=e.getMinutes()}else if(e.length===1){const[t]=e;[this.hour,this.minute]=t.split(":").slice(0,2).map(e=>this.validatePart(e));this.normalize()}else if(v.length===2){[this.hour,this.minute]=e}}validatePart(e){const t=parseInt(e);if(!isNaN(t)&&0<=t&&t<=59){return t}else{return null}}normalize(){while(this.minute<0){this.minute+=60;this.hour-=1}while(this.minute>=60){this.minute-=60;this.hour+=1}while(this.hour<0){this.hour+=24}while(this.hour>=24){this.hour-=24}}lessThan(e){if(this.houre.hour||this.hour===e.hour&&this.minute>e.minute){return true}return false}equals(e){return this.hour===e.hour&&this.minute===e.minute}isInRange(e,t){if(e.equals(t)){return false}let i=this.greaterThan(e)&&this.lessThan(t);if(e.greaterThan(t)){i=this.greaterThan(e)||this.lessThan(t)}const s=i||this.equals(e);return s}static millisecondsBefore(e){const t=new i;const s=(new Date).getSeconds();const r=1e3*(t.hour*3600+t.minute*60+s);const n=1e3*(e.hour*3600+e.minute*60);let h=n-r;if(t.greaterThan(e)||t.equals(e)&&s!==0){h+=24*3600*1e3}return h}}function s(){if(e.darkSchedule){const t=new i(e.darkScheduleStart);const r=new i(e.darkScheduleEnd);const n=new i;const h=n.isInRange(t,r);if(e.useDarkStyle!==h){e.useDarkStyle=h;saveSettings(e)}let u=0;if(h){u=i.millisecondsBefore(r)}else{u=i.millisecondsBefore(t)}if(u!==0){setTimeout(()=>s(),u)}}}s();return{export:{ScheduleTime:i}}}})(); offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/clear-cache.min.js"] = (()=>{return(n,c)=>{return{widget:{content:`\n \n \n 清除缓存\n `,condition:()=>typeof offlineData==="undefined",success:()=>{$("#clear-cache").on("click",()=>{n.cache={};saveSettings(n);Toast.success("已删除全部缓存.","清除缓存",5e3)})}}}}})(); offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.js"] = (()=>{return(e,t)=>{const{getFriendlyTitle:n}=t.import("title");const s={entity:null,aid:undefined,cid:undefined};class o{constructor(){this.menuClasses=["quality","action","progress"];this.currentMenuClass="quality"}get menuPanel(){return document.querySelector(".download-video-panel")}addMenuClass(){this.menuPanel.classList.remove(...this.menuClasses);this.menuPanel.classList.add(this.currentMenuClass);return this.currentMenuClass}resetMenuClass(){[this.currentMenuClass]=this.menuClasses;this.addMenuClass()}nextMenuClass(){const e=this.menuClasses.indexOf(this.currentMenuClass)+1;const t=this.menuClasses[e>=this.menuClasses.length?0:e];this.currentMenuClass=t;this.addMenuClass();return t}addError(){this.menuPanel.classList.add("error")}removeError(){this.menuPanel.classList.remove("error");this.resetMenuClass()}async getUrl(e){if(e){return`https://api.bilibili.com/x/player/playurl?avid=${s.aid}&cid=${s.cid}&qn=${e}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${s.aid}&cid=${s.cid}&otype=json`}}}class i extends o{async getUrl(e){if(e){return`https://api.bilibili.com/pgc/player/web/playurl?avid=${s.aid}&cid=${s.cid}&qn=${e}&otype=json`}else{return`https://api.bilibili.com/pgc/player/web/playurl?avid=${s.aid}&cid=${s.cid}&qn=&otype=json`}}}class a{constructor(e,t,n){this.quality=e;this.internalName=t;this.displayName=n}async downloadInfo(){const e=new l(this);await e.fetchVideoInfo();return e}static get availableFormats(){return new Promise((e,t)=>{s.entity.getUrl().then(n=>{const s=new XMLHttpRequest;s.addEventListener("load",()=>{const n=JSON.parse(s.responseText);if(n.code!==0){t("获取清晰度信息失败.")}const o=n.data||n.result||n;const i=o.accept_quality;const r=o.accept_format.split(",");const l=o.accept_description;const d=[];while(i.length>0){const e=new a(i.pop(),r.pop(),l.pop());d.push(e)}e(d)});s.addEventListener("error",()=>t(`获取清晰度信息失败.`));s.withCredentials=true;s.open("GET",n);s.send()})})}}class r{constructor(e,t,n,s){this.length=e;this.size=t;this.url=n;this.backupUrls=s}}class l{constructor(e,t){this.format=e;this.fragments=t||[];this.progress=null;this.loaded=0;this.totalSize=null;this.workingXhr=null;this.fragmentSplitFactor=6*5}fetchVideoInfo(){return new Promise((e,t)=>{s.entity.getUrl(this.format.quality).then(n=>{const s=new XMLHttpRequest;s.addEventListener("load",()=>{const n=JSON.parse(s.responseText.replace(/http:/g,"https:"));const o=n.data||n.result||n;if(o.quality!==this.format.quality){t("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const i=o.durl;this.fragments=i.map(e=>new r(e.length,e.size,e.url,e.backup_url));e(this.fragments)});s.withCredentials=true;s.open("GET",n);s.send()})})}cancelDownload(){if("forEach"in this.workingXhr){this.workingXhr.forEach(e=>e.abort())}else{logError("Cancel Download Failed: forEach in this.workingXhr not found.")}}downloadFragment(e){const t=[];this.workingXhr=[];const n=Math.round(e.size/this.fragmentSplitFactor);let s=0;while(s{let s=0;const i=new XMLHttpRequest;i.open("GET",e.url);i.responseType="arraybuffer";i.withCredentials=false;i.addEventListener("progress",e=>{this.loaded+=e.loaded-s;s=e.loaded;this.progress&&this.progress(this.loaded/this.totalSize)});i.addEventListener("load",()=>{if((""+i.status)[0]==="2"){t(i.response)}else{n(`请求失败.`)}});i.addEventListener("abort",()=>n("下载已取消."));i.addEventListener("error",()=>{this.loaded-=s;s=0;i.open("GET",e.url);i.send()});i.setRequestHeader("Range",o);i.send();this.workingXhr.push(i)}));s=Math.round(s+n)+1}return Promise.all(t)}copyUrl(){const e=this.fragments.map(e=>e.url).reduce((e,t)=>e+"\r\n"+t);GM_setClipboard(e,"text")}extension(e){return(e||this.fragments[0]).url.indexOf(".flv")!==-1?".flv":".mp4"}makeBlob(e,t=null){return new Blob(Array.isArray(e)?e:[e],{type:this.extension(t)===".flv"?"video/x-flv":"video/mp4"})}cleanUpOldBlobUrl(){const e=$("a#video-complete").attr("href");if(e&&$(`.link[href=${e}]`).length===0){URL.revokeObjectURL(e)}}downloadSingle(e){const[t]=e;const s=this.makeBlob(t);const o=n()+this.extension();return[s,o]}async downloadMultiple(e){const t=new JSZip;const s=n();if(e.length>1){e.forEach((e,n)=>{const o=this.fragments[n];t.file(`${s} - ${n+1}${this.extension(o)}`,this.makeBlob(e,o))})}else{const[n]=e;t.file(`${s}${this.extension()}`,this.makeBlob(n))}const o=await t.generateAsync({type:"blob"});const i=s+".zip";return[o,i]}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 n=await this.downloadFragment(t);e.push(n)}if(e.length<1){throw new Error("下载失败.")}let t=null;let n=null;if(e.length===1){[t,n]=this.downloadSingle(e)}else{[t,n]=await this.downloadMultiple(e)}const s=URL.createObjectURL(t);this.cleanUpOldBlobUrl();this.progress&&this.progress(0);return{url:s,filename:n}}}async function d(){const e=await SpinQuery.select(()=>(unsafeWindow||window).aid);const t=await SpinQuery.select(()=>(unsafeWindow||window).cid);s.aid=e;s.cid=t;if(document.URL.indexOf("bangumi")!==-1){s.entity=new i}else{s.entity=new o}return Boolean(e&&t)}async function c(){let e=await a.availableFormats;let[n]=e;const o=async()=>{await d();e=await a.availableFormats;const t=$("ol.video-quality");t.html("");e.forEach(e=>{$(`
    • ${e.displayName}
    • `).on("click",()=>{n=e;s.entity.nextMenuClass()}).prependTo(t)})};if(Observer.videoChange){Observer.videoChange(o)}else{Observer.childList("#bofqi",o)}const i=()=>n.downloadInfo().catch(e=>{s.entity.addError();$(".video-error").text(e)});async function r(){if(!n){return}s.entity.nextMenuClass();const e=await i();e.progress=(e=>{$(".download-progress-value").text(`${fixed(e*100)}`);$(".download-progress-foreground").css("transform",`scaleX(${e})`)});document.querySelector(".download-progress-cancel>span").onclick=(()=>e.cancelDownload());const t=await e.download().catch(e=>{s.entity.addError();$(".video-error").text(e)});if(!t){return}const o=document.getElementById("video-complete");o.setAttribute("href",t.url);o.setAttribute("download",t.filename);o.click();const a=`下载完成. 再次保存`;Toast.success(a,"下载视频");s.entity.resetMenuClass()}async function l(){if(!n){return}const e=await i();e.copyUrl();Toast.success("已复制链接到剪贴板.","复制链接",3e3);s.entity.resetMenuClass()}$(".video-action>#video-action-download").on("click",r);$(".video-action>#video-action-copy").on("click",l);t.applyStyle("downloadVideoStyle");const c=document.querySelector(".download-video-panel");const u=()=>$(".download-video-panel").toggleClass("opened");$("#download-video").on("click",e=>{if(!c.contains(e.target)){u()}});$(".video-error").on("click",()=>{$(".video-error").text("");s.entity.removeError()});await SpinQuery.select(()=>document.querySelector(".download-video-panel"));s.entity.addMenuClass()}return{widget:{content:(t.data.downloadVideoDom||t.data.downloadVideoHtml).text,condition:d,success:c}}}})(); -offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-danmaku.min.js"] = (()=>{return(t,e)=>{const{getFriendlyTitle:n}=e.import("title");const{DanmakuInfo:i}=e.import("video-info");const{DanmakuConverter:o}=e.import("danmaku-converter");async function a(t,e){const a=n();const l=new i((unsafeWindow||window).cid);await l.fetchInfo();const r=await(async()=>{if(e===true){let t={title:a};try{await loadLazyPanel(".bilibili-player-video-danmaku-setting");const e=t=>{const e=parseFloat(document.querySelector(t).style.transform.replace(/translateX\(([\d\.]+)/,"$1"));const n={0:0,44:1,94:2,144:3,188:4}[e];return n};t.font=document.querySelector(".bilibili-player-video-danmaku-setting-right-font .bui-select-result").innerText;t.alpha=parseFloat(document.querySelector(".bilibili-player-setting-opacity .bui-bar").style.transform.replace(/scaleX\(([\d\.]+)\)/,"$1"));t.duration=(()=>{const t=[10,8,6,4,2][e(".bilibili-player-setting-speedplus .bui-thumb")];return e=>{switch(e.type){case 4:case 5:return 4;default:return t}}})();t.blockTypes=(()=>{let t=[];const e={".bilibili-player-block-filter-type[ftype=scroll]":[1,2,3],".bilibili-player-block-filter-type[ftype=top]":[5],".bilibili-player-block-filter-type[ftype=bottom]":[4],".bilibili-player-block-filter-type[ftype=color]":["color"]};for(const[n,i]of Object.entries(e)){if(document.querySelector(n).classList.contains("disabled")){t=t.concat(i)}}return t.concat(7,8)})();const n=[1.4,1.2,1,.8,.6][e(".bilibili-player-setting-fontsize .bui-thumb")];t.resolution={x:1920*n,y:1080*n};t.bottomMarginPercent=[.75,.5,.25,.15,.15][e(".bilibili-player-setting-area .bui-thumb")];t.bold=document.querySelector(".bilibili-player-video-danmaku-setting-right-font-bold input").checked}catch(e){t={font:"微软雅黑",alpha:.6,duration:t=>{switch(t.type){case 4:case 5:return 4;default:return 6}},blockTypes:[],resolution:{x:1920,y:1080},bottomMarginPercent:.15,bold:false}}const e=new o(t);const n=e.convertToAssDocument(l.rawXML);return new Blob([n.generateAss()],{type:"text/plain"})}else{return new Blob([l.rawXML],{type:"text/plain"})}})();const c=URL.createObjectURL(r);const s=$("#danmaku-link");const u=s.attr("href");if(u){URL.revokeObjectURL(u)}clearTimeout(t);document.querySelector("#download-danmaku>span").innerHTML="下载弹幕";s.attr("download",`${a}.${e?"ass":"xml"}`).attr("href",c).get(0).click()}return{widget:{content:`\n \n \n 下载弹幕\n \n `,condition:async()=>{let t=await SpinQuery.select(()=>(unsafeWindow||window).cid);return Boolean(t)},success:()=>{const t=document.querySelector("#danmaku-link");$("#download-danmaku").on("click",e=>{if(e.target!==t){const t=setTimeout(()=>document.querySelector("#download-danmaku>span").innerHTML="请稍侯...",200);a(t,e.shiftKey)}})}}}}})(); +offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-danmaku.min.js"] = (()=>{return(t,e)=>{const{getFriendlyTitle:n}=e.import("title");const{DanmakuInfo:i}=e.import("video-info");const{DanmakuConverter:o}=e.import("danmaku-converter");async function a(t,e){const a=n();const r=new i((unsafeWindow||window).cid);await r.fetchInfo();const l=await(async()=>{if(e===true){let t={title:a};try{await loadLazyPanel(".bilibili-player-video-danmaku-setting");const e=t=>{const e=parseFloat(document.querySelector(t).style.transform.replace(/translateX\(([\d\.]+)/,"$1"));const n={0:0,44:1,94:2,144:3,188:4}[e];return n};t.font=document.querySelector(".bilibili-player-video-danmaku-setting-right-font .bui-select-result").innerText;t.alpha=parseFloat(document.querySelector(".bilibili-player-setting-opacity .bui-bar").style.transform.replace(/scaleX\(([\d\.]+)\)/,"$1"));t.duration=(()=>{const t=[10,8,6,4,2][e(".bilibili-player-setting-speedplus .bui-thumb")];return e=>{switch(e.type){case 4:case 5:return 4;default:return t}}})();t.blockTypes=(()=>{let t=[];const e={".bilibili-player-block-filter-type[ftype=scroll]":[1,2,3],".bilibili-player-block-filter-type[ftype=top]":[5],".bilibili-player-block-filter-type[ftype=bottom]":[4],".bilibili-player-block-filter-type[ftype=color]":["color"]};for(const[n,i]of Object.entries(e)){if(document.querySelector(n).classList.contains("disabled")){t=t.concat(i)}}return t.concat(7,8)})();const n=[1.4,1.2,1,.8,.6][e(".bilibili-player-setting-fontsize .bui-thumb")];t.resolution={x:1920*n,y:1080*n};t.bottomMarginPercent=[.75,.5,.25,0,0][e(".bilibili-player-setting-area .bui-thumb")];if(t.bottomMarginPercent===0&&document.querySelector(".bilibili-player-video-danmaku-setting-left-preventshade input").checked){t.bottomMarginPercent=.15}t.bold=document.querySelector(".bilibili-player-video-danmaku-setting-right-font-bold input").checked}catch(e){t={font:"微软雅黑",alpha:.6,duration:t=>{switch(t.type){case 4:case 5:return 4;default:return 6}},blockTypes:[7,8],resolution:{x:1920,y:1080},bottomMarginPercent:.15,bold:false}}const e=new o(t);const n=e.convertToAssDocument(r.rawXML);return new Blob([n.generateAss()],{type:"text/plain"})}else{return new Blob([r.rawXML],{type:"text/plain"})}})();const c=URL.createObjectURL(l);const s=$("#danmaku-link");const u=s.attr("href");if(u){URL.revokeObjectURL(u)}clearTimeout(t);document.querySelector("#download-danmaku>span").innerHTML="下载弹幕";s.attr("download",`${a}.${e?"ass":"xml"}`).attr("href",c).get(0).click()}return{widget:{content:`\n \n \n 下载弹幕\n \n `,condition:async()=>{let t=await SpinQuery.select(()=>(unsafeWindow||window).cid);return Boolean(t)},success:()=>{const t=document.querySelector("#danmaku-link");$("#download-danmaku").on("click",e=>{if(e.target!==t){const t=setTimeout(()=>document.querySelector("#download-danmaku>span").innerHTML="请稍侯...",200);a(t,e.shiftKey)}})}}}}})(); offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/danmaku-converter.min.js"] = (()=>{return(t,e)=>{class i{constructor(t,e,i,s,n){this.content=t;this.time=e;this.type=parseInt(i);this.fontSize=parseFloat(s);this.color=parseInt(n)}}class s extends i{constructor({content:t,time:e,type:i,fontSize:s,color:n,timeStamp:r,pool:a,userHash:o,rowId:c}){super(t,e,i,s,n);this.timeStamp=parseInt(r);this.pool=parseInt(a);this.userHash=o;this.rowId=parseInt(c);this.time=parseFloat(this.time);this.pDataArray=[e,i,s,n,r,a,o,c]}text(){const t=this.pDataArray.join(",");return`${this.content}`}static parse(t){const e=t.getAttribute("p");const[i,n,r,a,o,c,h,l]=e.split(",");const u=t.innerHTML;return new s({content:u,time:i,type:n,fontSize:r,color:a,timeStamp:o,pool:c,userHash:h,rowId:l})}}class n{constructor(t){this.xml=t;const e=(new DOMParser).parseFromString(t,"application/xml").documentElement;this.danmakus=[...e.querySelectorAll("d[p]")].map(t=>s.parse(t))}}class r extends i{constructor({content:t,time:e,type:i,fontSize:s,color:n,typeTag:r,colorTag:a,endTime:o}){super(t,e,i,s,n);this.typeTag=r;this.colorTag=a;this.endTime=o}text(t){const e=t[this.fontSize].match(/Style:(.*?),/)[1].trim();return`Dialogue: 0,${this.time},${this.endTime},${e},,0,0,0,,{${this.typeTag}${this.colorTag}}${this.content}`}}class a{constructor({danmakus:t,title:e,fontStyles:i,blockTypes:s,resolution:n}){this.danmakus=t;this.title=e;this.fontStyles=i;this.blockTypes=s;this.resolution=n}generateAss(){const t=`\n[Script Info]\n; Script generated by Bilibili Evolved Danmaku Converter\n; https://github.com/the1812/Bilibili-Evolved/\nTitle: ${this.title}\nScriptType: v4.00+\nPlayResX: ${this.resolution.x}\nPlayResY: ${this.resolution.y}\nTimer: 10.0000\nWrapStyle: 2\nScaledBorderAndShadow: no\n\n[V4+ Styles]\nFormat: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\n${Object.values(this.fontStyles).join("\n")}\n\n[Events]\nFormat: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\n `.trim();return t+"\n"+this.danmakus.map(t=>t.text(this.fontStyles,this.blockTypes)).filter(t=>t!=="").join("\n")}}class o{constructor(t,e,i,s){this.horizontalDanmakus=[];this.horizontalTrack=[];this.verticalDanmakus=[];this.verticalTrack=[];this.resolution=e;this.duration=i;this.canvas=document.createElement("canvas");this.context=this.canvas.getContext("2d");this.fontSizes={25:`52px ${t}`,18:`36px ${t}`};this.danmakuType={1:"normal",2:"normal",3:"normal",4:"bottom",5:"top",6:"reversed",7:"special",8:"special"};this.bottomMarginPercent=s;this.margin=4;this.nextDanmakuDelay=.05;this.generateTracks()}generateTracks(){const t=52;this.danmakuHeight=t;this.trackHeight=this.margin*2+t;this.trackCount=parseInt(fixed(this.resolution.y*(1-this.bottomMarginPercent)/this.trackHeight,0))}getTextSize(t){this.context.font=this.fontSizes[t.fontSize];const e=this.context.measureText(t.content);const i=e.width/2;return[i,this.danmakuHeight/2]}getTags(t,{targetTrack:e,initTrack:i,nextTrack:s,isClosestDanmaku:n,getTrackItem:r,getTag:a}){const[o,c]=this.getTextSize(t);const h=o*2;const l=this.duration(t)*h/(this.resolution.x+h)+this.nextDanmakuDelay;let u=i;let m=null;do{m=e.find(t=>n({it:t,track:u,width:h}));u+=s}while(m&&u<=this.trackCount&&u>=0);if(u>this.trackCount||u<0){return`\\pos(0,-999)`}u-=s;e.push(r({track:u,width:h,visibleTime:l}));return a({track:u,x:o,y:c})}getHorizontalTags(t){return this.getTags(t,{targetTrack:this.horizontalTrack,initTrack:0,nextTrack:1,isClosestDanmaku:({it:e,track:i,width:s})=>{if(e.track!==i){return false}if(e.widtht.time}},getTrackItem:({track:e,width:i,visibleTime:s})=>{return{width:i,start:t.time,visible:t.time+s,end:t.time+this.duration(t),track:e}},getTag:({track:e,x:i,y:s})=>{return`\\move(${this.resolution.x+i},${e*this.trackHeight+this.margin+s},${-i},${e*this.trackHeight+this.margin+s},0,${this.duration(t)*1e3})`}})}getVerticalTags(t){const e=this.danmakuType[t.type]==="top";return this.getTags(t,{targetTrack:this.verticalTrack,initTrack:e?0:this.trackCount-1,nextTrack:e?1:-1,isClosestDanmaku:({it:e,track:i})=>{if(e.track!==i){return false}return e.end>t.time},getTrackItem:({track:e})=>{return{start:t.time,end:t.time+this.duration(t),track:e}},getTag:({track:t,y:i})=>{if(e){return`\\pos(${this.resolution.x/2},${t*this.trackHeight+this.margin+i})`}else{return`\\pos(${this.resolution.x/2},${this.resolution.y-this.margin-i-(this.trackCount-1-t)*this.trackHeight})`}}})}push(t){let e=null;let i=null;switch(this.danmakuType[t.type]){case"normal":case"reversed":{e=this.getHorizontalTags(t);i=this.horizontalDanmakus;break}case"top":case"bottom":{e=this.getVerticalTags(t);i=this.verticalDanmakus;break}case"special":default:{return{tags:`\\pos(0,-999)`}}}const s={tags:e};i.push(s);return s}}class c{constructor({title:t,font:e,alpha:i,duration:s,blockTypes:n,resolution:r,bottomMarginPercent:a,bold:c}){this.title=t;this.font=e;this.alpha=Math.round(i*100).toString(16).toUpperCase();this.duration=s;this.blockTypes=n;this.resolution=r;this.bold=c;this.white=16777215;this.danmakuStack=new o(e,r,s,a)}get fontStyles(){return{25:`Style: Medium,${this.font},52,&H${this.alpha}FFFFFF,&H${this.alpha}FFFFFF,&H${this.alpha}000000,&H${this.alpha}000000,${this.bold?"1":"0"},0,0,0,100,100,0,0,1,1.2,0,5,0,0,0,0`,18:`Style: Small,${this.font},36,&H${this.alpha}FFFFFF,&H${this.alpha}FFFFFF,&H${this.alpha}000000,&H${this.alpha}000000,${this.bold?"1":"0"},0,0,0,100,100,0,0,1,1.2,0,5,0,0,0,0`}}convertToAssDocument(t){const e=new n(t);const i=[];for(const t of e.danmakus.sort((t,e)=>t.time-e.time)){if(this.blockTypes.indexOf(t.type)!==-1||this.blockTypes.indexOf("color")!==-1&&t.color!==this.white){continue}const[e,s]=this.convertTime(t.time,this.duration(t));i.push(new r({content:this.convertText(t.content),time:e,endTime:s,type:t.type,fontSize:t.fontSize,color:t.color,typeTag:this.convertType(t),colorTag:this.convertColor(t.color)}))}return new a({danmakus:i,title:this.title,blockTypes:this.blockTypes,fontStyles:this.fontStyles,resolution:this.resolution})}convertText(t){const e={"{":"{","}":"}","&":"&","<":"<",">":">",""":'"',"'":"'"};for(const[i,s]of Object.entries(e)){t=t.replace(new RegExp(i,"g"),s)}return t}convertType(t){return this.danmakuStack.push(t).tags}convertColor(t){if(t===this.white){return""}const e=t.toString(16);const i=e.substring(0,2);const s=e.substring(2,4);const n=e.substring(4,6);return`\\c&H${n}${s}${i}&`}convertTime(t,e){function i(t){const[e,i="00"]=String(t).split(".");return`${e.padStart(2,"0")}.${i.substr(0,2).padEnd(2,"0")}`}function s(t){let e=0;let s=0;while(t>=60){t-=60;s++}while(s>=60){s-=60;e++}return`${e}:${String(s).padStart(2,"0")}:${i(t)}`}return[s(t),s(t+e)]}}return{export:{AssDanmaku:r,AssDanmakuDocument:a,Danmaku:i,DanmakuConverter:c,DanmakuStack:o,XmlDanmaku:s,XmlDanmakuDocument:n}}}})(); offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/video-info.min.js"] = (()=>{return(t,i)=>{class e{constructor(t){this.aid=t}async fetchInfo(){const t=JSON.parse(await downloadText(`https://api.bilibili.com/x/web-interface/view?aid=${this.aid}`));if(t.code!==0){throw new Error(t.message)}const i=t.data;this.cid=i.cid;this.pageCount=i.videos;this.coverUrl=i.pic;this.tagId=i.tid;this.tagName=i.tname;this.title=i.title;this.description=i.desc;this.up={uid:i.owner.mid,name:i.owner.name,faceUrl:i.owner.face};this.pages=i.pages.map(t=>{return{cid:t.cid,title:t.part,pageNumber:t.page}});return this}async fetchDanmaku(){this.danmaku=new s(this.cid);return this.danmaku.fetchInfo()}}class a{constructor(t,i){this.text=t;this.p=i}}class s{constructor(t){this.cid=t}async fetchInfo(){const t=await downloadText(`https://api.bilibili.com/x/v1/dm/list.so?oid=${this.cid}`);this.rawXML=t;const i=(new DOMParser).parseFromString(t,"application/xml").documentElement;this.xml=i;this.danmakus=[].map.call(i.querySelectorAll("d[p]"),t=>{return new a(t.innerHTML,t.getAttribute("p"))})}}class n{constructor(t){this.ep=t;this.videos=[]}async fetchInfo(){const t=await downloadText(`https://www.bilibili.com/bangumi/play/ep${this.ep}/`);const i=JSON.parse(t.match(/window\.__INITIAL_STATE__=(.*);\(function\(\){/)[1]);this.title=i.mediaInfo.title;this.cover=i.mediaInfo.cover;this.squareCover=i.mediaInfo.square_cover;this.aid=i.epInfo.aid;this.cid=i.epInfo.cid;this.videos=i.epList.map(async t=>{return{title:t.index_title,aid:t.aid,cid:t.cid,info:await new e(t.aid).fetchInfo()}});return this}}return{export:{VideoInfo:e,BangumiInfo:n,Danmaku:a,DanmakuInfo:s}}}})(); offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/about.min.html"] = `

      Bilibili Evolved

      开源组件

        `; diff --git a/min/download-danmaku.min.js b/min/download-danmaku.min.js index 0452a866a..6633d7450 100644 --- a/min/download-danmaku.min.js +++ b/min/download-danmaku.min.js @@ -1 +1 @@ -(()=>{return(t,e)=>{const{getFriendlyTitle:n}=e.import("title");const{DanmakuInfo:i}=e.import("video-info");const{DanmakuConverter:o}=e.import("danmaku-converter");async function a(t,e){const a=n();const l=new i((unsafeWindow||window).cid);await l.fetchInfo();const r=await(async()=>{if(e===true){let t={title:a};try{await loadLazyPanel(".bilibili-player-video-danmaku-setting");const e=t=>{const e=parseFloat(document.querySelector(t).style.transform.replace(/translateX\(([\d\.]+)/,"$1"));const n={0:0,44:1,94:2,144:3,188:4}[e];return n};t.font=document.querySelector(".bilibili-player-video-danmaku-setting-right-font .bui-select-result").innerText;t.alpha=parseFloat(document.querySelector(".bilibili-player-setting-opacity .bui-bar").style.transform.replace(/scaleX\(([\d\.]+)\)/,"$1"));t.duration=(()=>{const t=[10,8,6,4,2][e(".bilibili-player-setting-speedplus .bui-thumb")];return e=>{switch(e.type){case 4:case 5:return 4;default:return t}}})();t.blockTypes=(()=>{let t=[];const e={".bilibili-player-block-filter-type[ftype=scroll]":[1,2,3],".bilibili-player-block-filter-type[ftype=top]":[5],".bilibili-player-block-filter-type[ftype=bottom]":[4],".bilibili-player-block-filter-type[ftype=color]":["color"]};for(const[n,i]of Object.entries(e)){if(document.querySelector(n).classList.contains("disabled")){t=t.concat(i)}}return t.concat(7,8)})();const n=[1.4,1.2,1,.8,.6][e(".bilibili-player-setting-fontsize .bui-thumb")];t.resolution={x:1920*n,y:1080*n};t.bottomMarginPercent=[.75,.5,.25,.15,.15][e(".bilibili-player-setting-area .bui-thumb")];t.bold=document.querySelector(".bilibili-player-video-danmaku-setting-right-font-bold input").checked}catch(e){t={font:"微软雅黑",alpha:.6,duration:t=>{switch(t.type){case 4:case 5:return 4;default:return 6}},blockTypes:[],resolution:{x:1920,y:1080},bottomMarginPercent:.15,bold:false}}const e=new o(t);const n=e.convertToAssDocument(l.rawXML);return new Blob([n.generateAss()],{type:"text/plain"})}else{return new Blob([l.rawXML],{type:"text/plain"})}})();const c=URL.createObjectURL(r);const s=$("#danmaku-link");const u=s.attr("href");if(u){URL.revokeObjectURL(u)}clearTimeout(t);document.querySelector("#download-danmaku>span").innerHTML="下载弹幕";s.attr("download",`${a}.${e?"ass":"xml"}`).attr("href",c).get(0).click()}return{widget:{content:`\n \n \n 下载弹幕\n \n `,condition:async()=>{let t=await SpinQuery.select(()=>(unsafeWindow||window).cid);return Boolean(t)},success:()=>{const t=document.querySelector("#danmaku-link");$("#download-danmaku").on("click",e=>{if(e.target!==t){const t=setTimeout(()=>document.querySelector("#download-danmaku>span").innerHTML="请稍侯...",200);a(t,e.shiftKey)}})}}}}})(); \ No newline at end of file +(()=>{return(t,e)=>{const{getFriendlyTitle:n}=e.import("title");const{DanmakuInfo:i}=e.import("video-info");const{DanmakuConverter:o}=e.import("danmaku-converter");async function a(t,e){const a=n();const r=new i((unsafeWindow||window).cid);await r.fetchInfo();const l=await(async()=>{if(e===true){let t={title:a};try{await loadLazyPanel(".bilibili-player-video-danmaku-setting");const e=t=>{const e=parseFloat(document.querySelector(t).style.transform.replace(/translateX\(([\d\.]+)/,"$1"));const n={0:0,44:1,94:2,144:3,188:4}[e];return n};t.font=document.querySelector(".bilibili-player-video-danmaku-setting-right-font .bui-select-result").innerText;t.alpha=parseFloat(document.querySelector(".bilibili-player-setting-opacity .bui-bar").style.transform.replace(/scaleX\(([\d\.]+)\)/,"$1"));t.duration=(()=>{const t=[10,8,6,4,2][e(".bilibili-player-setting-speedplus .bui-thumb")];return e=>{switch(e.type){case 4:case 5:return 4;default:return t}}})();t.blockTypes=(()=>{let t=[];const e={".bilibili-player-block-filter-type[ftype=scroll]":[1,2,3],".bilibili-player-block-filter-type[ftype=top]":[5],".bilibili-player-block-filter-type[ftype=bottom]":[4],".bilibili-player-block-filter-type[ftype=color]":["color"]};for(const[n,i]of Object.entries(e)){if(document.querySelector(n).classList.contains("disabled")){t=t.concat(i)}}return t.concat(7,8)})();const n=[1.4,1.2,1,.8,.6][e(".bilibili-player-setting-fontsize .bui-thumb")];t.resolution={x:1920*n,y:1080*n};t.bottomMarginPercent=[.75,.5,.25,0,0][e(".bilibili-player-setting-area .bui-thumb")];if(t.bottomMarginPercent===0&&document.querySelector(".bilibili-player-video-danmaku-setting-left-preventshade input").checked){t.bottomMarginPercent=.15}t.bold=document.querySelector(".bilibili-player-video-danmaku-setting-right-font-bold input").checked}catch(e){t={font:"微软雅黑",alpha:.6,duration:t=>{switch(t.type){case 4:case 5:return 4;default:return 6}},blockTypes:[7,8],resolution:{x:1920,y:1080},bottomMarginPercent:.15,bold:false}}const e=new o(t);const n=e.convertToAssDocument(r.rawXML);return new Blob([n.generateAss()],{type:"text/plain"})}else{return new Blob([r.rawXML],{type:"text/plain"})}})();const c=URL.createObjectURL(l);const s=$("#danmaku-link");const u=s.attr("href");if(u){URL.revokeObjectURL(u)}clearTimeout(t);document.querySelector("#download-danmaku>span").innerHTML="下载弹幕";s.attr("download",`${a}.${e?"ass":"xml"}`).attr("href",c).get(0).click()}return{widget:{content:`\n \n \n 下载弹幕\n \n `,condition:async()=>{let t=await SpinQuery.select(()=>(unsafeWindow||window).cid);return Boolean(t)},success:()=>{const t=document.querySelector("#danmaku-link");$("#download-danmaku").on("click",e=>{if(e.target!==t){const t=setTimeout(()=>document.querySelector("#download-danmaku>span").innerHTML="请稍侯...",200);a(t,e.shiftKey)}})}}}}})(); \ No newline at end of file diff --git a/video/download-danmaku.js b/video/download-danmaku.js index 5dafb0c08..bacc275a8 100644 --- a/video/download-danmaku.js +++ b/video/download-danmaku.js @@ -68,11 +68,16 @@ async function downloadDanmaku(timeout, ass) x: 1920 * resolutionFactor, y: 1080 * resolutionFactor, }; - config.bottomMarginPercent = [0.75, 0.5, 0.25, 0.15, 0.15][getSliderIndex(".bilibili-player-setting-area .bui-thumb")]; + config.bottomMarginPercent = [0.75, 0.5, 0.25, 0, 0][getSliderIndex(".bilibili-player-setting-area .bui-thumb")]; + if (config.bottomMarginPercent === 0 && document.querySelector(".bilibili-player-video-danmaku-setting-left-preventshade input").checked) // 无显示区域限制时要检查是否开启防挡字幕 + { + config.bottomMarginPercent = 0.15; + } config.bold = document.querySelector(".bilibili-player-video-danmaku-setting-right-font-bold input").checked; } catch (error) { + // The default config config = { font: "微软雅黑", alpha: 0.6, @@ -87,7 +92,7 @@ async function downloadDanmaku(timeout, ass) return 6; } }, - blockTypes: [], + blockTypes: [7, 8], resolution: { x: 1920, y: 1080,