写了一个无限制视频下载脚本

2022-05-31 17:38:14 +08:00
 dabaisuv

在家想下载视频到本地,发现很多视频网站的video标签的src指向了 Blob: http(s)://xxx.xxx.xxx/xxx,直接进这个链接的话会显示链接已禁用。 想法:既然能播放视频,就证明视频到最后一定是被 video 拿到了的.

谷歌一圈后发现了: 1.window.URL.createObjectURL(object)方法会返回该链接

A File, Blob, or MediaSource object to create an object URL for.( https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL

2.window.URL.revokeObjectURL(objectURL),禁用上面返回的链接

A string representing a object URL that was previously created by calling createObjectURL().( https://developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL)

尝试:

1.hook 了window.URL.revokeObjectURL(objectURL)来忽略禁用请求,结果没用,依旧被禁用。

2.换个方法,直接 hook 二进制流,你缓存多少,我给你复制多少。查了下MediaSource, 他结合上面的createObjectURL(object)可以分片的方式加载视频,大概就是看多少,就加多少。 其中的音频和视频分别放在两个 sourceBuffer 中,直接 hook 住SourceBuffer.appendBuffer()就能实现视频流的截取了。再将每个分片以数组的方式保存下来,最后等视频缓存完后 new Blob(video/audio bufferArray)这样就实现了视频和音频的保存。

3.由于播放的时候,视频和音频分在两个 SourceBuffer 中,所以最后会得到两个文件。又是一番谷歌,有如下命令:

ffmpeg -i video.mp4 -i audio.mp4 -c:v copy -c:a aac -strict experimental output.mp4

可以将其合并为一个视频。

4.想过用 ffmpeg 的 wasm 库来在线合并,最后输出的,发现 ffmpeg-core 初始化时所需要的文件在国内下载不下来导致报错,从而导致适用的用户可能有点少,所以就没加,可能是我使用方法不对,以后有时间可以改改。

5.发现有些网站的视频是在iframe标签下的,并且加了sandbox属性,而有该属性的话就会导致最后的下载被拦截,于是,我使用了如下代码来将页面中的所有frame替换成无sandbox属性的:

 (function (that) {
          let removeSandboxInterval = setInterval(() => {
             if (that.document.querySelectorAll('iframe')[0] !== undefined) {
                that.document.querySelectorAll('iframe').forEach((v, i, a) => {
                   let ifr = v;
                   ifr.removeAttribute('sandbox');
                   const parentElem = that.document.querySelectorAll('iframe')[i].parentElement;
                   a[i].remove();
                   parentElem.appendChild(ifr);
                });
                clearInterval(removeSandboxInterval);
             }
          }, 1000);
       })(window);

于是有了如下油猴脚本:

英文名:Unlimited_downloader

https://greasyfork.org/en/scripts/445751-unlimited-downloader

Ps: 都是谷歌翻译成英文的,因为英文是个通用语言,所以不同地方的人看起来可能要方便点。

简短说明:

原理:直接 hook 媒体二进制流,换句话说就是你能看到,你就能下载,你能缓存多快,你就能下载多快。

使用方法:安装后,打开任意有视频或音频的网站,等视频缓存条加载完后会自动下载下来。

也可以自己手动开 16 倍速加速缓存,控制台输入:document.querySelector('video').playbackRate = x

最后,免责声明:请在合法范围内使用脚本,请勿用作任何非法用途,后果与作者无关。

23650 次点击
所在节点    程序员
95 条回复
heiyutian
2022-06-01 09:43:07 +08:00
建议可以只保存观看或缓冲的部分,有很多视频真的只需要一部分就够了,有时候并不需要整个视频,如果视频很长就比较费流量和时间了。
Rrrrrr
2022-06-01 10:10:11 +08:00
b 站确实不行,只有音频。我之前都是自己去分析代码,拿到真实地址,不过比较费时间。
zhaozhao
2022-06-01 10:37:42 +08:00
之前看到过一个完成度挺高的工具,原理一样

“无差别视频提取工具”
https://segmentfault.com/a/1190000025182822
tianyou666shen
2022-06-01 10:55:50 +08:00
用这个下了个视频 还不错 就是免费版两小时只能下一次文件
Video DownloadHelper (chrome)
root01
2022-06-01 10:58:48 +08:00
OP 很给力,但是视频和音频下载下来是分开的,美中不足
非常感谢 OP
root01
2022-06-01 11:07:17 +08:00
抱歉,没看完整,原来是分开的
OMGZui
2022-06-01 11:15:41 +08:00
感谢,很牛逼
ethusdt
2022-06-01 11:50:37 +08:00
这个原理不错, 前几天刚好遇到这个问题 : [Instagram 网页版视频是如何限制在 devtools 中找到视频链接进行直接下载的]( https://v2ex.com/t/852210#reply6)
shaojz2005
2022-06-01 12:16:38 +08:00
这些是针对什么视频网站的。我试了这几个,好像 B 站都下不回来
dabaisuv
2022-06-01 16:01:27 +08:00
@shaojz2005 测试的时候国内外的都行的。
dabaisuv
2022-06-01 16:02:41 +08:00
@zhaozhao 看了下,原理是一样的,而且他还写了界面,感觉好用的多
dabaisuv
2022-06-01 16:03:22 +08:00
@Rrrrrr 测试的时候都行的啊,我昨晚都能下
dabaisuv
2022-06-01 16:04:14 +08:00
@heiyutian 控制台输入 window.downloadAll = 1 可以提前下载
hxz0803
2022-06-01 20:46:48 +08:00
试了一下,DMM 那种视频也可以下载
xifangczy
2022-06-02 03:13:52 +08:00
之前我也有类似的想法,甚至经历都跟你差不多一步步试验过来,想装到 chrome 扩展里...因为扩展 manifest 升级到了 V3 然后又因为 V3 的脚本注入 API scripting 又巨难用,它甚至不能在 document-start 运行(刚刚去看了 102 版终于加上了)... 我就搁置了。。还是油猴脚本好使啊
shaojz2005
2022-06-02 09:26:34 +08:00
@dabaisuv 我装了你这个插件,然后打开哔哩哔哩视频时,在视频页没有右上角的捕获片段的提示,但是哔哩哔哩首页或者搜索页(即进入详情页的上一页)会有提示捕获,但最后都没下载到什么完整的视频,都是一些小片段。不知道我是不是操作流程有什么问题。。。
shaojz2005
2022-06-02 09:38:24 +08:00
咦,再试了下又可以了
dabaisuv
2022-06-02 09:51:06 +08:00
@shaojz2005 这代码没有加右上角的捕获片段提示啊,捕获到了片段会在控制台打印出来
Rrrrrr
2022-06-02 10:56:11 +08:00
应该要加个按钮,点开始才下,我昨晚看 youtube 怎么突然就给我下了一个视频
heiyutian
2022-06-02 11:01:15 +08:00
@dabaisuv 如果把只保存观看或缓冲的部分加到 Tampermonkey 的右键菜单来启用就更好了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/856510

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX