游客发表
打开开发者工具,加密切到Network面板,网页刷新页面,视频找到那个后缀是下载.m3u8或者.ts的请求——恭喜,你离拿到视频文件只差一步。到本地视但多数人卡在这一步:直接右键保存?加密文件是加密的,播放器能放,网页下载器打不开。视频这不是下载什么黑魔法,就是到本地视AES-128或者更复杂的DRM在挡路。
我去年帮朋友扒一套在线课程,加密页面用的网页是HLS流,每个.ts片段单独加密,视频密钥通过一个单独的下载URI获取。浏览器能解密,到本地视是因为它拿到了密钥并且按规范拼接。你要做的,就是模拟这个过程。别想着用那些“一键下载”的浏览器插件,它们遇到加密流基本歇菜,要么下下来一堆乱码。
常见的加密就两种:一种是HLS里的AES-128,密钥明文放在m3u8文件里,或者通过一个链接获取;另一种是Widevine、FairPlay这类DRM,密钥不在你手里,解密得靠CDM模块。前者你能自己动手,后者基本没戏——除非你能拿到解密后的流,但那就不叫“下载加密视频”了。
怎么判断?打开m3u8文件,看有没有#EXT-X-KEY标签。如果有,后面跟着METHOD=AES-128和URI="...",那就是第一种。URI指向一个密钥文件,通常是一串16字节的二进制。把它下载下来,再用ffmpeg或者自己写脚本解密每个.ts片段,最后合并成mp4。
命令行大概长这样:
ffmpeg -i "https://example.com/video.m3u8" -c copy output.mp4 但ffmpeg不是万能的。如果密钥URI需要特定的请求头(比如Referer、Cookie),它不会自动带上。这时候你得手动下载m3u8和密钥,改成本地路径,或者用-headers参数塞进去。我遇到过最坑的情况是密钥URI动态生成,每次请求都不一样,那就得写脚本模拟浏览器行为。
更省事的办法:既然浏览器已经解密并播放了,那内存里或者MediaSource里就有解密后的数据。Chrome的chrome://media-internals可以看媒体信息,但拿不到数据流。真正有用的是MediaSource的SourceBuffer,你可以注入JS钩住appendBuffer方法,把每个解密后的片段存下来。这招对大多数非DRM的加密流有效。
具体操作:在Console里执行一段脚本,重写SourceBuffer.prototype.appendBuffer,把传入的ArrayBuffer保存到全局数组。然后正常播放视频,等播完或者拖到结尾,数组里就是完整的视频数据。最后用Blob和URL.createObjectURL拼成一个文件下载。代码不长,但得注意时机——必须在播放器创建SourceBuffer之前注入。
有人问为什么不直接抓包?因为TLS加密了,你抓到的还是密文。浏览器解密后的数据不会走网络,只在内存里流转。所以钩子方法比抓包靠谱。
Netflix、Disney+这些用的Widevine L1/L3,密钥在CDM里,浏览器只负责把加密数据喂给CDM,解密后的帧直接送进显卡。你钩不到明文。市面上那些“Netflix下载器”要么是录屏,要么是模拟播放然后重新编码,画质损失严重。真能无损下载的,基本都涉及破解CDM,法律风险自己掂量。
我个人的判断:如果只是普通网站用AES-128保护一下,自己动手解密完全合理,毕竟你付了费或者有访问权限。但如果是商业DRM,别折腾了,录屏虽然笨,但至少不违法。技术不是用来突破所有边界的,有些边界存在是有原因的。
最后提醒一句:下载下来的视频别到处传。自己看没问题,传播加密内容可能违反DMCA或者当地法律。工具是中性的,用的人得有点分寸。
友情链接