Bilibili-Evolved/min/download-danmaku.min.js
2020-10-18 23:05:26 +08:00

1 line
3.2 KiB
JavaScript

(()=>{return(t,n)=>{const{getFriendlyTitle:e}=n.import("title");const{DanmakuInfo:o}=n.import("video-info");const{DanmakuConverter:a}=n.import("danmaku-converter");async function s(t){const n=e();const o={font:"微软雅黑",alpha:.4,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};let s={...o,title:n};try{await loadDanmakuSettingsPanel();const t=localStorage.getItem("bilibili_player_settings");if(t){const n=JSON.parse(t);const e=(t,e)=>_.get(n,`setting_config.${t}`,e);s.blockTypes=(()=>{const t=[];const e={scroll:[1,2,3],top:[5],bottom:[4],color:["color"]};for(const[o,a]of Object.entries(e)){if(_.get(n,`block.type_${o}`,true)===false){t.push(...a)}}return t.concat(7,8)})();s.bold=e("bold",false);s.alpha=_.clamp(1-parseFloat(e("opacity","0.4")),0,1);const o=1.4-.4*e("fontsize",1);s.resolution={x:Math.round(1920*o),y:Math.round(1080*o)};s.duration=(()=>{const t=18-3*e("speedplus",0);return n=>{switch(n.type){case 4:case 5:return 4;default:return t}}})();const a=e("danmakuArea",0);s.bottomMarginPercent=a>=100?0:a/100;if(s.bottomMarginPercent===0&&e("preventshade",false)){s.bottomMarginPercent=.15}const r=_.get(n,"block.list",[]);s.blockFilter=(t=>{for(const n of r){if(!n.s){continue}switch(n.t){case"keyword":{if(t.content.includes(n.v)){return false}break}case"regexp":{if(new RegExp(n.v).test(t.content)){return false}break}case"user":{if(t.userHash===n.v){return false}break}}}return true})}else{console.warn("[弹幕转换] 未找到播放器设置");s={...s,...o}}s.font=dq(".bilibili-player-video-danmaku-setting-right-font .bui-select-result").innerText}catch(t){logError(t);s={...s,...o}}for(const[t,n]of Object.entries(s)){if(n===undefined||n===null){console.warn("danmaku config invalid for key",t,", value =",n);s[t]=o[n]}}console.log(s);const r=new a(s);const c=r.convertToAssDocument(t);return c.generateAss()}async function r(t){const n=e();const a=new o((unsafeWindow||window).cid);await a.fetchInfo();const r=await(async()=>{if(t===true){return new Blob([await s(a.rawXML)],{type:"text/plain"})}else{return new Blob([a.rawXML],{type:"text/plain"})}})();const c=URL.createObjectURL(r);const i=dq("#danmaku-link");const l=i.getAttribute("href");if(l){URL.revokeObjectURL(l)}i.setAttribute("download",`${n}.${t?"ass":"xml"}`);i.setAttribute("href",c);i.click()}return{export:{downloadDanmaku:r,convertToAss:s},widget:{content:`\n<a id="danmaku-link" style="display:none"></a>\n<button\n class="gui-settings-flat-button"\n id="download-danmaku-xml">\n<i class="icon-danmaku"></i>\n<span>下载弹幕<span>(XML)</span></span>\n</button>\n<button\n class="gui-settings-flat-button"\n id="download-danmaku-ass">\n<i class="icon-danmaku"></i>\n<span>下载弹幕<span>(ASS)</span></span>\n</button>\n`,condition:async()=>{let t=await SpinQuery.select(()=>(unsafeWindow||window).cid);return Boolean(t)},success:()=>{const t=dq("#download-danmaku-xml");const n=dq("#download-danmaku-ass");const e=[t,n];const o=(t,n)=>{t.addEventListener("click",async()=>{try{e.forEach(t=>t.disabled=true);await r(n)}catch(t){logError(t)}finally{e.forEach(t=>t.disabled=false)}})};o(t,false);o(n,true)}}}}})();