代码
- // ==UserScript==
- // @name Unlimited_downloader
- // @name:zh-CN 无限制下载器
- // @namespace ooooooooo.io
- // @version 0.1.9
- // @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 *://*/*
- // @exclude https://mail.qq.com/*
- // @exclude https://wx.mail.qq.com/*
- // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
- // @grant none
- // @run-atdocument-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() {
- console.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...
- })();
- 点击之后是可以正常播放的
而且这上面的视频如果不太长的话,建议就使用一倍速或者二倍速播放就行了,这样稳当点,不会中间出错,毕竟短视频总共播放完也不用多长时间
正在进行多线程合并
全部合并完毕,36个视频一共耗时138秒,也就是2分钟,其实还挺快的
- import os
- import glob
- import subprocess
- from concurrent import futures
- import time
-
- def make_dir(path):
- import os
- dir = os.path.exists(path)
- if not dir:
- os.makedirs(path)
-
- def process_file(file):
- if (file_prefix in file):
- print('--------------------')
- video_name = os.path.basename(file)
- audio_name = video_name.replace('video_', 'audio_')
- base_name = video_name.replace('video_', '')
- print('base_name:', base_name)
- print('video_name:', video_name)
- print('audio_name:', audio_name)
-
- video_path = os.path.join(folder_path, video_name)
- audio_path = os.path.join(folder_path, audio_name)
- output_path = os.path.join(output_folder, base_name)
-
- print('output_path:', output_path)
- ffmpeg_command = f'ffmpeg -i "{video_path}" -i "{audio_path}" -c:v copy -c:a aac -strict experimental "{output_path}"'
-
- # 使用subprocess运行命令
- print('ffmpeg_command:', ffmpeg_command)
- subprocess.run(ffmpeg_command, shell=True)
-
- folder_path = ''
- file_prefix = 'video_'
- file_extension = '*.mp4' # 假设你只关注扩展名为.mp4的文件
- output_folder = 'merge'
- make_dir(output_folder)
-
- files = glob.glob(os.path.join(folder_path, file_extension))
-
- start_time = time.time()
-
- with futures.ThreadPoolExecutor() as executor:
- executor.map(process_file, files)
-
- end_time = time.time()
- total_time = end_time - start_time
-
- print(f"处理完成,总共使用的时间为:{total_time}秒")