背景
- 之前笔者实现了m3u8 视频在线提取工具,可对 m3u8 视频进行提取,合并,下载。实现整个视频下载流程。
- 后续还实现了非定制性的 ASE 解密性能(不提供定制性服务,定制性解密,属于破解,侵权行为,需尊重知识产权)
- 但上述工具仍存在肯定的通用性问题。为彻底解决通用性,实现无差别视频提取,开发了这个工具。
特点
- 长处,通用性强,无差别提取,只有应用到 MES 支流媒体播放技术的视频,均可捕捉。
- 长处,足够简略,在视频播放的最初一个步骤进行拦挡,躲避视频加载,加密,解密等简单过程。
- 毛病,被动,无奈被动干涉视频加载,只可被动捕捉视频资源。
- 毛病,有肯定门槛,依赖 chrome 浏览器开发者模式,无奈实现全自动化,有肯定应用门槛。
应用示例链接
性能阐明
【已捕捉 0 个片段】
- 显示程序已捕捉的视频片段数。
【下载已捕捉片段】
- 能够强制下载曾经捕捉的片段,无需期待整个视频全副捕捉实现。
【十倍速捕捉】
- 因为视频捕捉是依赖视频加载进度的。
- 点击该按钮,能够十倍速播放,减速视频加载,减速视频捕捉。
当视频全副加载实现,将触发主动下载。
- 若无触发,可手动点击「下载已捕捉片段」按钮,对捕捉到的视频进行下载。
应用形式
示例试验链接
复制工具代码
- 能够间接复制本文中的外围源码
- 也能够点开示例试验链接,点击按钮,疾速复制工具代码。
- 关上目前页面的控制台
- ctrl + f ,输出 <iframe,判断是否存在 iframe 内嵌页面。若存在 iframe,请看完本阐明,再持续查看下一节「iframe 解决方案」。若无,则下一步
- 关上代码调试面板
在调试面板中,找到以后页面的代码
- 留神文件的寻找办法,需依据 URL 中的门路层级寻找。
- 点击下方按钮,对代码进行排版。
搜寻,找到第一个 <script 标签,并设置多个断点
- 搜寻,如果第一个 <script 标签是一个链接。
- 则找到对应文件,设置断点。
- 搜寻,如果第一个 <script 标签是一个链接。
刷新页面,呈现如下状态,则证实断点设置胜利
- 若页面白屏,为失常景象,依照步骤继续执行即可。
- 在 console 栏,粘贴工具代码,回车
- 回到 source 栏,点击按钮,复原运行
- 若页面呈现这几个按钮,则证实注入胜利,工具运行胜利
失常观看视频,期待视频捕捉
- 可点击「十倍速捕捉」,接口视频播放速度,放慢视频捕捉速度。
- 若页面呈现如下弹窗,即捕捉实现,视频主动下载(也能够点击「下载已捕捉片段」,手动下载)
视频下载实现,失去「音频」文件,「视频」文件
- 可应用专属播放器,进行播放。
- 也能够应用其余工具,进行合并。
iframe 解决方案
示例试验链接
找到 iframe 标签,复制 src 中的 url,新建页面关上该 url。
- 如果该新建页面能失常播放视频,则在该新建页面,应用上述「应用阐明」即可。
- 如果该新建页面能失常播放视频,则在该新建页面,应用上述「应用阐明」即可。
- 如果新建页面没有失常播放页面,则回到原页面,换一种形式实现。
回到原页面,找到 iframe 内嵌页面的源码。
- 同样搜寻 <script,但这一次,要找带 src 的 script 标签
- 同样搜寻 <script,但这一次,要找带 src 的 script 标签
- 找到该 src 对应的文件,并打断点
刷新页面,并在源文件中,插入代码
- 留神,打断点和插入代码是在不同的栏,打断点的栏中,有「:format」标识。插入代码的栏,没有该标识。
- 粘贴代码,ctrl + s 进行保留
- 复原执行(操作形式,查看上一节「应用阐明」)
- 实现代码插入,捕捉视频
特地阐明
- 在代码操作过程中,页面白屏是失常的,依照步骤继续执行即可。
- 如果不行,装置应用阐明,多试几遍就能够了。可能是视频广告导致。
- 留神 Chrome 的多文件下载询问,如果回绝过,须要从新关上。
- 视频捕捉,分为「视频」文件与「音频」文件,「视频」文件是纯视频,没声音的。须要搭配「音频」文件播放。点击这里,应用专属播放器。
专属播放器
- 因为采集工具是独自对「视频」和「音频」离开采集的。
- 应用一般播放器可能无奈失常播放。
- 可利用本工具同时加载「视频」和「音频」同步播放。
- 本工具还附有倍速播放性能。
原理
- 支流视频媒体播放技术,均应用到 MES 技术
MES 技术播放流程个别如下:
- 创立 video 播放器标签。
- 拉取视频片段。
- 解密视频片段(如果对视频进行了加密操作)
- 解析视频片段,分为「视频轨」「音频轨」。
- 将每个片段的「视频轨」「音频轨」,"喂给" video 标签进行播放。
- 当已加载的视频片段快要播完时,反复第二个步骤,拉取新的视频片段,进行投喂。
本工具的外围逻辑
- 覆写视频片段的"投喂"操作。
- 插入自定义代码,收集"投喂"的「视频」「音频」资源,进行下载。
外围源码(共 91 行)
(function () { let _sourceBufferList = [] let $btnDownload = document.createElement('div') let $downloadNum = document.createElement('div') let $tenRate = document.createElement('div') // 十倍速播放 // 十倍速播放 function _tenRatePlay () { let $domList = document.getElementsByTagName('video') for (let i = 0, length = $domList.length; i < length; i++) { const $dom = $domList[i] $dom.playbackRate = 10 } } // 下载捕捉到的资源 function _download () { _sourceBufferList.forEach((target) => { const mime = target.mime.split(';')[0] const type = mime.split('/')[1] const fileBlob = new Blob(target.bufferList, { type: mime }) // 创立一个Blob对象,并设置文件的 MIME 类型 const a = document.createElement('a') a.download = `${document.title}.${type}` a.href = URL.createObjectURL(fileBlob) a.style.display = 'none' document.body.appendChild(a) a.click() a.remove() }) } // 监听资源全副录取胜利 let _endOfStream = window.MediaSource.prototype.endOfStream window.MediaSource.prototype.endOfStream = function () { alert('资源全副捕捉胜利,行将下载!') _download() _endOfStream.call(this) } // 捕捉资源 let _addSourceBuffer = window.MediaSource.prototype.addSourceBuffer window.MediaSource.prototype.addSourceBuffer = function (mime) { console.log(mime) let sourceBuffer = _addSourceBuffer.call(this, mime) let _append = sourceBuffer.appendBuffer let bufferList = [] _sourceBufferList.push({ mime, bufferList, }) sourceBuffer.appendBuffer = function (buffer) { $downloadNum.innerHTML = `已捕捉 ${_sourceBufferList[0].bufferList.length} 个片段` bufferList.push(buffer) _append.call(this, buffer) } return sourceBuffer } // 增加操作的 dom function _appendDom () { const baseStyle = ` position: fixed; top: 50px; right: 50px; height: 40px; padding: 0 20px; z-index: 9999; color: white; cursor: pointer; font-size: 16px; font-weight: bold; line-height: 40px; text-align: center; border-radius: 4px; background-color: #3498db; box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.3); ` $tenRate.innerHTML = '十倍速捕捉' $downloadNum.innerHTML = '已捕捉 0 个片段' $btnDownload.innerHTML = '下载已捕捉片段' $tenRate.style = baseStyle + `top: 150px;` $btnDownload.style = baseStyle + `top: 100px;` $downloadNum.style = baseStyle $btnDownload.addEventListener('click', _download) $tenRate.addEventListener('click', _tenRatePlay) document.getElementsByTagName('html')[0].insertBefore($tenRate, document.getElementsByTagName('head')[0]); document.getElementsByTagName('html')[0].insertBefore($downloadNum, document.getElementsByTagName('head')[0]); document.getElementsByTagName('html')[0].insertBefore($btnDownload, document.getElementsByTagName('head')[0]); } _appendDom()})()
我的项目源码
申明
本我的项目仅用于学习,交换,切勿用于侵权行为。