批量将B站学习视频以MP4格式下载到本地
一、背景描述
有些爱学习的小伙伴可能在外出或者回老家过节前会有提前将学习视频缓存的习惯,但是缓存的视频只能用Bilibili
App来看,屏幕属实有一点点小,因此更想将其下载到电脑上,然后用自己喜欢的播放器去观看(如potPlayer
)。
本篇博客将分享个JS脚本,利用免费解析网站,来实现批量的视频下载。
后续如果有bug将会在gitee上进行更新: https://gitee.com/he_fu_ren/bilibili-video-download
注:本脚本仅供学习使用,切勿用于商业用途
二、效果图
以下面的这个集数较少的视频为例,可以看到此教程有13个Part
脚本运行截图
下载文件截图
三、代码
本脚本使用的编程语言为为JavaScript,可以直接在浏览器中运行
let inputElement = document.getElementsByTagName('input')[0];
let resolveBtn = document.getElementsByClassName('btn')[0];
let beginTime = 0;
let downloadCount = 0;
let resolveCount = 0;
// 视频的前缀,只需要修改 .../video/av?p= 中的 av 号即可
let prefix = "https://www.bilibili.com/video/BV1q4411y7Zh/?p=";
// 从点击完解析按钮到解析完成的时间间隔,默认2s
let interval = 2000;
// 从第几集开始下载,默认是从第一集开始
let beginPart = 1;
// 要下载的视频的集数
let num = 13;
let retryCandidate = new Array(13);
retryCandidate.fill(1);
let retryTime = (interval + 1000) * num;
function downloadVideo(url,name) {
//创建XMLHttpRequest对象
let httpRequest = new XMLHttpRequest();
//打开连接,将请求参数拼在url后面
httpRequest.open('GET', url, true);
//设置期望的返回值类型
httpRequest.responseType = "blob";
//请求成功回调函数
httpRequest.onload = function (oEvent) {
if (httpRequest.status === 200) {
let fileName = decodeURI(name+'.mp4');
let response = httpRequest.response;
//数据转换为文件下载
let elink = document.createElement('a');
elink.download = fileName;
elink.style.display = 'none';
let blob = new Blob([response]);
elink.href = URL.createObjectURL(blob);
document.body.appendChild(elink);
elink.click();
document.body.removeChild(elink);
console.log('视频' + fileName + '下载完成');
downloadCount = downloadCount + 1;
console.log('下载进度' + downloadCount + '/' + num);
}else {
console.log('请求失败,视频url ' + url);
}
}
httpRequest.send();
};
function resolve(i) {
if (document.getElementsByClassName('caption').length > 0) {
// 获取解析后的url
let url = document.getElementsByClassName('caption')[0].getElementsByTagName('p')[1].getElementsByTagName('a')[0].getAttribute('href');
// 获取文件名
let name= document.getElementsByClassName('caption')[0].getElementsByTagName('p')[0].innerText;
resolveCount = resolveCount + 1;
retryCandidate[i] = 0;
downloadVideo(url, name);
} else {
console.log('第' + i + '集视频解析失败,稍后将会重试');
}
console.log('解析进度:' + resolveCount + '/' + num);
};
function sendResolvRequest(i) {
console.log('当前正在解析第' + i + '集视频');
// url
let bilibiliUrl = prefix + i;
inputElement.value = bilibiliUrl;
let evt = document.createEvent('HTMLEvents');
evt.initEvent('input',true,true);
inputElement.dispatchEvent(evt);
// 触发按钮点击事件
resolveBtn.click();
// 解析结果
setTimeout(resolve(i),interval);
};
function doRetry() {
console.log('开始重试');
let len = retryCandidate.length;
beginTime = 0;
console.log('剩余解析失败的视频数量:',len);
for(let i = 0; i < len; i++) {
if (retryCandidate[i] == 1) {
setTimeout(function(){
sendResolvRequest(i);
},beginTime);
beginTime = beginTime + interval + 1000;
}
}
let retryTime = (interval + 1000) * len ;
setTimeout(function() {
retry();
},retryTime);
}
function retry() {
if (resolveCount < num) {
doRetry()
}
}
for(let i = beginPart; i <= num; i++) {
setTimeout(function(){
sendResolvRequest(i);
},beginTime);
beginTime = beginTime + interval + 1000;
}
setTimeout(function() {
retry();
},retryTime);
四、使用教程
第一步
打开视频解析网址:https://bilibili.iiilab.com/
第二步
按F12
打开控制台 或者 右键
网页然后再点检查
,打开控制台后点击`Consoles,切换到控制台界面
第三步
将上述代码全部复制到文本编辑器中,根据自身情况去做修改
可修改部分在代码最上面:
// 视频的前缀,只需要修改 .../video/【av】?p= 中括号内的部分即可,av号在对应B站视频的url中可以看到
let prefix = "https://www.bilibili.com/video/BV1q4411y7Zh/?p=";
// 从点击完解析按钮到解析完成的时间间隔,默认2s(2000ms),网速如果比较慢就改大一些
let interval = 2000;
// 从第几集开始下载,默认是从第一集开始
let beginPart = 1;
// 要下载的视频的集数,配合上面的参数,就是下载1-13集视频
let num = 13;
修改完之后就可以将修改后的代码粘贴到第一步打开的网页中去了。
说明
本脚本仅供学习使用,目前是初代版本,可能会有一些小bug,比如可能漏下载个别视频等,之后有时间会进行修复,并提交到git上