最近買了體驗課,但是快到期了還沒看完。于是準(zhǔn)備下載下來。
工具:
global speed(加速視頻),油猴腳本(無限制下載器代碼在最后),ffmpeg(合成視頻);
步驟
1.先打開需要下載的視頻,查看油猴無限制腳本是否顯示,然后啟用speed16倍速。
2.等待視頻播放完成自動下載,下載完記得關(guān)閉。
3.打開目錄,有兩個文件。video開頭是視頻文件(重命名1.mp4),audio開頭是音頻文件(重命名2.mp4);
4.安裝ffepeg,教程ffmpeg安裝教程(windows版)_windows ffmpeg安裝-CSDN博客;
5.cmd打開視頻文件目錄,運行
ffmpeg -i 2.mp4 -vn -c:a copy 2.aac
//主要是將下載的音頻轉(zhuǎn)為可用格式,直接拼接音頻不可用
ffmpeg -i 1.mp4 -i 2.aac -vcodec copy -acodec copy new.mp4
//兩個視頻拼接到一起
無限制下載代碼
// ==UserScript==
// @name Unlimited_downloader
// @name:zh-CN 無限制下載器
// @namespace ooooooooo.io
// @version 0.1.8
// @description Get video and audio binary streams directly, breaking all download limitations. (As long as you can play, then you can download!)
// @description:zh-Cn 直接獲取視頻和音頻二進制流,打破所有下載限制。(只要你可以播放,你就可以下載!)
// @author dabaisuv
// @match *://*/*
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant none
// @run-at document-start
// ==/UserScript==
(function () {
'use strict';
console.log(`Unlimited_downloader: begin......${location.href}`);
//Setting it to 1 will automatically download the video after it finishes playing.
window.autoDownload = 1;
window.isComplete = 0;
window.audio = [];
window.video = [];
window.downloadAll = 0;
window.quickPlay = 1.0;
const _endOfStream = window.MediaSource.prototype.endOfStream
window.MediaSource.prototype.endOfStream = function () {
window.isComplete = 1;
return _endOfStream.apply(this, arguments)
}
window.MediaSource.prototype.endOfStream.toString = function() {
onsole.log('endOfStream hook is detecting!');
return _endOfStream.toString();
}
const _addSourceBuffer = window.MediaSource.prototype.addSourceBuffer
window.MediaSource.prototype.addSourceBuffer = function (mime) {
console.log("MediaSource.addSourceBuffer ", mime)
if (mime.toString().indexOf('audio') !== -1) {
window.audio = [];
console.log('audio array cleared.');
} else if (mime.toString().indexOf('video') !== -1) {
window.video = [];
console.log('video array cleared.');
}
let sourceBuffer = _addSourceBuffer.call(this, mime)
const _append = sourceBuffer.appendBuffer
sourceBuffer.appendBuffer = function (buffer) {
console.log(mime, buffer);
if (mime.toString().indexOf('audio') !== -1) {
window.audio.push(buffer);
} else if (mime.toString().indexOf('video') !== -1) {
window.video.push(buffer)
}
_append.call(this, buffer)
}
sourceBuffer.appendBuffer.toString = function () {
console.log('appendSourceBuffer hook is detecting!');
return _append.toString();
}
return sourceBuffer
}
window.MediaSource.prototype.addSourceBuffer.toString = function () {
console.log('addSourceBuffer hook is detecting!');
return _addSourceBuffer.toString();
}
function download() {
let a = document.createElement('a');
a.href = window.URL.createObjectURL(new Blob(window.audio));
a.download = 'audio_' + document.title + '.mp4';
a.click();
a.href = window.URL.createObjectURL(new Blob(window.video));
a.download = 'video_' + document.title + '.mp4';
a.click();
window.downloadAll = 0;
window.isComplete = 0;
// window.open(window.URL.createObjectURL(new Blob(window.audio)));
// window.open(window.URL.createObjectURL(new Blob(window.video)));
// window.downloadAll = 0
// GM_download(window.URL.createObjectURL(new Blob(window.audio)));
// GM_download(window.URL.createObjectURL(new Blob(window.video)));
// window.isComplete = 0;
// const { createFFmpeg } = FFmpeg;
// const ffmpeg = createFFmpeg({ log: true });
// (async () => {
// const { audioName } = new File([new Blob(window.audio)], 'audio');
// const { videoName } = new File([new Blob(window.video)], 'video')
// await ffmpeg.load();
// //ffmpeg -i audioLess.mp4 -i sampleAudio.mp3 -c copy output.mp4
// await ffmpeg.run('-i', audioName, '-i', videoName, '-c', 'copy', 'output.mp4');
// const data = ffmpeg.FS('readFile', 'output.mp4');
// let a = document.createElement('a');
// let blobUrl = new Blob([data.buffer], { type: 'video/mp4' })
// console.log(blobUrl);
// a.href = URL.createObjectURL(blobUrl);
// a.download = 'output.mp4';
// a.click();
// })()
// window.downloadAll = 0;
}
setInterval(() => {
if (window.downloadAll === 1) {
download();
}
}, 2000);
// setInterval(() => {
// if(window.quickPlay !==1.0){
// document.querySelector('video').playbackRate = window.quickPlay;
// }
//
// }, 2000);
if (window.autoDownload === 1) {
let autoDownInterval = setInterval(() => {
//document.querySelector('video').playbackRate = 16.0;
if (window.isComplete === 1) {
download();
}
}, 2000);
}
(function (that) {
let removeSandboxInterval = setInterval(() => {
if (that.document.querySelectorAll('iframe')[0] !== undefined) {
that.document.querySelectorAll('iframe').forEach((v, i, a) => {
let ifr = v;
// ifr.sandbox.add('allow-popups');
ifr.removeAttribute('sandbox');
const parentElem = that.document.querySelectorAll('iframe')[i].parentElement;
a[i].remove();
parentElem.appendChild(ifr);
});
clearInterval(removeSandboxInterval);
}
}, 1000);
})(window);
// Your code here...
})();