Add download xml danmaku option

This commit is contained in:
the1812 2018-11-19 19:47:34 +08:00
parent 5b2ca0c8ab
commit 2e44766c01
8 changed files with 84 additions and 33 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
// ==UserScript== // ==UserScript==
// @name Bilibili Evolved (Preview) // @name Bilibili Evolved (Preview)
// @version 1.5.37 // @version 1.5.38
// @description 增强哔哩哔哩Web端体验(预览版分支): 修复界面瑕疵, 删除广告, 使用夜间模式浏览, 下载视频或视频封面, 以及增加对触屏设备的支持等. // @description 增强哔哩哔哩Web端体验(预览版分支): 修复界面瑕疵, 删除广告, 使用夜间模式浏览, 下载视频或视频封面, 以及增加对触屏设备的支持等.
// @author Grant Howard, Coulomb-G // @author Grant Howard, Coulomb-G
// @copyright 2018, Grant Howrad (https://github.com/the1812) // @copyright 2018, Grant Howrad (https://github.com/the1812)
@ -56,6 +56,7 @@
blurBackgroundOpacity: 0.382, blurBackgroundOpacity: 0.382,
defaultPlayerMode: "常规", defaultPlayerMode: "常规",
autoLightOff: false, autoLightOff: false,
downloadDanmaku: false,
useCache: true, useCache: true,
cache: {}, cache: {},
}; };
@ -394,6 +395,9 @@
"downloadVideoStyle", "downloadVideoStyle",
"videoInfo", "videoInfo",
], ],
displayNames: {
"downloadDanmaku": "下载视频时包含弹幕",
},
}, },
videoInfo: { videoInfo: {
path: "min/video-info.min.js", path: "min/video-info.min.js",

View File

@ -1,6 +1,6 @@
// ==UserScript== // ==UserScript==
// @name Bilibili Evolved // @name Bilibili Evolved
// @version 1.5.37 // @version 1.5.38
// @description 增强哔哩哔哩Web端体验: 修复界面瑕疵, 删除广告, 使用夜间模式浏览, 下载视频或视频封面, 以及增加对触屏设备的支持等. // @description 增强哔哩哔哩Web端体验: 修复界面瑕疵, 删除广告, 使用夜间模式浏览, 下载视频或视频封面, 以及增加对触屏设备的支持等.
// @author Grant Howard, Coulomb-G // @author Grant Howard, Coulomb-G
// @copyright 2018, Grant Howrad (https://github.com/the1812) // @copyright 2018, Grant Howrad (https://github.com/the1812)
@ -56,6 +56,7 @@
blurBackgroundOpacity: 0.382, blurBackgroundOpacity: 0.382,
defaultPlayerMode: "常规", defaultPlayerMode: "常规",
autoLightOff: false, autoLightOff: false,
downloadDanmaku: false,
useCache: true, useCache: true,
cache: {}, cache: {},
}; };
@ -394,6 +395,9 @@
"downloadVideoStyle", "downloadVideoStyle",
"videoInfo", "videoInfo",
], ],
displayNames: {
"downloadDanmaku": "下载视频时包含弹幕",
},
}, },
videoInfo: { videoInfo: {
path: "min/video-info.min.js", path: "min/video-info.min.js",

File diff suppressed because one or more lines are too long

View File

@ -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}}}})(); (()=>{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}}}})();

View File

@ -1 +1 @@
1.5.37 1.5.38

View File

@ -4,6 +4,7 @@
{ {
const VideoInfo = resources.attributes.videoInfo.export.VideoInfo; const VideoInfo = resources.attributes.videoInfo.export.VideoInfo;
const BangumiInfo = resources.attributes.videoInfo.export.BangumiInfo; const BangumiInfo = resources.attributes.videoInfo.export.BangumiInfo;
const DanmakuInfo = resources.attributes.videoInfo.export.DanmakuInfo;
const pageData = { const pageData = {
aid: undefined, aid: undefined,
cid: undefined, cid: undefined,
@ -152,6 +153,56 @@
const urls = this.fragments.map(it => it.url).reduce((acc, it) => acc + "\r\n" + it); const urls = this.fragments.map(it => it.url).reduce((acc, it) => acc + "\r\n" + it);
GM_setClipboard(urls, "text"); 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() async download()
{ {
const downloadedData = []; const downloadedData = [];
@ -170,33 +221,17 @@
let blob = null; let blob = null;
let filename = null; let filename = null;
const extension = fragment => (fragment || this.fragments[0]).url.indexOf(".flv") !== -1 ? ".flv" : ".mp4"; if (downloadedData.length === 1 && !settings.downloadDanmaku)
if (downloadedData.length === 1)
{ {
const [data] = downloadedData; [blob, filename] = this.downloadSingle(downloadedData);
blob = new Blob([data], {
type: extension() === ".flv" ? "video/x-flv" : "video/mp4"
});
filename = document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili", "") + extension();
} }
else else
{ {
const zip = new JSZip(); [blob, filename] = await this.downloadMultiple(downloadedData);
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";
} }
const blobUrl = URL.createObjectURL(blob); const blobUrl = URL.createObjectURL(blob);
const oldBlobUrl = $("a#video-complete").attr("href"); this.cleanUpOldBlobUrl();
if (oldBlobUrl && $(`.link[href=${oldBlobUrl}]`).length === 0)
{
URL.revokeObjectURL(oldBlobUrl);
}
this.progress && this.progress(0); this.progress && this.progress(0);
return { return {
url: blobUrl, url: blobUrl,