init
This commit is contained in:
		
							
								
								
									
										38
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| # 通用网页视频下载油猴脚本 | ||||
|  | ||||
| ## 特性 | ||||
| - 使用JS-Hook技术基于MediaSource原理捕获解密后的原始视频流,通杀几乎网页视频保护方案 | ||||
| - 支持直播流 | ||||
|  | ||||
| ## 已测试场景 | ||||
| - bilibili所有视频含付费保护视频 | ||||
| - bilibili直播 | ||||
| - 虎牙直播 | ||||
| - 慕课网 | ||||
| - 腾讯课堂 | ||||
| - P站 -_-; | ||||
|  | ||||
| ## 用法 | ||||
| - 使用油猴插件导入脚本,修改作用域 | ||||
| - 脚本生效后视频完成加载会自动完成下载 | ||||
| - 下载后的文件需要使用FFmpeg完成音视频合并 | ||||
|  | ||||
| ## 参数 | ||||
| ```javascript | ||||
| //自动快进 | ||||
| evanEnv.enableAutoForward = true | ||||
| //完成后自动下载 | ||||
| evanEnv.enableAutoDownload = true | ||||
| ``` | ||||
|  | ||||
| ## FFmpeg合并示例 | ||||
| ```shell | ||||
| ffmpeg -i mediasource_0_0.mp4 -i mediasource_0_1.mp4 -c copy -bsf:a aac_adtstoasc out.mp4 | ||||
| ``` | ||||
|  | ||||
| ## 常见问题 | ||||
| - 合并后声音播放不正常:由于部分网站使用了HE-AAC v2(AAC+SBR+PS)作为音频编码,大部分播放器还不支持此音频流格式,故声音不正常,使用Windows自带的视频播放器播放正常 | ||||
|  | ||||
|  | ||||
| ## 特别说明 | ||||
| - 仅限内部交流使用,请勿用于非法用途 | ||||
							
								
								
									
										106
									
								
								downloadMedia.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								downloadMedia.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,106 @@ | ||||
| // ==UserScript== | ||||
| // @name         Universal encrypted video downloader | ||||
| // @namespace    http://tampermonkey.net/ | ||||
| // @version      0.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== | ||||
|  | ||||
| evanEnv = new Object(); | ||||
| evanEnv.mediaSources = []; | ||||
| evanEnv.enableAutoForward = true; | ||||
| evanEnv.enableAutoDownload = true; | ||||
|  | ||||
| (function () { | ||||
|     evanEnv.videos = document.getElementsByTagName('video'); | ||||
|     evanEnv.buildArrayBuffer = function (bufferList) { | ||||
|         var totalLength = 0; | ||||
|         for (var i = 0; i < bufferList.length; i++) { | ||||
|             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') { | ||||
|         var buff = evanEnv.buildArrayBuffer(bufferList); | ||||
|         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); | ||||
|     }; | ||||
|  | ||||
|     evanEnv.download = function () { | ||||
|         for (var i = 0; i < evanEnv.mediaSources.length; i++) { | ||||
|             var currentItem = evanEnv.mediaSources[i]; | ||||
|             if (currentItem.downloaded == undefined || currentItem.downloaded == false) { | ||||
|                 for (var x = 0; x < currentItem.rawSources.length; x++) { | ||||
|                     evanEnv.downloadRawData(currentItem.rawSources[x], 'mediasource_' + i + '_' + x + '.mp4'); | ||||
|                 } | ||||
|             } | ||||
|             currentItem.downloaded = true; | ||||
|         } | ||||
|     }; | ||||
|     evanEnv.downloadMediaSource = function (mediaSource) { | ||||
|         for (var x = 0; x < mediaSource.rawSources.length; x++) { | ||||
|             evanEnv.downloadRawData(mediaSource.rawSources[x], 'mediasource_' + x + '.mp4'); | ||||
|             mediaSource.downloaded = true; | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     var proxy_addSourceBuffer = MediaSource.prototype.addSourceBuffer; | ||||
|     MediaSource.prototype.addSourceBuffer = function (mimeType) { | ||||
|         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)); | ||||
|         if (this.rawSources == undefined) { | ||||
|             this.rawSources = []; | ||||
|         } | ||||
|         var buffList = []; | ||||
|         this.rawSources.push(buffList); | ||||
|         retSourceBuffer.rawData = buffList; | ||||
|         if (evanEnv.enableAutoForward) { | ||||
|             retSourceBuffer.onupdate = function () { | ||||
|                 if (this.buffered != this.buffered.length > 0) { | ||||
|                     var endPos = this.buffered.end(0); | ||||
|                     if (endPos > 5 && endPos - mediaSourceThis.lastPos > 25) { | ||||
|                         evanEnv.videos[0].currentTime = endPos - 3; | ||||
|                         mediaSourceThis.lastPos = evanEnv.videos[0].currentTime; | ||||
|                     } | ||||
|                 } | ||||
|             }; | ||||
|         } | ||||
|         return retSourceBuffer; | ||||
|     }; | ||||
|     var proxy_appendBuffer = SourceBuffer.prototype.appendBuffer; | ||||
|     SourceBuffer.prototype.appendBuffer = function (buf) { | ||||
|         this.rawData.push(buf); | ||||
|         return proxy_appendBuffer.apply(this, [].slice.call(arguments)); | ||||
|     }; | ||||
| })(); | ||||
		Reference in New Issue
	
	Block a user