diff --git a/bilibili-evolved.offline.user.js b/bilibili-evolved.offline.user.js index 61e9ecfa3..98e588813 100644 --- a/bilibili-evolved.offline.user.js +++ b/bilibili-evolved.offline.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name Bilibili Evolved (Offline) -// @version 126.05 +// @version 126.17 // @description 增强哔哩哔哩Web端体验(离线版): 修复界面瑕疵, 删除广告, 使用夜间模式浏览, 下载视频或视频封面, 以及增加对触屏设备的支持等. // @author Grant Howard, Coulomb-G // @copyright 2018, Grant Howrad (https://github.com/the1812) @@ -56,6 +56,7 @@ blurBackgroundOpacity: 0.382, defaultPlayerMode: "常规", autoLightOff: false, + downloadDanmaku: false, useCache: true, cache: {}, }; @@ -394,6 +395,9 @@ "downloadVideoStyle", "videoInfo", ], + displayNames: { + "downloadDanmaku": "下载视频时包含弹幕", + }, }, videoInfo: { path: "min/video-info.min.js", @@ -859,7 +863,7 @@ offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/m offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/gui-settings.min.html"] = `
设置
    样式
  • 工具视频与直播
  • 触摸优化其他
`; offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/image-viewer.min.html"] = `
`; offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.html"] = ``; -offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/version.txt"] = `1.5.37`; +offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/version.txt"] = `1.5.38`; offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/gui-settings.min.js"] = (()=>{return(e,t)=>{const n={red:"#e57373",pink:"#F06292",purple:"#BA68C8",deepPurple:"#9575CD",indigo:"#7986CB",blue:"#2196F3",lightBlue:"#00A0D8",cyan:"#00ACC1",teal:"#26A69A",green:"#81C784",lightGreen:"#9CCC65",orange:"#FF9800",deepOrange:"#FF7043",brown:"#A1887F",grey:"#757575",blueGrey:"#78909C"};const i={settings:"M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z",close:"M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z",ok:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"};const o={forceWideMinWidth:e=>e,customStyleColor:t=>{const n=t.match(/^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/);if(n){if(t.length<7){return`#${t[1]}${t[1]}${t[2]}${t[2]}${t[3]}${t[3]}`}else{return t}}else{return e.customStyleColor}},blurBackgroundOpacity:t=>{const n=t.match(/^([-\+]?\d+)(\.\d+)?$/);if(n){const e=parseFloat(t);if(e>=0&&e<=1){return t}}return e.blurBackgroundOpacity},defaultPlayerMode:t=>{if(["常规","宽屏","网页全屏"].indexOf(t)!==-1){return t}return e.defaultPlayerMode}};function s(e){let t=e.nextElementSibling;const n=[];while(t!==null&&!t.classList.contains("category")){n.push(t);t=t.nextElementSibling}return n}function c(e,t){const n=e.match(/^([\d]{1,2}):([\d]{1,2})$/);if(n&&n.length>=3){const e={hour:parseInt(n[1]),minute:parseInt(n[2])};(function(){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}}).call(e);return`${e.hour}:${e.minute<10?"0"+e.minute:e.minute}`}else{return t}}o.darkScheduleStart=(t=>c(t,e.darkScheduleStart));o.darkScheduleEnd=(t=>c(t,e.darkScheduleEnd));function a(e,t){const n=e.match(/^([-\+]?\d+)(\.\d+)?$/);if(n){const t=parseFloat(e);if(t>=0&&t<=1){return e}}return t}o.blurBackgroundOpacity=(t=>a(t,e.blurBackgroundOpacity));o.customControlBackgroundOpacity=(t=>a(t,e.customControlBackgroundOpacity));function r(e,t,n){$(`input[type='checkbox'][key='${e}']`).prop("checked",n);$(`input[type='text'][key='${e}']`).val(n)}function l(){for(const t in e){r(t,undefined,e[t])}$(".gui-settings-content ul li.category").each((e,t)=>{const n=s(t);if(n.filter(e=>!e.classList.contains("disabled")).every(e=>$(e).has("input:checked").length===0)){$(t).click()}})}function u(){$(".gui-settings-header .gui-settings-close").on("click",()=>{$(".gui-settings-panel").removeClass("opened")});$("input[key='customStyleColor']").on("input",()=>{const e=o.customStyleColor($("input[key='customStyleColor']").val());$("div.custom-color-preview").css("background",e)});$("input[type='text'][key]").each((t,n)=>{$(n).attr("placeholder",e[$(n).attr("key")])});$("div.custom-color-preview").on("click",()=>{const e=$(".predefined-colors");e.toggleClass("opened")});$(".gui-settings-content ul li.category").on("click",e=>{e.currentTarget.classList.toggle("folded");s(e.currentTarget).forEach(e=>e.classList.toggle("folded"))});$(".gui-settings-dropdown>input").on("click",e=>{$(e.currentTarget).parent().toggleClass("opened")});$(".gui-settings-panel").on("click",e=>{if(e.target===document.querySelector(".gui-settings-panel")){$(".gui-settings-panel .popup").removeClass("opened")}});onSettingsChange(r)}function d(){const t=()=>{$("input[type='checkbox'][key]").each((t,n)=>{e[$(n).attr("key")]=$(n).prop("checked")});$("input[type='text'][key]").each((t,n)=>{const i=$(n);const s=i.attr("key");const c=o[s](i.val());e[s]=c;i.val(c)});saveSettings(e)};$("input[type='checkbox'][key]").on("change",()=>t());$("input[type='text'][key]").on("change",()=>t())}function p(){$(".gui-settings-close path").attr("d",i.close);$(".gui-settings-ok path").attr("d",i.ok);$(".gui-settings svg path").attr("d",i.settings)}function g(){const e={};$(`input[dependencies]`).each((t,n)=>{const i=$(n).attr("dependencies");if(i){e[$(n).attr("key")]=i}});const t=t=>{const n=t.prop("checked");for(const i in e){const o=e[i].split(" ");if(o.indexOf(t.attr("key"))!==-1){let e=true;if(n&&o.every(e=>$(`input[key='${e}']`).prop("checked"))){e=false}const t=$(`li:has(input[key='${i}'])`);const s=e?"addClass":"removeClass";t[s]("disabled");$(`input[key='${i}'][type='text']`).parent()[s]("disabled")}}$(".gui-settings-panel .popup").removeClass("opened")};$(`input[type='checkbox'][key]`).on("change",e=>t($(e.target))).each((e,n)=>t($(n)))}function h(e){if($(".gui-settings").length===0){e.append(`
\n \n \n \n
`);$(".gui-settings").on("click",()=>{$(".gui-settings-panel").addClass("opened")})}t.applyStyle("guiSettingsStyle")}function y(){const e=$(".predefined-colors-grid");for(const t of Object.values(n)){$(`
`).appendTo(e).css("background",t).attr("data-color",t).on("click",e=>{$(`input[key='customStyleColor']`).val($(e.target).attr("data-color")).trigger("input").change();$("div.custom-color-preview").on("click")})}}function f(){if(e.blurSettingsPanel){$(".gui-settings-box").addClass("blur")}else{$(".gui-settings-panel").addClass("animation")}}function k(){if(typeof offlineData!=="undefined"){$("li:has(input[key=useCache])").addClass("disabled");$("input[key=useCache]").prop("disabled",true)}}h($("body"));const C=t.data.guiSettingsDom.text;if(C){$("body").append(C);u();p();k();l();g();y();d();f()}new SpinQuery(()=>$("body"),e=>e.length>0&&!(unsafeWindow.parent.window===unsafeWindow),e=>$(".gui-settings-icon-panel").css("display","none")).start()}})(); offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/dark-styles.min.js"] = (()=>{return(l,e)=>{if(l.useDarkStyle){e.applyStyle("scrollbarStyle");SpinQuery.any(()=>$(".custom-scrollbar"),l=>l.removeClass("custom-scrollbar"));if($("#banner_link").length===0||$("#banner_link").length>0&&l.overrideNavBar&&!l.showBanner){e.applyImportantStyle("darkStyleNavBar")}e.applyStyle("darkStyle");e.applyImportantStyle("darkStyleImportant")}else{$("#bilibili-scrollbar-style,#bilibili-new-style-dark-nav-bar,#bilibili-new-style-dark,#bilibili-new-style-dark-important").remove()}}})(); offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/new-styles.min.js"] = (()=>{return(e,t)=>{if(document.URL===`https://h.bilibili.com/`){return}SpinQuery.any(()=>$(".custom-scrollbar"),e=>e.removeClass("custom-scrollbar"));const l={selectors:["div.nav-con.fl","#link-navbar-vm",".link-navbar",".nav-header-wrapper",".z_top .z_header"],get allSelectors(){return this.selectors.reduce((e,t)=>e+","+t)},get navbar(){let e=null;for(const t of this.selectors){e=e||document.querySelector(t)}return e},supports(e){if(e instanceof Element){const t=parseInt(window.getComputedStyle(e).height);const l=[60,50,0,56];return l.indexOf(t)!==-1}return false}};SpinQuery.any(()=>$(l.allSelectors),()=>{const e=l.navbar;if(l.supports(e)){t.applyStyle("style","bilibili-style-optimization")}else{t.applyStyle("oldStyle","bilibili-style-optimization")}})}})(); @@ -881,8 +885,8 @@ 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 s{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 s=this.greaterThan(e)&&this.lessThan(t);if(e.greaterThan(t)){s=this.greaterThan(e)||this.lessThan(t)}const i=s||this.equals(e);return i}static millisecondsBefore(e){const t=new s;const i=(new Date).getSeconds();const r=1e3*(t.hour*3600+t.minute*60+i);const n=1e3*(e.hour*3600+e.minute*60);let h=n-r;if(t.greaterThan(e)||t.equals(e)&&i!==0){h+=24*3600*1e3}return h}}function i(){if(e.darkSchedule){const r=new s(e.darkScheduleStart);const n=new s(e.darkScheduleEnd);const h=new s;const u=h.isInRange(r,n);if(e.useDarkStyle!==u){e.useDarkStyle=u;saveSettings(e);t.fetchByKey("useDarkStyle")}let o=0;if(u){o=s.millisecondsBefore(n)}else{o=s.millisecondsBefore(r)}if(o!==0){setTimeout(()=>i(),o)}}}i();return{export:s}}})(); offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/force-wide.min.js"] = (()=>{return(e,t)=>{t.applyImportantStyle("forceWideStyle")}})(); offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/clear-cache.min.js"] = (()=>{return(e,t)=>{return{settingsWidget:{category:"其他",content:`
\n \n 清除缓存\n \n
`,success:()=>{$("#clear-cache").on("click",()=>{e.cache={};Toast.success("已删除全部缓存.","清除缓存",5e3)});if(typeof offlineData!=="undefined"){$("button#clear-cache").parent().addClass("hidden")}}}}}})(); -offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.js"] = (()=>{return(e,t)=>{const o=t.attributes.videoInfo.export.VideoInfo;const n=t.attributes.videoInfo.export.BangumiInfo;const s={aid:undefined,cid:undefined,isBangumi:false,isMovie:false};class i{constructor(e,t,o){this.quality=e;this.internalName=t;this.displayName=o}async downloadInfo(){const e=new r(this);await e.fetchVideoInfo();return e}static get availableFormats(){return new Promise((e,t)=>{const o=`https://api.bilibili.com/x/player/playurl?avid=${s.aid}&cid=${s.cid}&otype=json`;const n=new XMLHttpRequest;n.addEventListener("load",()=>{const o=JSON.parse(n.responseText);if(o.code!==0){t("获取清晰度信息失败.")}const s=o.data;const a=s.accept_quality;const r=s.accept_format.split(",");const d=s.accept_description;const l=[];while(a.length>0){const e=new i(a.pop(),r.pop(),d.pop());l.push(e)}e(l)});n.addEventListener("error",()=>t(`获取清晰度信息失败.`));n.withCredentials=true;n.open("GET",o);n.send()})}}class a{constructor(e,t,o,n){this.length=e;this.size=t;this.url=o;this.backupUrls=n}}class r{constructor(e,t){this.format=e;this.fragments=t||[];this.progress=null;this.loaded=0;this.totalSize=null;this.workingXhr=null}fetchVideoInfo(){return new Promise((e,t)=>{const o=`https://api.bilibili.com/x/player/playurl?avid=${s.aid}&cid=${s.cid}&qn=${this.format.quality}&otype=json`;const n=new XMLHttpRequest;n.addEventListener("load",()=>{const o=JSON.parse(n.responseText.replace(/http:/g,"https:")).data;if(o.quality!==this.format.quality){t("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const s=o.durl;this.fragments=s.map(e=>new a(e.length,e.size,e.url,e.backup_url));e(this.fragments)});n.withCredentials=true;n.open("GET",o);n.send()})}cancelDownload(){if(this.workingXhr){this.workingXhr.abort()}}downloadUrl(e){return new Promise((t,o)=>{const n=new XMLHttpRequest;n.open("GET",e);n.responseType="arraybuffer";n.withCredentials=false;n.addEventListener("progress",e=>{this.progress&&this.progress((this.loaded+e.loaded)/this.totalSize)});n.addEventListener("load",()=>{if(n.status===200){t(n.response)}else{o(`请求失败.`)}});n.addEventListener("abort",()=>o("下载已取消."));n.addEventListener("error",()=>o(`下载失败.`));n.send();this.workingXhr=n})}copyUrl(){const e=this.fragments.map(e=>e.url).reduce((e,t)=>e+"\r\n"+t);GM_setClipboard(e,"text")}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 o=await this.downloadUrl(t.url);this.loaded+=t.size;e.push(o)}if(e.length<1){throw new Error("下载失败.")}let t=null;let o=null;const n=e=>(e||this.fragments[0]).url.indexOf(".flv")!==-1?".flv":".mp4";if(e.length===1){const[s]=e;t=new Blob([s],{type:n()===".flv"?"video/x-flv":"video/mp4"});o=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","")+n()}else{const s=new JSZip;const i=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","");e.forEach((e,t)=>{s.file(`${i} - ${t+1}${n(this.fragments[t])}`,e)});t=await s.generateAsync({type:"blob"});o=i+".zip"}const s=URL.createObjectURL(t);const i=$("a#video-complete").attr("href");if(i&&$(`.link[href=${i}]`).length===0){URL.revokeObjectURL(i)}this.progress&&this.progress(0);return{url:s,filename:o}}}function d(){(async()=>{let e=(unsafeWindow||window).aid;let t=(unsafeWindow||window).cid;if(e===undefined||t===undefined){const n=document.URL.match(/\/av(\d+)/);const s=document.URL.match(/\/ep(\d+)/);if(n&&n[1]){const s=await new o(n[1]).fetchInfo();e=s.aid;t=s.cid}}return[e,t]})().then(e=>{const[o,n]=e;if(o===undefined||n===undefined){return}s.aid=o;s.cid=n;i.availableFormats.then(e=>{let[o]=e;const n=()=>o.downloadInfo().catch(e=>{$(".download-video-panel").addClass("error");$(".video-error").text(e)});async function s(){if(!o){return}$(".download-video-panel").removeClass("action").addClass("progress");const e=await n();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=>{$(".download-video-panel").addClass("error");$(".video-error").text(e)});if(!t){return}const s=document.getElementById("video-complete");s.setAttribute("href",t.url);s.setAttribute("download",t.filename);s.click();const i=`下载完成. 再次保存`;Toast.success(i,"下载视频");$(".download-video-panel").removeClass("progress").addClass("quality")}async function i(){if(!o){return}const e=await n();e.copyUrl();Toast.success("已复制链接到剪贴板.","复制链接",3e3);$(".download-video-panel").removeClass("action").addClass("quality")}$(".video-action>#video-action-download").on("click",s);$(".video-action>#video-action-copy").on("click",i);e.forEach(e=>{$(`
  • ${e.displayName}
  • `).on("click",()=>{o=e;$(".download-video-panel").removeClass("quality").addClass("action")}).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")})})}return{settingsWidget:{category:"视频与直播",content:t.data.downloadVideoDom.text,success:d}}}})(); -offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/video-info.min.js"] = (()=>{return()=>{class t{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}}class i{constructor(t,i){this.text=t;this.p=i}}class e{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 e=(new DOMParser).parseFromString(t,"application/xml").documentElement;this.xml=e;this.danmakus=[].map.call(e.querySelectorAll("d[p]"),t=>{return new i(t.innerHTML,t.getAttribute("p"))})}}class a{constructor(t){this.ep=t;this.videos=[]}async fetchInfo(){const i=await downloadText(`https://www.bilibili.com/bangumi/play/ep${this.ep}/`);const e=JSON.parse(i.match(/window\.__INITIAL_STATE__=(.*);\(function\(\){/)[1]);this.title=e.mediaInfo.title;this.cover=e.mediaInfo.cover;this.squareCover=e.mediaInfo.square_cover;this.aid=e.epInfo.aid;this.cid=e.epInfo.cid;this.videos=e.epList.map(async i=>{return{title:i.index_title,aid:i.aid,cid:i.cid,info:await new t(i.aid).fetchInfo()}});return this}}return{export:{VideoInfo:t,BangumiInfo:a,Danmaku:i,DanmakuInfo:e}}}})(); +offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.js"] = (()=>{return(e,t)=>{const o=t.attributes.videoInfo.export.VideoInfo;const n=t.attributes.videoInfo.export.BangumiInfo;const s=t.attributes.videoInfo.export.DanmakuInfo;const i={aid:undefined,cid:undefined,isBangumi:false,isMovie:false};class a{constructor(e,t,o){this.quality=e;this.internalName=t;this.displayName=o}async downloadInfo(){const e=new l(this);await e.fetchVideoInfo();return e}static get availableFormats(){return new Promise((e,t)=>{const o=`https://api.bilibili.com/x/player/playurl?avid=${i.aid}&cid=${i.cid}&otype=json`;const n=new XMLHttpRequest;n.addEventListener("load",()=>{const o=JSON.parse(n.responseText);if(o.code!==0){t("获取清晰度信息失败.")}const s=o.data;const i=s.accept_quality;const r=s.accept_format.split(",");const l=s.accept_description;const d=[];while(i.length>0){const e=new a(i.pop(),r.pop(),l.pop());d.push(e)}e(d)});n.addEventListener("error",()=>t(`获取清晰度信息失败.`));n.withCredentials=true;n.open("GET",o);n.send()})}}class r{constructor(e,t,o,n){this.length=e;this.size=t;this.url=o;this.backupUrls=n}}class l{constructor(e,t){this.format=e;this.fragments=t||[];this.progress=null;this.loaded=0;this.totalSize=null;this.workingXhr=null}fetchVideoInfo(){return new Promise((e,t)=>{const o=`https://api.bilibili.com/x/player/playurl?avid=${i.aid}&cid=${i.cid}&qn=${this.format.quality}&otype=json`;const n=new XMLHttpRequest;n.addEventListener("load",()=>{const o=JSON.parse(n.responseText.replace(/http:/g,"https:")).data;if(o.quality!==this.format.quality){t("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const s=o.durl;this.fragments=s.map(e=>new r(e.length,e.size,e.url,e.backup_url));e(this.fragments)});n.withCredentials=true;n.open("GET",o);n.send()})}cancelDownload(){if(this.workingXhr){this.workingXhr.abort()}}downloadUrl(e){return new Promise((t,o)=>{const n=new XMLHttpRequest;n.open("GET",e);n.responseType="arraybuffer";n.withCredentials=false;n.addEventListener("progress",e=>{this.progress&&this.progress((this.loaded+e.loaded)/this.totalSize)});n.addEventListener("load",()=>{if(n.status===200){t(n.response)}else{o(`请求失败.`)}});n.addEventListener("abort",()=>o("下载已取消."));n.addEventListener("error",()=>o(`下载失败.`));n.send();this.workingXhr=n})}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"}cleanUpOldBlobUrl(){const e=$("a#video-complete").attr("href");if(e&&$(`.link[href=${e}]`).length===0){URL.revokeObjectURL(e)}}downloadSingle(e){const[t]=e;const o=new Blob([t],{type:this.extension()===".flv"?"video/x-flv":"video/mp4"});const n=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","")+this.extension();return[o,n]}async downloadMultiple(e){const t=new JSZip;const o=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","");if(e.length>1){e.forEach((e,n)=>{t.file(`${o} - ${n+1}${this.extension(this.fragments[n])}`,e)})}else{t.file(`${o}}${this.extension()}`,data)}if(settings.downloadDanmaku){const e=new s(i.cid);await e.fetchInfo();t.file(`${o}.xml`,e.rawXML)}const n=await t.generateAsync({type:"blob"});const a=o+".zip";return[n,a]}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 o=await this.downloadUrl(t.url);this.loaded+=t.size;e.push(o)}if(e.length<1){throw new Error("下载失败.")}let t=null;let o=null;if(e.length===1&&!settings.downloadDanmaku){[t,o]=this.downloadSingle(e)}else{[t,o]=await this.downloadMultiple(e)}const n=URL.createObjectURL(t);this.cleanUpOldBlobUrl();this.progress&&this.progress(0);return{url:n,filename:o}}}function d(){(async()=>{let e=(unsafeWindow||window).aid;let t=(unsafeWindow||window).cid;if(e===undefined||t===undefined){const n=document.URL.match(/\/av(\d+)/);const s=document.URL.match(/\/ep(\d+)/);if(n&&n[1]){const s=await new o(n[1]).fetchInfo();e=s.aid;t=s.cid}}return[e,t]})().then(e=>{const[o,n]=e;if(o===undefined||n===undefined){return}i.aid=o;i.cid=n;a.availableFormats.then(e=>{let[o]=e;const n=()=>o.downloadInfo().catch(e=>{$(".download-video-panel").addClass("error");$(".video-error").text(e)});async function s(){if(!o){return}$(".download-video-panel").removeClass("action").addClass("progress");const e=await n();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=>{$(".download-video-panel").addClass("error");$(".video-error").text(e)});if(!t){return}const s=document.getElementById("video-complete");s.setAttribute("href",t.url);s.setAttribute("download",t.filename);s.click();const i=`下载完成. 再次保存`;Toast.success(i,"下载视频");$(".download-video-panel").removeClass("progress").addClass("quality")}async function i(){if(!o){return}const e=await n();e.copyUrl();Toast.success("已复制链接到剪贴板.","复制链接",3e3);$(".download-video-panel").removeClass("action").addClass("quality")}$(".video-action>#video-action-download").on("click",s);$(".video-action>#video-action-copy").on("click",i);e.forEach(e=>{$(`
  • ${e.displayName}
  • `).on("click",()=>{o=e;$(".download-video-panel").removeClass("quality").addClass("action")}).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")})})}return{settingsWidget:{category:"视频与直播",content:t.data.downloadVideoDom.text,success:d}}}})(); +offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/video-info.min.js"] = (()=>{return()=>{class t{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 e(this.cid);return this.danmaku.fetchInfo()}}class i{constructor(t,i){this.text=t;this.p=i}}class e{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 e=(new DOMParser).parseFromString(t,"application/xml").documentElement;this.xml=e;this.danmakus=[].map.call(e.querySelectorAll("d[p]"),t=>{return new i(t.innerHTML,t.getAttribute("p"))})}}class a{constructor(t){this.ep=t;this.videos=[]}async fetchInfo(){const i=await downloadText(`https://www.bilibili.com/bangumi/play/ep${this.ep}/`);const e=JSON.parse(i.match(/window\.__INITIAL_STATE__=(.*);\(function\(\){/)[1]);this.title=e.mediaInfo.title;this.cover=e.mediaInfo.cover;this.squareCover=e.mediaInfo.square_cover;this.aid=e.epInfo.aid;this.cid=e.epInfo.cid;this.videos=e.epList.map(async i=>{return{title:i.index_title,aid:i.aid,cid:i.cid,info:await new t(i.aid).fetchInfo()}});return this}}return{export:{VideoInfo:t,BangumiInfo:a,Danmaku:i,DanmakuInfo:e}}}})(); offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/about.min.html"] = `

    Bilibili Evolved

    开源组件

      `; offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/about.min.scss"] = `.about.gui-settings-footer{height:24px;font-size:14px;justify-content:space-between;padding:6px 24px;border-top:1px dashed #8884;}.about.gui-settings-footer>span{opacity:0.2;}.bilibili-evolved-about{display:flex;width:400px;height:70vh;background-color:white;position:fixed;top:15%;left:calc(50% - 200px);z-index:100000;box-shadow:0px 3px 20px 2px #0004;border-top:4px solid $customStyleColor;flex-direction:column;transition:all .2s ease-out;transform-origin:center;transform:scale(0);}.bilibili-evolved-about.opened{transform:scale(1);}.bilibili-evolved-info a{margin:0 4px;}.bilibili-evolved-info>p{margin:8px 0;}.bilibili-evolved-about>div{flex:1 0 0;display:flex;align-items:center;justify-content:space-between;flex-direction:column;padding:8px;}.bilibili-evolved-about>div.about-block{flex:4 0 0;padding:32px;align-items:stretch;}.bilibili-evolved-about h1{font-size:36px;margin-bottom:16px;}.bilibili-evolved-about h2{font-size:18px;margin-bottom:8px;}.open-source-components>li{margin:12px 0;padding:12px 24px;background:rgba(0,0,0,0.2);border-left:4px solid $customStyleColor;cursor:pointer;transition:all .2s ease-out;}.open-source-components>li:hover{opacity:0.8;}.component-name{font-size:18px;font-weight:bold;}.component-info{margin-top:8px;}#about-link{cursor:pointer;transition:all .2s;}.bilibili-evolved-about a{color:$customStyleColor;}#about-link:hover{opacity:1;color:$customStyleColor;}#about-close{background-color:#8884;border-color:transparent;opacity:1;transition:all .2s ease-out;width:80px;height:32px;color:inherit;cursor:pointer;}#about-close:hover{opacity:0.8;}#about-close:active{outline:none;opacity:0.6;}`; offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/about.min.js"] = (()=>{return(e,n)=>{$("body").append(n.data.aboutDom.text);const i=GM_info.script.name.replace("Bilibili Evolved","").replace(/^[\(\) ]+|[\(\) ]+$/g,"")+" · "+e.currentVersion;$(".bilibili-evolved-version").text(i);const o=[{name:"jQuery",homepage:"https://jquery.com/",license:"MIT",version:"3.2.1"},{name:"JSZip",homepage:"https://stuk.github.io/jszip/",license:"MIT",version:"3.1.5"}];o.forEach(e=>{$(".open-source-components").append(`\n
    • \n \n
      ${e.name}
      \n
      ${e.version} · ${e.license}
      \n
      \n
    • \n `)});function t(){n.applyStyle("aboutStyle");$("#about-link,#about-close").on("click",()=>{$(".bilibili-evolved-about").toggleClass("opened")})}return{settingsWidget:{after:()=>$(".gui-settings-content"),content:`\n `,success:t}}}})(); diff --git a/bilibili-evolved.preview-offline.user.js b/bilibili-evolved.preview-offline.user.js index 486914fe4..8afa2e06c 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 126.05 +// @version 126.17 // @description 增强哔哩哔哩Web端体验(预览离线版): 修复界面瑕疵, 删除广告, 使用夜间模式浏览, 下载视频或视频封面, 以及增加对触屏设备的支持等. // @author Grant Howard, Coulomb-G // @copyright 2018, Grant Howrad (https://github.com/the1812) @@ -56,6 +56,7 @@ blurBackgroundOpacity: 0.382, defaultPlayerMode: "常规", autoLightOff: false, + downloadDanmaku: false, useCache: true, cache: {}, }; @@ -394,6 +395,9 @@ "downloadVideoStyle", "videoInfo", ], + displayNames: { + "downloadDanmaku": "下载视频时包含弹幕", + }, }, videoInfo: { path: "min/video-info.min.js", @@ -859,7 +863,7 @@ offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/m offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/gui-settings.min.html"] = `
      设置
        样式
      • 工具视频与直播
      • 触摸优化其他
      `; offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/image-viewer.min.html"] = `
      `; offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.html"] = ``; -offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/version.txt"] = `1.5.37`; +offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/version.txt"] = `1.5.38`; offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/gui-settings.min.js"] = (()=>{return(e,t)=>{const n={red:"#e57373",pink:"#F06292",purple:"#BA68C8",deepPurple:"#9575CD",indigo:"#7986CB",blue:"#2196F3",lightBlue:"#00A0D8",cyan:"#00ACC1",teal:"#26A69A",green:"#81C784",lightGreen:"#9CCC65",orange:"#FF9800",deepOrange:"#FF7043",brown:"#A1887F",grey:"#757575",blueGrey:"#78909C"};const i={settings:"M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z",close:"M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z",ok:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"};const o={forceWideMinWidth:e=>e,customStyleColor:t=>{const n=t.match(/^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/);if(n){if(t.length<7){return`#${t[1]}${t[1]}${t[2]}${t[2]}${t[3]}${t[3]}`}else{return t}}else{return e.customStyleColor}},blurBackgroundOpacity:t=>{const n=t.match(/^([-\+]?\d+)(\.\d+)?$/);if(n){const e=parseFloat(t);if(e>=0&&e<=1){return t}}return e.blurBackgroundOpacity},defaultPlayerMode:t=>{if(["常规","宽屏","网页全屏"].indexOf(t)!==-1){return t}return e.defaultPlayerMode}};function s(e){let t=e.nextElementSibling;const n=[];while(t!==null&&!t.classList.contains("category")){n.push(t);t=t.nextElementSibling}return n}function c(e,t){const n=e.match(/^([\d]{1,2}):([\d]{1,2})$/);if(n&&n.length>=3){const e={hour:parseInt(n[1]),minute:parseInt(n[2])};(function(){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}}).call(e);return`${e.hour}:${e.minute<10?"0"+e.minute:e.minute}`}else{return t}}o.darkScheduleStart=(t=>c(t,e.darkScheduleStart));o.darkScheduleEnd=(t=>c(t,e.darkScheduleEnd));function a(e,t){const n=e.match(/^([-\+]?\d+)(\.\d+)?$/);if(n){const t=parseFloat(e);if(t>=0&&t<=1){return e}}return t}o.blurBackgroundOpacity=(t=>a(t,e.blurBackgroundOpacity));o.customControlBackgroundOpacity=(t=>a(t,e.customControlBackgroundOpacity));function r(e,t,n){$(`input[type='checkbox'][key='${e}']`).prop("checked",n);$(`input[type='text'][key='${e}']`).val(n)}function l(){for(const t in e){r(t,undefined,e[t])}$(".gui-settings-content ul li.category").each((e,t)=>{const n=s(t);if(n.filter(e=>!e.classList.contains("disabled")).every(e=>$(e).has("input:checked").length===0)){$(t).click()}})}function u(){$(".gui-settings-header .gui-settings-close").on("click",()=>{$(".gui-settings-panel").removeClass("opened")});$("input[key='customStyleColor']").on("input",()=>{const e=o.customStyleColor($("input[key='customStyleColor']").val());$("div.custom-color-preview").css("background",e)});$("input[type='text'][key]").each((t,n)=>{$(n).attr("placeholder",e[$(n).attr("key")])});$("div.custom-color-preview").on("click",()=>{const e=$(".predefined-colors");e.toggleClass("opened")});$(".gui-settings-content ul li.category").on("click",e=>{e.currentTarget.classList.toggle("folded");s(e.currentTarget).forEach(e=>e.classList.toggle("folded"))});$(".gui-settings-dropdown>input").on("click",e=>{$(e.currentTarget).parent().toggleClass("opened")});$(".gui-settings-panel").on("click",e=>{if(e.target===document.querySelector(".gui-settings-panel")){$(".gui-settings-panel .popup").removeClass("opened")}});onSettingsChange(r)}function d(){const t=()=>{$("input[type='checkbox'][key]").each((t,n)=>{e[$(n).attr("key")]=$(n).prop("checked")});$("input[type='text'][key]").each((t,n)=>{const i=$(n);const s=i.attr("key");const c=o[s](i.val());e[s]=c;i.val(c)});saveSettings(e)};$("input[type='checkbox'][key]").on("change",()=>t());$("input[type='text'][key]").on("change",()=>t())}function p(){$(".gui-settings-close path").attr("d",i.close);$(".gui-settings-ok path").attr("d",i.ok);$(".gui-settings svg path").attr("d",i.settings)}function g(){const e={};$(`input[dependencies]`).each((t,n)=>{const i=$(n).attr("dependencies");if(i){e[$(n).attr("key")]=i}});const t=t=>{const n=t.prop("checked");for(const i in e){const o=e[i].split(" ");if(o.indexOf(t.attr("key"))!==-1){let e=true;if(n&&o.every(e=>$(`input[key='${e}']`).prop("checked"))){e=false}const t=$(`li:has(input[key='${i}'])`);const s=e?"addClass":"removeClass";t[s]("disabled");$(`input[key='${i}'][type='text']`).parent()[s]("disabled")}}$(".gui-settings-panel .popup").removeClass("opened")};$(`input[type='checkbox'][key]`).on("change",e=>t($(e.target))).each((e,n)=>t($(n)))}function h(e){if($(".gui-settings").length===0){e.append(`
      \n \n \n \n
      `);$(".gui-settings").on("click",()=>{$(".gui-settings-panel").addClass("opened")})}t.applyStyle("guiSettingsStyle")}function y(){const e=$(".predefined-colors-grid");for(const t of Object.values(n)){$(`
      `).appendTo(e).css("background",t).attr("data-color",t).on("click",e=>{$(`input[key='customStyleColor']`).val($(e.target).attr("data-color")).trigger("input").change();$("div.custom-color-preview").on("click")})}}function f(){if(e.blurSettingsPanel){$(".gui-settings-box").addClass("blur")}else{$(".gui-settings-panel").addClass("animation")}}function k(){if(typeof offlineData!=="undefined"){$("li:has(input[key=useCache])").addClass("disabled");$("input[key=useCache]").prop("disabled",true)}}h($("body"));const C=t.data.guiSettingsDom.text;if(C){$("body").append(C);u();p();k();l();g();y();d();f()}new SpinQuery(()=>$("body"),e=>e.length>0&&!(unsafeWindow.parent.window===unsafeWindow),e=>$(".gui-settings-icon-panel").css("display","none")).start()}})(); offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/dark-styles.min.js"] = (()=>{return(l,e)=>{if(l.useDarkStyle){e.applyStyle("scrollbarStyle");SpinQuery.any(()=>$(".custom-scrollbar"),l=>l.removeClass("custom-scrollbar"));if($("#banner_link").length===0||$("#banner_link").length>0&&l.overrideNavBar&&!l.showBanner){e.applyImportantStyle("darkStyleNavBar")}e.applyStyle("darkStyle");e.applyImportantStyle("darkStyleImportant")}else{$("#bilibili-scrollbar-style,#bilibili-new-style-dark-nav-bar,#bilibili-new-style-dark,#bilibili-new-style-dark-important").remove()}}})(); offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/new-styles.min.js"] = (()=>{return(e,t)=>{if(document.URL===`https://h.bilibili.com/`){return}SpinQuery.any(()=>$(".custom-scrollbar"),e=>e.removeClass("custom-scrollbar"));const l={selectors:["div.nav-con.fl","#link-navbar-vm",".link-navbar",".nav-header-wrapper",".z_top .z_header"],get allSelectors(){return this.selectors.reduce((e,t)=>e+","+t)},get navbar(){let e=null;for(const t of this.selectors){e=e||document.querySelector(t)}return e},supports(e){if(e instanceof Element){const t=parseInt(window.getComputedStyle(e).height);const l=[60,50,0,56];return l.indexOf(t)!==-1}return false}};SpinQuery.any(()=>$(l.allSelectors),()=>{const e=l.navbar;if(l.supports(e)){t.applyStyle("style","bilibili-style-optimization")}else{t.applyStyle("oldStyle","bilibili-style-optimization")}})}})(); @@ -881,8 +885,8 @@ 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 s{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 s=this.greaterThan(e)&&this.lessThan(t);if(e.greaterThan(t)){s=this.greaterThan(e)||this.lessThan(t)}const i=s||this.equals(e);return i}static millisecondsBefore(e){const t=new s;const i=(new Date).getSeconds();const r=1e3*(t.hour*3600+t.minute*60+i);const n=1e3*(e.hour*3600+e.minute*60);let h=n-r;if(t.greaterThan(e)||t.equals(e)&&i!==0){h+=24*3600*1e3}return h}}function i(){if(e.darkSchedule){const r=new s(e.darkScheduleStart);const n=new s(e.darkScheduleEnd);const h=new s;const u=h.isInRange(r,n);if(e.useDarkStyle!==u){e.useDarkStyle=u;saveSettings(e);t.fetchByKey("useDarkStyle")}let o=0;if(u){o=s.millisecondsBefore(n)}else{o=s.millisecondsBefore(r)}if(o!==0){setTimeout(()=>i(),o)}}}i();return{export:s}}})(); offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/force-wide.min.js"] = (()=>{return(e,t)=>{t.applyImportantStyle("forceWideStyle")}})(); offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/clear-cache.min.js"] = (()=>{return(e,t)=>{return{settingsWidget:{category:"其他",content:`
      \n \n 清除缓存\n \n
      `,success:()=>{$("#clear-cache").on("click",()=>{e.cache={};Toast.success("已删除全部缓存.","清除缓存",5e3)});if(typeof offlineData!=="undefined"){$("button#clear-cache").parent().addClass("hidden")}}}}}})(); -offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.js"] = (()=>{return(e,t)=>{const o=t.attributes.videoInfo.export.VideoInfo;const n=t.attributes.videoInfo.export.BangumiInfo;const s={aid:undefined,cid:undefined,isBangumi:false,isMovie:false};class i{constructor(e,t,o){this.quality=e;this.internalName=t;this.displayName=o}async downloadInfo(){const e=new r(this);await e.fetchVideoInfo();return e}static get availableFormats(){return new Promise((e,t)=>{const o=`https://api.bilibili.com/x/player/playurl?avid=${s.aid}&cid=${s.cid}&otype=json`;const n=new XMLHttpRequest;n.addEventListener("load",()=>{const o=JSON.parse(n.responseText);if(o.code!==0){t("获取清晰度信息失败.")}const s=o.data;const a=s.accept_quality;const r=s.accept_format.split(",");const d=s.accept_description;const l=[];while(a.length>0){const e=new i(a.pop(),r.pop(),d.pop());l.push(e)}e(l)});n.addEventListener("error",()=>t(`获取清晰度信息失败.`));n.withCredentials=true;n.open("GET",o);n.send()})}}class a{constructor(e,t,o,n){this.length=e;this.size=t;this.url=o;this.backupUrls=n}}class r{constructor(e,t){this.format=e;this.fragments=t||[];this.progress=null;this.loaded=0;this.totalSize=null;this.workingXhr=null}fetchVideoInfo(){return new Promise((e,t)=>{const o=`https://api.bilibili.com/x/player/playurl?avid=${s.aid}&cid=${s.cid}&qn=${this.format.quality}&otype=json`;const n=new XMLHttpRequest;n.addEventListener("load",()=>{const o=JSON.parse(n.responseText.replace(/http:/g,"https:")).data;if(o.quality!==this.format.quality){t("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const s=o.durl;this.fragments=s.map(e=>new a(e.length,e.size,e.url,e.backup_url));e(this.fragments)});n.withCredentials=true;n.open("GET",o);n.send()})}cancelDownload(){if(this.workingXhr){this.workingXhr.abort()}}downloadUrl(e){return new Promise((t,o)=>{const n=new XMLHttpRequest;n.open("GET",e);n.responseType="arraybuffer";n.withCredentials=false;n.addEventListener("progress",e=>{this.progress&&this.progress((this.loaded+e.loaded)/this.totalSize)});n.addEventListener("load",()=>{if(n.status===200){t(n.response)}else{o(`请求失败.`)}});n.addEventListener("abort",()=>o("下载已取消."));n.addEventListener("error",()=>o(`下载失败.`));n.send();this.workingXhr=n})}copyUrl(){const e=this.fragments.map(e=>e.url).reduce((e,t)=>e+"\r\n"+t);GM_setClipboard(e,"text")}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 o=await this.downloadUrl(t.url);this.loaded+=t.size;e.push(o)}if(e.length<1){throw new Error("下载失败.")}let t=null;let o=null;const n=e=>(e||this.fragments[0]).url.indexOf(".flv")!==-1?".flv":".mp4";if(e.length===1){const[s]=e;t=new Blob([s],{type:n()===".flv"?"video/x-flv":"video/mp4"});o=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","")+n()}else{const s=new JSZip;const i=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","");e.forEach((e,t)=>{s.file(`${i} - ${t+1}${n(this.fragments[t])}`,e)});t=await s.generateAsync({type:"blob"});o=i+".zip"}const s=URL.createObjectURL(t);const i=$("a#video-complete").attr("href");if(i&&$(`.link[href=${i}]`).length===0){URL.revokeObjectURL(i)}this.progress&&this.progress(0);return{url:s,filename:o}}}function d(){(async()=>{let e=(unsafeWindow||window).aid;let t=(unsafeWindow||window).cid;if(e===undefined||t===undefined){const n=document.URL.match(/\/av(\d+)/);const s=document.URL.match(/\/ep(\d+)/);if(n&&n[1]){const s=await new o(n[1]).fetchInfo();e=s.aid;t=s.cid}}return[e,t]})().then(e=>{const[o,n]=e;if(o===undefined||n===undefined){return}s.aid=o;s.cid=n;i.availableFormats.then(e=>{let[o]=e;const n=()=>o.downloadInfo().catch(e=>{$(".download-video-panel").addClass("error");$(".video-error").text(e)});async function s(){if(!o){return}$(".download-video-panel").removeClass("action").addClass("progress");const e=await n();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=>{$(".download-video-panel").addClass("error");$(".video-error").text(e)});if(!t){return}const s=document.getElementById("video-complete");s.setAttribute("href",t.url);s.setAttribute("download",t.filename);s.click();const i=`下载完成. 再次保存`;Toast.success(i,"下载视频");$(".download-video-panel").removeClass("progress").addClass("quality")}async function i(){if(!o){return}const e=await n();e.copyUrl();Toast.success("已复制链接到剪贴板.","复制链接",3e3);$(".download-video-panel").removeClass("action").addClass("quality")}$(".video-action>#video-action-download").on("click",s);$(".video-action>#video-action-copy").on("click",i);e.forEach(e=>{$(`
    • ${e.displayName}
    • `).on("click",()=>{o=e;$(".download-video-panel").removeClass("quality").addClass("action")}).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")})})}return{settingsWidget:{category:"视频与直播",content:t.data.downloadVideoDom.text,success:d}}}})(); -offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/video-info.min.js"] = (()=>{return()=>{class t{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}}class i{constructor(t,i){this.text=t;this.p=i}}class e{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 e=(new DOMParser).parseFromString(t,"application/xml").documentElement;this.xml=e;this.danmakus=[].map.call(e.querySelectorAll("d[p]"),t=>{return new i(t.innerHTML,t.getAttribute("p"))})}}class a{constructor(t){this.ep=t;this.videos=[]}async fetchInfo(){const i=await downloadText(`https://www.bilibili.com/bangumi/play/ep${this.ep}/`);const e=JSON.parse(i.match(/window\.__INITIAL_STATE__=(.*);\(function\(\){/)[1]);this.title=e.mediaInfo.title;this.cover=e.mediaInfo.cover;this.squareCover=e.mediaInfo.square_cover;this.aid=e.epInfo.aid;this.cid=e.epInfo.cid;this.videos=e.epList.map(async i=>{return{title:i.index_title,aid:i.aid,cid:i.cid,info:await new t(i.aid).fetchInfo()}});return this}}return{export:{VideoInfo:t,BangumiInfo:a,Danmaku:i,DanmakuInfo:e}}}})(); +offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.js"] = (()=>{return(e,t)=>{const o=t.attributes.videoInfo.export.VideoInfo;const n=t.attributes.videoInfo.export.BangumiInfo;const s=t.attributes.videoInfo.export.DanmakuInfo;const i={aid:undefined,cid:undefined,isBangumi:false,isMovie:false};class a{constructor(e,t,o){this.quality=e;this.internalName=t;this.displayName=o}async downloadInfo(){const e=new l(this);await e.fetchVideoInfo();return e}static get availableFormats(){return new Promise((e,t)=>{const o=`https://api.bilibili.com/x/player/playurl?avid=${i.aid}&cid=${i.cid}&otype=json`;const n=new XMLHttpRequest;n.addEventListener("load",()=>{const o=JSON.parse(n.responseText);if(o.code!==0){t("获取清晰度信息失败.")}const s=o.data;const i=s.accept_quality;const r=s.accept_format.split(",");const l=s.accept_description;const d=[];while(i.length>0){const e=new a(i.pop(),r.pop(),l.pop());d.push(e)}e(d)});n.addEventListener("error",()=>t(`获取清晰度信息失败.`));n.withCredentials=true;n.open("GET",o);n.send()})}}class r{constructor(e,t,o,n){this.length=e;this.size=t;this.url=o;this.backupUrls=n}}class l{constructor(e,t){this.format=e;this.fragments=t||[];this.progress=null;this.loaded=0;this.totalSize=null;this.workingXhr=null}fetchVideoInfo(){return new Promise((e,t)=>{const o=`https://api.bilibili.com/x/player/playurl?avid=${i.aid}&cid=${i.cid}&qn=${this.format.quality}&otype=json`;const n=new XMLHttpRequest;n.addEventListener("load",()=>{const o=JSON.parse(n.responseText.replace(/http:/g,"https:")).data;if(o.quality!==this.format.quality){t("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const s=o.durl;this.fragments=s.map(e=>new r(e.length,e.size,e.url,e.backup_url));e(this.fragments)});n.withCredentials=true;n.open("GET",o);n.send()})}cancelDownload(){if(this.workingXhr){this.workingXhr.abort()}}downloadUrl(e){return new Promise((t,o)=>{const n=new XMLHttpRequest;n.open("GET",e);n.responseType="arraybuffer";n.withCredentials=false;n.addEventListener("progress",e=>{this.progress&&this.progress((this.loaded+e.loaded)/this.totalSize)});n.addEventListener("load",()=>{if(n.status===200){t(n.response)}else{o(`请求失败.`)}});n.addEventListener("abort",()=>o("下载已取消."));n.addEventListener("error",()=>o(`下载失败.`));n.send();this.workingXhr=n})}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"}cleanUpOldBlobUrl(){const e=$("a#video-complete").attr("href");if(e&&$(`.link[href=${e}]`).length===0){URL.revokeObjectURL(e)}}downloadSingle(e){const[t]=e;const o=new Blob([t],{type:this.extension()===".flv"?"video/x-flv":"video/mp4"});const n=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","")+this.extension();return[o,n]}async downloadMultiple(e){const t=new JSZip;const o=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","");if(e.length>1){e.forEach((e,n)=>{t.file(`${o} - ${n+1}${this.extension(this.fragments[n])}`,e)})}else{t.file(`${o}}${this.extension()}`,data)}if(settings.downloadDanmaku){const e=new s(i.cid);await e.fetchInfo();t.file(`${o}.xml`,e.rawXML)}const n=await t.generateAsync({type:"blob"});const a=o+".zip";return[n,a]}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 o=await this.downloadUrl(t.url);this.loaded+=t.size;e.push(o)}if(e.length<1){throw new Error("下载失败.")}let t=null;let o=null;if(e.length===1&&!settings.downloadDanmaku){[t,o]=this.downloadSingle(e)}else{[t,o]=await this.downloadMultiple(e)}const n=URL.createObjectURL(t);this.cleanUpOldBlobUrl();this.progress&&this.progress(0);return{url:n,filename:o}}}function d(){(async()=>{let e=(unsafeWindow||window).aid;let t=(unsafeWindow||window).cid;if(e===undefined||t===undefined){const n=document.URL.match(/\/av(\d+)/);const s=document.URL.match(/\/ep(\d+)/);if(n&&n[1]){const s=await new o(n[1]).fetchInfo();e=s.aid;t=s.cid}}return[e,t]})().then(e=>{const[o,n]=e;if(o===undefined||n===undefined){return}i.aid=o;i.cid=n;a.availableFormats.then(e=>{let[o]=e;const n=()=>o.downloadInfo().catch(e=>{$(".download-video-panel").addClass("error");$(".video-error").text(e)});async function s(){if(!o){return}$(".download-video-panel").removeClass("action").addClass("progress");const e=await n();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=>{$(".download-video-panel").addClass("error");$(".video-error").text(e)});if(!t){return}const s=document.getElementById("video-complete");s.setAttribute("href",t.url);s.setAttribute("download",t.filename);s.click();const i=`下载完成. 再次保存`;Toast.success(i,"下载视频");$(".download-video-panel").removeClass("progress").addClass("quality")}async function i(){if(!o){return}const e=await n();e.copyUrl();Toast.success("已复制链接到剪贴板.","复制链接",3e3);$(".download-video-panel").removeClass("action").addClass("quality")}$(".video-action>#video-action-download").on("click",s);$(".video-action>#video-action-copy").on("click",i);e.forEach(e=>{$(`
    • ${e.displayName}
    • `).on("click",()=>{o=e;$(".download-video-panel").removeClass("quality").addClass("action")}).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")})})}return{settingsWidget:{category:"视频与直播",content:t.data.downloadVideoDom.text,success:d}}}})(); +offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/video-info.min.js"] = (()=>{return()=>{class t{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 e(this.cid);return this.danmaku.fetchInfo()}}class i{constructor(t,i){this.text=t;this.p=i}}class e{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 e=(new DOMParser).parseFromString(t,"application/xml").documentElement;this.xml=e;this.danmakus=[].map.call(e.querySelectorAll("d[p]"),t=>{return new i(t.innerHTML,t.getAttribute("p"))})}}class a{constructor(t){this.ep=t;this.videos=[]}async fetchInfo(){const i=await downloadText(`https://www.bilibili.com/bangumi/play/ep${this.ep}/`);const e=JSON.parse(i.match(/window\.__INITIAL_STATE__=(.*);\(function\(\){/)[1]);this.title=e.mediaInfo.title;this.cover=e.mediaInfo.cover;this.squareCover=e.mediaInfo.square_cover;this.aid=e.epInfo.aid;this.cid=e.epInfo.cid;this.videos=e.epList.map(async i=>{return{title:i.index_title,aid:i.aid,cid:i.cid,info:await new t(i.aid).fetchInfo()}});return this}}return{export:{VideoInfo:t,BangumiInfo:a,Danmaku:i,DanmakuInfo:e}}}})(); offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/about.min.html"] = `

      Bilibili Evolved

      开源组件

        `; offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/about.min.scss"] = `.about.gui-settings-footer{height:24px;font-size:14px;justify-content:space-between;padding:6px 24px;border-top:1px dashed #8884;}.about.gui-settings-footer>span{opacity:0.2;}.bilibili-evolved-about{display:flex;width:400px;height:70vh;background-color:white;position:fixed;top:15%;left:calc(50% - 200px);z-index:100000;box-shadow:0px 3px 20px 2px #0004;border-top:4px solid $customStyleColor;flex-direction:column;transition:all .2s ease-out;transform-origin:center;transform:scale(0);}.bilibili-evolved-about.opened{transform:scale(1);}.bilibili-evolved-info a{margin:0 4px;}.bilibili-evolved-info>p{margin:8px 0;}.bilibili-evolved-about>div{flex:1 0 0;display:flex;align-items:center;justify-content:space-between;flex-direction:column;padding:8px;}.bilibili-evolved-about>div.about-block{flex:4 0 0;padding:32px;align-items:stretch;}.bilibili-evolved-about h1{font-size:36px;margin-bottom:16px;}.bilibili-evolved-about h2{font-size:18px;margin-bottom:8px;}.open-source-components>li{margin:12px 0;padding:12px 24px;background:rgba(0,0,0,0.2);border-left:4px solid $customStyleColor;cursor:pointer;transition:all .2s ease-out;}.open-source-components>li:hover{opacity:0.8;}.component-name{font-size:18px;font-weight:bold;}.component-info{margin-top:8px;}#about-link{cursor:pointer;transition:all .2s;}.bilibili-evolved-about a{color:$customStyleColor;}#about-link:hover{opacity:1;color:$customStyleColor;}#about-close{background-color:#8884;border-color:transparent;opacity:1;transition:all .2s ease-out;width:80px;height:32px;color:inherit;cursor:pointer;}#about-close:hover{opacity:0.8;}#about-close:active{outline:none;opacity:0.6;}`; offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/about.min.js"] = (()=>{return(e,n)=>{$("body").append(n.data.aboutDom.text);const i=GM_info.script.name.replace("Bilibili Evolved","").replace(/^[\(\) ]+|[\(\) ]+$/g,"")+" · "+e.currentVersion;$(".bilibili-evolved-version").text(i);const o=[{name:"jQuery",homepage:"https://jquery.com/",license:"MIT",version:"3.2.1"},{name:"JSZip",homepage:"https://stuk.github.io/jszip/",license:"MIT",version:"3.1.5"}];o.forEach(e=>{$(".open-source-components").append(`\n
      • \n \n
        ${e.name}
        \n
        ${e.version} · ${e.license}
        \n
        \n
      • \n `)});function t(){n.applyStyle("aboutStyle");$("#about-link,#about-close").on("click",()=>{$(".bilibili-evolved-about").toggleClass("opened")})}return{settingsWidget:{after:()=>$(".gui-settings-content"),content:`\n `,success:t}}}})(); diff --git a/bilibili-evolved.preview.user.js b/bilibili-evolved.preview.user.js index 94d0eff8d..cab2cf818 100644 --- a/bilibili-evolved.preview.user.js +++ b/bilibili-evolved.preview.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name Bilibili Evolved (Preview) -// @version 1.5.37 +// @version 1.5.38 // @description 增强哔哩哔哩Web端体验(预览版分支): 修复界面瑕疵, 删除广告, 使用夜间模式浏览, 下载视频或视频封面, 以及增加对触屏设备的支持等. // @author Grant Howard, Coulomb-G // @copyright 2018, Grant Howrad (https://github.com/the1812) @@ -56,6 +56,7 @@ blurBackgroundOpacity: 0.382, defaultPlayerMode: "常规", autoLightOff: false, + downloadDanmaku: false, useCache: true, cache: {}, }; @@ -394,6 +395,9 @@ "downloadVideoStyle", "videoInfo", ], + displayNames: { + "downloadDanmaku": "下载视频时包含弹幕", + }, }, videoInfo: { path: "min/video-info.min.js", diff --git a/bilibili-evolved.user.js b/bilibili-evolved.user.js index 1e09c4a7b..9cfc837a5 100644 --- a/bilibili-evolved.user.js +++ b/bilibili-evolved.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name Bilibili Evolved -// @version 1.5.37 +// @version 1.5.38 // @description 增强哔哩哔哩Web端体验: 修复界面瑕疵, 删除广告, 使用夜间模式浏览, 下载视频或视频封面, 以及增加对触屏设备的支持等. // @author Grant Howard, Coulomb-G // @copyright 2018, Grant Howrad (https://github.com/the1812) @@ -56,6 +56,7 @@ blurBackgroundOpacity: 0.382, defaultPlayerMode: "常规", autoLightOff: false, + downloadDanmaku: false, useCache: true, cache: {}, }; @@ -394,6 +395,9 @@ "downloadVideoStyle", "videoInfo", ], + displayNames: { + "downloadDanmaku": "下载视频时包含弹幕", + }, }, videoInfo: { path: "min/video-info.min.js", diff --git a/min/download-video.min.js b/min/download-video.min.js index 2c086ff77..70c7ffa8a 100644 --- a/min/download-video.min.js +++ b/min/download-video.min.js @@ -1 +1 @@ -(()=>{return(e,t)=>{const o=t.attributes.videoInfo.export.VideoInfo;const n=t.attributes.videoInfo.export.BangumiInfo;const s={aid:undefined,cid:undefined,isBangumi:false,isMovie:false};class i{constructor(e,t,o){this.quality=e;this.internalName=t;this.displayName=o}async downloadInfo(){const e=new r(this);await e.fetchVideoInfo();return e}static get availableFormats(){return new Promise((e,t)=>{const o=`https://api.bilibili.com/x/player/playurl?avid=${s.aid}&cid=${s.cid}&otype=json`;const n=new XMLHttpRequest;n.addEventListener("load",()=>{const o=JSON.parse(n.responseText);if(o.code!==0){t("获取清晰度信息失败.")}const s=o.data;const a=s.accept_quality;const r=s.accept_format.split(",");const d=s.accept_description;const l=[];while(a.length>0){const e=new i(a.pop(),r.pop(),d.pop());l.push(e)}e(l)});n.addEventListener("error",()=>t(`获取清晰度信息失败.`));n.withCredentials=true;n.open("GET",o);n.send()})}}class a{constructor(e,t,o,n){this.length=e;this.size=t;this.url=o;this.backupUrls=n}}class r{constructor(e,t){this.format=e;this.fragments=t||[];this.progress=null;this.loaded=0;this.totalSize=null;this.workingXhr=null}fetchVideoInfo(){return new Promise((e,t)=>{const o=`https://api.bilibili.com/x/player/playurl?avid=${s.aid}&cid=${s.cid}&qn=${this.format.quality}&otype=json`;const n=new XMLHttpRequest;n.addEventListener("load",()=>{const o=JSON.parse(n.responseText.replace(/http:/g,"https:")).data;if(o.quality!==this.format.quality){t("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const s=o.durl;this.fragments=s.map(e=>new a(e.length,e.size,e.url,e.backup_url));e(this.fragments)});n.withCredentials=true;n.open("GET",o);n.send()})}cancelDownload(){if(this.workingXhr){this.workingXhr.abort()}}downloadUrl(e){return new Promise((t,o)=>{const n=new XMLHttpRequest;n.open("GET",e);n.responseType="arraybuffer";n.withCredentials=false;n.addEventListener("progress",e=>{this.progress&&this.progress((this.loaded+e.loaded)/this.totalSize)});n.addEventListener("load",()=>{if(n.status===200){t(n.response)}else{o(`请求失败.`)}});n.addEventListener("abort",()=>o("下载已取消."));n.addEventListener("error",()=>o(`下载失败.`));n.send();this.workingXhr=n})}copyUrl(){const e=this.fragments.map(e=>e.url).reduce((e,t)=>e+"\r\n"+t);GM_setClipboard(e,"text")}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 o=await this.downloadUrl(t.url);this.loaded+=t.size;e.push(o)}if(e.length<1){throw new Error("下载失败.")}let t=null;let o=null;const n=e=>(e||this.fragments[0]).url.indexOf(".flv")!==-1?".flv":".mp4";if(e.length===1){const[s]=e;t=new Blob([s],{type:n()===".flv"?"video/x-flv":"video/mp4"});o=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","")+n()}else{const s=new JSZip;const i=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","");e.forEach((e,t)=>{s.file(`${i} - ${t+1}${n(this.fragments[t])}`,e)});t=await s.generateAsync({type:"blob"});o=i+".zip"}const s=URL.createObjectURL(t);const i=$("a#video-complete").attr("href");if(i&&$(`.link[href=${i}]`).length===0){URL.revokeObjectURL(i)}this.progress&&this.progress(0);return{url:s,filename:o}}}function d(){(async()=>{let e=(unsafeWindow||window).aid;let t=(unsafeWindow||window).cid;if(e===undefined||t===undefined){const n=document.URL.match(/\/av(\d+)/);const s=document.URL.match(/\/ep(\d+)/);if(n&&n[1]){const s=await new o(n[1]).fetchInfo();e=s.aid;t=s.cid}}return[e,t]})().then(e=>{const[o,n]=e;if(o===undefined||n===undefined){return}s.aid=o;s.cid=n;i.availableFormats.then(e=>{let[o]=e;const n=()=>o.downloadInfo().catch(e=>{$(".download-video-panel").addClass("error");$(".video-error").text(e)});async function s(){if(!o){return}$(".download-video-panel").removeClass("action").addClass("progress");const e=await n();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=>{$(".download-video-panel").addClass("error");$(".video-error").text(e)});if(!t){return}const s=document.getElementById("video-complete");s.setAttribute("href",t.url);s.setAttribute("download",t.filename);s.click();const i=`下载完成. 再次保存`;Toast.success(i,"下载视频");$(".download-video-panel").removeClass("progress").addClass("quality")}async function i(){if(!o){return}const e=await n();e.copyUrl();Toast.success("已复制链接到剪贴板.","复制链接",3e3);$(".download-video-panel").removeClass("action").addClass("quality")}$(".video-action>#video-action-download").on("click",s);$(".video-action>#video-action-copy").on("click",i);e.forEach(e=>{$(`
      • ${e.displayName}
      • `).on("click",()=>{o=e;$(".download-video-panel").removeClass("quality").addClass("action")}).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")})})}return{settingsWidget:{category:"视频与直播",content:t.data.downloadVideoDom.text,success:d}}}})(); \ No newline at end of file +(()=>{return(e,t)=>{const o=t.attributes.videoInfo.export.VideoInfo;const n=t.attributes.videoInfo.export.BangumiInfo;const s=t.attributes.videoInfo.export.DanmakuInfo;const i={aid:undefined,cid:undefined,isBangumi:false,isMovie:false};class a{constructor(e,t,o){this.quality=e;this.internalName=t;this.displayName=o}async downloadInfo(){const e=new l(this);await e.fetchVideoInfo();return e}static get availableFormats(){return new Promise((e,t)=>{const o=`https://api.bilibili.com/x/player/playurl?avid=${i.aid}&cid=${i.cid}&otype=json`;const n=new XMLHttpRequest;n.addEventListener("load",()=>{const o=JSON.parse(n.responseText);if(o.code!==0){t("获取清晰度信息失败.")}const s=o.data;const i=s.accept_quality;const r=s.accept_format.split(",");const l=s.accept_description;const d=[];while(i.length>0){const e=new a(i.pop(),r.pop(),l.pop());d.push(e)}e(d)});n.addEventListener("error",()=>t(`获取清晰度信息失败.`));n.withCredentials=true;n.open("GET",o);n.send()})}}class r{constructor(e,t,o,n){this.length=e;this.size=t;this.url=o;this.backupUrls=n}}class l{constructor(e,t){this.format=e;this.fragments=t||[];this.progress=null;this.loaded=0;this.totalSize=null;this.workingXhr=null}fetchVideoInfo(){return new Promise((e,t)=>{const o=`https://api.bilibili.com/x/player/playurl?avid=${i.aid}&cid=${i.cid}&qn=${this.format.quality}&otype=json`;const n=new XMLHttpRequest;n.addEventListener("load",()=>{const o=JSON.parse(n.responseText.replace(/http:/g,"https:")).data;if(o.quality!==this.format.quality){t("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const s=o.durl;this.fragments=s.map(e=>new r(e.length,e.size,e.url,e.backup_url));e(this.fragments)});n.withCredentials=true;n.open("GET",o);n.send()})}cancelDownload(){if(this.workingXhr){this.workingXhr.abort()}}downloadUrl(e){return new Promise((t,o)=>{const n=new XMLHttpRequest;n.open("GET",e);n.responseType="arraybuffer";n.withCredentials=false;n.addEventListener("progress",e=>{this.progress&&this.progress((this.loaded+e.loaded)/this.totalSize)});n.addEventListener("load",()=>{if(n.status===200){t(n.response)}else{o(`请求失败.`)}});n.addEventListener("abort",()=>o("下载已取消."));n.addEventListener("error",()=>o(`下载失败.`));n.send();this.workingXhr=n})}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"}cleanUpOldBlobUrl(){const e=$("a#video-complete").attr("href");if(e&&$(`.link[href=${e}]`).length===0){URL.revokeObjectURL(e)}}downloadSingle(e){const[t]=e;const o=new Blob([t],{type:this.extension()===".flv"?"video/x-flv":"video/mp4"});const n=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","")+this.extension();return[o,n]}async downloadMultiple(e){const t=new JSZip;const o=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","");if(e.length>1){e.forEach((e,n)=>{t.file(`${o} - ${n+1}${this.extension(this.fragments[n])}`,e)})}else{t.file(`${o}}${this.extension()}`,data)}if(settings.downloadDanmaku){const e=new s(i.cid);await e.fetchInfo();t.file(`${o}.xml`,e.rawXML)}const n=await t.generateAsync({type:"blob"});const a=o+".zip";return[n,a]}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 o=await this.downloadUrl(t.url);this.loaded+=t.size;e.push(o)}if(e.length<1){throw new Error("下载失败.")}let t=null;let o=null;if(e.length===1&&!settings.downloadDanmaku){[t,o]=this.downloadSingle(e)}else{[t,o]=await this.downloadMultiple(e)}const n=URL.createObjectURL(t);this.cleanUpOldBlobUrl();this.progress&&this.progress(0);return{url:n,filename:o}}}function d(){(async()=>{let e=(unsafeWindow||window).aid;let t=(unsafeWindow||window).cid;if(e===undefined||t===undefined){const n=document.URL.match(/\/av(\d+)/);const s=document.URL.match(/\/ep(\d+)/);if(n&&n[1]){const s=await new o(n[1]).fetchInfo();e=s.aid;t=s.cid}}return[e,t]})().then(e=>{const[o,n]=e;if(o===undefined||n===undefined){return}i.aid=o;i.cid=n;a.availableFormats.then(e=>{let[o]=e;const n=()=>o.downloadInfo().catch(e=>{$(".download-video-panel").addClass("error");$(".video-error").text(e)});async function s(){if(!o){return}$(".download-video-panel").removeClass("action").addClass("progress");const e=await n();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=>{$(".download-video-panel").addClass("error");$(".video-error").text(e)});if(!t){return}const s=document.getElementById("video-complete");s.setAttribute("href",t.url);s.setAttribute("download",t.filename);s.click();const i=`下载完成. 再次保存`;Toast.success(i,"下载视频");$(".download-video-panel").removeClass("progress").addClass("quality")}async function i(){if(!o){return}const e=await n();e.copyUrl();Toast.success("已复制链接到剪贴板.","复制链接",3e3);$(".download-video-panel").removeClass("action").addClass("quality")}$(".video-action>#video-action-download").on("click",s);$(".video-action>#video-action-copy").on("click",i);e.forEach(e=>{$(`
      • ${e.displayName}
      • `).on("click",()=>{o=e;$(".download-video-panel").removeClass("quality").addClass("action")}).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")})})}return{settingsWidget:{category:"视频与直播",content:t.data.downloadVideoDom.text,success:d}}}})(); \ No newline at end of file diff --git a/min/video-info.min.js b/min/video-info.min.js index bb328e546..51e6be3e4 100644 --- a/min/video-info.min.js +++ b/min/video-info.min.js @@ -1 +1 @@ -(()=>{return()=>{class t{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}}class i{constructor(t,i){this.text=t;this.p=i}}class e{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 e=(new DOMParser).parseFromString(t,"application/xml").documentElement;this.xml=e;this.danmakus=[].map.call(e.querySelectorAll("d[p]"),t=>{return new i(t.innerHTML,t.getAttribute("p"))})}}class a{constructor(t){this.ep=t;this.videos=[]}async fetchInfo(){const i=await downloadText(`https://www.bilibili.com/bangumi/play/ep${this.ep}/`);const e=JSON.parse(i.match(/window\.__INITIAL_STATE__=(.*);\(function\(\){/)[1]);this.title=e.mediaInfo.title;this.cover=e.mediaInfo.cover;this.squareCover=e.mediaInfo.square_cover;this.aid=e.epInfo.aid;this.cid=e.epInfo.cid;this.videos=e.epList.map(async i=>{return{title:i.index_title,aid:i.aid,cid:i.cid,info:await new t(i.aid).fetchInfo()}});return this}}return{export:{VideoInfo:t,BangumiInfo:a,Danmaku:i,DanmakuInfo:e}}}})(); \ No newline at end of file +(()=>{return()=>{class t{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 e(this.cid);return this.danmaku.fetchInfo()}}class i{constructor(t,i){this.text=t;this.p=i}}class e{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 e=(new DOMParser).parseFromString(t,"application/xml").documentElement;this.xml=e;this.danmakus=[].map.call(e.querySelectorAll("d[p]"),t=>{return new i(t.innerHTML,t.getAttribute("p"))})}}class a{constructor(t){this.ep=t;this.videos=[]}async fetchInfo(){const i=await downloadText(`https://www.bilibili.com/bangumi/play/ep${this.ep}/`);const e=JSON.parse(i.match(/window\.__INITIAL_STATE__=(.*);\(function\(\){/)[1]);this.title=e.mediaInfo.title;this.cover=e.mediaInfo.cover;this.squareCover=e.mediaInfo.square_cover;this.aid=e.epInfo.aid;this.cid=e.epInfo.cid;this.videos=e.epList.map(async i=>{return{title:i.index_title,aid:i.aid,cid:i.cid,info:await new t(i.aid).fetchInfo()}});return this}}return{export:{VideoInfo:t,BangumiInfo:a,Danmaku:i,DanmakuInfo:e}}}})(); \ No newline at end of file diff --git a/version.txt b/version.txt index e8693f0fc..ab7b65c00 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.5.37 \ No newline at end of file +1.5.38 \ No newline at end of file diff --git a/video/download-video/download-video.js b/video/download-video/download-video.js index a5338d69c..e99b7226a 100644 --- a/video/download-video/download-video.js +++ b/video/download-video/download-video.js @@ -4,6 +4,7 @@ { const VideoInfo = resources.attributes.videoInfo.export.VideoInfo; const BangumiInfo = resources.attributes.videoInfo.export.BangumiInfo; + const DanmakuInfo = resources.attributes.videoInfo.export.DanmakuInfo; const pageData = { aid: undefined, cid: undefined, @@ -152,6 +153,56 @@ const urls = this.fragments.map(it => it.url).reduce((acc, it) => acc + "\r\n" + it); GM_setClipboard(urls, "text"); } + extension(fragment) + { + return (fragment || this.fragments[0]).url + .indexOf(".flv") !== -1 + ? ".flv" + : ".mp4"; + } + cleanUpOldBlobUrl() + { + const oldBlobUrl = $("a#video-complete").attr("href"); + if (oldBlobUrl && $(`.link[href=${oldBlobUrl}]`).length === 0) + { + URL.revokeObjectURL(oldBlobUrl); + } + } + downloadSingle(downloadedData) + { + const [data] = downloadedData; + const blob = new Blob([data], { + type: this.extension() === ".flv" ? "video/x-flv" : "video/mp4" + }); + const filename = document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili", "") + this.extension(); + return [blob, filename]; + } + async downloadMultiple(downloadedData) + { + const zip = new JSZip(); + const title = document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili", ""); + if (downloadedData.length > 1) + { + downloadedData.forEach((data, index) => + { + zip.file(`${title} - ${index + 1}${this.extension(this.fragments[index])}`, data); + }); + } + else + { + zip.file(`${title}}${this.extension()}`, data); + } + + if (settings.downloadDanmaku) + { + const danmaku = new DanmakuInfo(pageData.cid); + await danmaku.fetchInfo(); + zip.file(`${title}.xml`, danmaku.rawXML); + } + const blob = await zip.generateAsync({ type: "blob" }); + const filename = title + ".zip"; + return [blob, filename]; + } async download() { const downloadedData = []; @@ -170,33 +221,17 @@ let blob = null; let filename = null; - const extension = fragment => (fragment || this.fragments[0]).url.indexOf(".flv") !== -1 ? ".flv" : ".mp4"; - if (downloadedData.length === 1) + if (downloadedData.length === 1 && !settings.downloadDanmaku) { - const [data] = downloadedData; - blob = new Blob([data], { - type: extension() === ".flv" ? "video/x-flv" : "video/mp4" - }); - filename = document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili", "") + extension(); + [blob, filename] = this.downloadSingle(downloadedData); } else { - const zip = new JSZip(); - const title = document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili", ""); - downloadedData.forEach((data, index) => - { - zip.file(`${title} - ${index + 1}${extension(this.fragments[index])}`, data); - }); - blob = await zip.generateAsync({ type: "blob" }); - filename = title + ".zip"; + [blob, filename] = await this.downloadMultiple(downloadedData); } const blobUrl = URL.createObjectURL(blob); - const oldBlobUrl = $("a#video-complete").attr("href"); - if (oldBlobUrl && $(`.link[href=${oldBlobUrl}]`).length === 0) - { - URL.revokeObjectURL(oldBlobUrl); - } + this.cleanUpOldBlobUrl(); this.progress && this.progress(0); return { url: blobUrl,