Compare commits
5 Commits
c5e84f805a
...
master
Author | SHA1 | Date | |
---|---|---|---|
49dae65bca | |||
8472b29247 | |||
881037a195 | |||
5b204904a7 | |||
401a6c2286 |
18
README.md
18
README.md
@ -21,20 +21,24 @@
|
|||||||
|
|
||||||
## 参数
|
## 参数
|
||||||
```javascript
|
```javascript
|
||||||
//自动快进
|
//快进抓取
|
||||||
evanEnv.enableAutoForward = true
|
jsMedia.setSpeed(10);
|
||||||
//完成后自动下载
|
//完成后自动下载
|
||||||
evanEnv.enableAutoDownload = true
|
jsMedia.enableAutoDownload = true;
|
||||||
|
//手工触发下载
|
||||||
|
jsMedia.download();
|
||||||
```
|
```
|
||||||
|
|
||||||
## FFmpeg合并示例
|
## FFmpeg合并示例
|
||||||
```shell
|
```shell
|
||||||
ffmpeg -i mediasource_0_0.mp4 -i mediasource_0_1.mp4 -c copy -bsf:a aac_adtstoasc out.mp4
|
ffmpeg -i audio.mp4 -acodec copy audio.aac
|
||||||
|
ffmpeg -i audio.aac -i video.mp4 -c copy -bsf:a aac_adtstoasc out.mp4
|
||||||
```
|
```
|
||||||
|
|
||||||
## 常见问题
|
## 大文件分段需要先文件合并
|
||||||
- 合并后声音播放不正常:由于部分网站使用了HE-AAC v2(AAC+SBR+PS)作为音频编码,大部分播放器还不支持此音频流格式,故声音不正常,使用Windows自带的视频播放器播放正常
|
```
|
||||||
|
copy /b media_0_*.mp4 out.mp4
|
||||||
|
```
|
||||||
|
|
||||||
## 特别说明
|
## 特别说明
|
||||||
- 仅限内部交流使用,请勿用于非法用途
|
- 仅限内部交流使用,请勿用于非法用途
|
139
downloadMedia.js
139
downloadMedia.js
@ -1,7 +1,7 @@
|
|||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name Universal encrypted video downloader
|
// @name Universal encrypted video downloader
|
||||||
// @namespace http://tampermonkey.net/
|
// @namespace http://tampermonkey.net/
|
||||||
// @version 0.1
|
// @version 1.1
|
||||||
// @description Bypass the encrypted video download protection via js hook
|
// @description Bypass the encrypted video download protection via js hook
|
||||||
// @author Evan
|
// @author Evan
|
||||||
// @match https://www.bilibili.com/video/*
|
// @match https://www.bilibili.com/video/*
|
||||||
@ -12,29 +12,20 @@
|
|||||||
// @grant none
|
// @grant none
|
||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
|
|
||||||
evanEnv = new Object();
|
jsMedia = new Object();
|
||||||
evanEnv.mediaSources = [];
|
jsMedia.mediaSources = [];
|
||||||
evanEnv.enableAutoForward = true;
|
jsMedia.enableAutoDownload = true;
|
||||||
evanEnv.enableAutoDownload = true;
|
//1G
|
||||||
|
jsMedia.fragmentSize = 1024*1024*1024;
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
evanEnv.videos = document.getElementsByTagName('video');
|
let mediaSourceSeq = 0;
|
||||||
evanEnv.buildArrayBuffer = function (bufferList) {
|
jsMedia.videos = document.getElementsByTagName('video');
|
||||||
var totalLength = 0;
|
jsMedia.addZero = function(num){
|
||||||
for (var i = 0; i < bufferList.length; i++) {
|
return ('00' + num).slice(-3);
|
||||||
totalLength += bufferList[i].byteLength;
|
|
||||||
}
|
|
||||||
var tmp = new Uint8Array(totalLength);
|
|
||||||
var lastLength = 0;
|
|
||||||
for (var ix = 0; ix < bufferList.length; ix++) {
|
|
||||||
tmp.set(new Uint8Array(bufferList[ix]), lastLength);
|
|
||||||
lastLength += bufferList[ix].byteLength;
|
|
||||||
}
|
|
||||||
return tmp.buffer;
|
|
||||||
};
|
};
|
||||||
evanEnv.downloadRawData = function (bufferList, fileName = 'out.mp4') {
|
jsMedia.downloadBlob = function (buff, fileName) {
|
||||||
var buff = evanEnv.buildArrayBuffer(bufferList);
|
let url = window.URL.createObjectURL(new Blob(buff, { type: "arraybuffer" }))
|
||||||
let url = window.URL.createObjectURL(new Blob([buff], {type: "arraybuffer"}))
|
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
link.style.display = 'none';
|
link.style.display = 'none';
|
||||||
link.href = url;
|
link.href = url;
|
||||||
@ -43,22 +34,62 @@ evanEnv.enableAutoDownload = true;
|
|||||||
link.click();
|
link.click();
|
||||||
document.body.removeChild(link);
|
document.body.removeChild(link);
|
||||||
};
|
};
|
||||||
|
jsMedia.calcBlobLength = function (buffList) {
|
||||||
evanEnv.download = function () {
|
let totalLength = 0;
|
||||||
for (var i = 0; i < evanEnv.mediaSources.length; i++) {
|
for (let i = 0; i < buffList.length; i++) {
|
||||||
var currentItem = evanEnv.mediaSources[i];
|
totalLength = totalLength + buffList[i].byteLength;
|
||||||
if (currentItem.downloaded == undefined || currentItem.downloaded == false) {
|
}
|
||||||
for (var x = 0; x < currentItem.rawSources.length; x++) {
|
return totalLength;
|
||||||
evanEnv.downloadRawData(currentItem.rawSources[x], 'mediasource_' + i + '_' + x + '.mp4');
|
};
|
||||||
}
|
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;
|
||||||
}
|
}
|
||||||
currentItem.downloaded = true;
|
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
evanEnv.downloadMediaSource = function (mediaSource) {
|
|
||||||
for (var x = 0; x < mediaSource.rawSources.length; x++) {
|
jsMedia.setSpeed = function (speed) {
|
||||||
evanEnv.downloadRawData(mediaSource.rawSources[x], 'mediasource_' + x + '.mp4');
|
for (let i = 0, length = jsMedia.videos.length; i < length; i++) {
|
||||||
mediaSource.downloaded = true;
|
jsMedia.videos[i].playbackRate = speed;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -66,41 +97,31 @@ evanEnv.enableAutoDownload = true;
|
|||||||
MediaSource.prototype.addSourceBuffer = function (mimeType) {
|
MediaSource.prototype.addSourceBuffer = function (mimeType) {
|
||||||
var mediaSourceThis = this;
|
var mediaSourceThis = this;
|
||||||
|
|
||||||
evanEnv.mediaSources.push(this);
|
|
||||||
this.lastPos = 0;
|
|
||||||
if (evanEnv.enableAutoDownload) {
|
|
||||||
this.onsourceended = function () {
|
|
||||||
evanEnv.download();
|
|
||||||
};
|
|
||||||
this.onsourceclose = function () {
|
|
||||||
evanEnv.downloadMediaSource(this);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var retSourceBuffer = proxy_addSourceBuffer.apply(this, [].slice.call(arguments));
|
var retSourceBuffer = proxy_addSourceBuffer.apply(this, [].slice.call(arguments));
|
||||||
if (this.rawSources == undefined) {
|
if (this.rawSources == undefined) {
|
||||||
this.rawSources = [];
|
this.rawSources = [];
|
||||||
}
|
}
|
||||||
var buffList = [];
|
|
||||||
this.rawSources.push(buffList);
|
retSourceBuffer.mySourceBuffer = new jsMedia.MyMediaSourceBuffer();
|
||||||
retSourceBuffer.rawData = buffList;
|
retSourceBuffer.mySourceBuffer.id = mediaSourceSeq;
|
||||||
if (evanEnv.enableAutoForward) {
|
jsMedia.mediaSources.push(retSourceBuffer.mySourceBuffer);
|
||||||
retSourceBuffer.onupdate = function () {
|
|
||||||
if (this.buffered != this.buffered.length > 0) {
|
|
||||||
var endPos = this.buffered.end(0);
|
if (jsMedia.enableAutoDownload) {
|
||||||
if (endPos > 5 && endPos - mediaSourceThis.lastPos > 25) {
|
this.onsourceended = function () {
|
||||||
evanEnv.videos[0].currentTime = endPos - 3;
|
jsMedia.download();
|
||||||
mediaSourceThis.lastPos = evanEnv.videos[0].currentTime;
|
};
|
||||||
}
|
this.onsourceclose = function () {
|
||||||
}
|
jsMedia.download();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mediaSourceSeq++;
|
||||||
return retSourceBuffer;
|
return retSourceBuffer;
|
||||||
};
|
};
|
||||||
var proxy_appendBuffer = SourceBuffer.prototype.appendBuffer;
|
var proxy_appendBuffer = SourceBuffer.prototype.appendBuffer;
|
||||||
SourceBuffer.prototype.appendBuffer = function (buf) {
|
SourceBuffer.prototype.appendBuffer = function (buf) {
|
||||||
this.rawData.push(buf);
|
this.mySourceBuffer.appendBuffer(buf);
|
||||||
return proxy_appendBuffer.apply(this, [].slice.call(arguments));
|
return proxy_appendBuffer.apply(this, [].slice.call(arguments));
|
||||||
};
|
};
|
||||||
})();
|
})();
|
Reference in New Issue
Block a user