127 lines
4.2 KiB
JavaScript
127 lines
4.2 KiB
JavaScript
// ==UserScript==
|
|
// @name Universal encrypted video downloader
|
|
// @namespace http://tampermonkey.net/
|
|
// @version 1.1
|
|
// @description Bypass the encrypted video download protection via js hook
|
|
// @author Evan
|
|
// @match https://www.bilibili.com/video/*
|
|
// @match https://www.bilibili.com/bangumi/play/*
|
|
// @match https://www.youtube.com/watch*
|
|
// @match https://www.huya.com/*
|
|
// @match https://live.bilibili.com/*
|
|
// @grant none
|
|
// ==/UserScript==
|
|
|
|
jsMedia = new Object();
|
|
jsMedia.mediaSources = [];
|
|
jsMedia.enableAutoDownload = true;
|
|
//1G
|
|
jsMedia.fragmentSize = 1024*1024*1024;
|
|
|
|
(function () {
|
|
let mediaSourceSeq = 0;
|
|
jsMedia.videos = document.getElementsByTagName('video');
|
|
jsMedia.addZero = function(num){
|
|
return ('00' + num).slice(-3);
|
|
};
|
|
jsMedia.downloadBlob = function (buff, fileName) {
|
|
let url = window.URL.createObjectURL(new Blob(buff, { type: "arraybuffer" }))
|
|
const link = document.createElement('a');
|
|
link.style.display = 'none';
|
|
link.href = url;
|
|
link.setAttribute('download', fileName);
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
};
|
|
jsMedia.calcBlobLength = function (buffList) {
|
|
let totalLength = 0;
|
|
for (let i = 0; i < buffList.length; i++) {
|
|
totalLength = totalLength + buffList[i].byteLength;
|
|
}
|
|
return totalLength;
|
|
};
|
|
jsMedia.MyMediaSourceBuffer = function () {
|
|
this.id = 0;
|
|
this.rawData1 = [];
|
|
this.rawData2 = [];
|
|
let currentSlot = 0;
|
|
let downloadedIndex = 0;
|
|
this.download = function () {
|
|
let lastSlot = currentSlot;
|
|
if (currentSlot === 0) {
|
|
currentSlot = 1;
|
|
} else {
|
|
currentSlot = 0;
|
|
}
|
|
|
|
if (lastSlot == 0) {
|
|
jsMedia.downloadBlob(this.rawData1, 'media_' + this.id + '_' + jsMedia.addZero(downloadedIndex) + '.mp4');
|
|
this.rawData1 = [];
|
|
} else {
|
|
jsMedia.downloadBlob(this.rawData2, 'media_' + this.id + '_' + jsMedia.addZero(downloadedIndex) + '.mp4');
|
|
this.rawData2 = [];
|
|
}
|
|
downloadedIndex++;
|
|
};
|
|
this.appendBuffer = function (buf) {
|
|
let totalLength = 0;
|
|
if (currentSlot === 0) {
|
|
this.rawData1.push(buf);
|
|
totalLength = jsMedia.calcBlobLength(this.rawData1);
|
|
} else {
|
|
this.rawData2.push(buf);
|
|
totalLength = jsMedia.calcBlobLength(this.rawData2);
|
|
}
|
|
if (totalLength >= jsMedia.fragmentSize) {
|
|
this.download();
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
jsMedia.download = function(){
|
|
for (let i = 0, length = jsMedia.mediaSources.length; i < length; i++) {
|
|
jsMedia.mediaSources[i].download();
|
|
}
|
|
};
|
|
|
|
jsMedia.setSpeed = function (speed) {
|
|
for (let i = 0, length = jsMedia.videos.length; i < length; i++) {
|
|
jsMedia.videos[i].playbackRate = speed;
|
|
}
|
|
};
|
|
|
|
var proxy_addSourceBuffer = MediaSource.prototype.addSourceBuffer;
|
|
MediaSource.prototype.addSourceBuffer = function (mimeType) {
|
|
var mediaSourceThis = this;
|
|
|
|
var retSourceBuffer = proxy_addSourceBuffer.apply(this, [].slice.call(arguments));
|
|
if (this.rawSources == undefined) {
|
|
this.rawSources = [];
|
|
}
|
|
|
|
retSourceBuffer.mySourceBuffer = new jsMedia.MyMediaSourceBuffer();
|
|
retSourceBuffer.mySourceBuffer.id = mediaSourceSeq;
|
|
jsMedia.mediaSources.push(retSourceBuffer.mySourceBuffer);
|
|
|
|
|
|
if (jsMedia.enableAutoDownload) {
|
|
this.onsourceended = function () {
|
|
jsMedia.download();
|
|
};
|
|
this.onsourceclose = function () {
|
|
jsMedia.download();
|
|
};
|
|
}
|
|
|
|
mediaSourceSeq++;
|
|
return retSourceBuffer;
|
|
};
|
|
var proxy_appendBuffer = SourceBuffer.prototype.appendBuffer;
|
|
SourceBuffer.prototype.appendBuffer = function (buf) {
|
|
this.mySourceBuffer.appendBuffer(buf);
|
|
return proxy_appendBuffer.apply(this, [].slice.call(arguments));
|
|
};
|
|
})(); |