Loading...
墨滴

Covh

2021/10/27  阅读:93  主题:橙心

当女朋友让我帮忙下载一个腾讯视频时

背景

作为一名前端开发工程师,我始终认为,在网页上,我们几乎是无所不能的

前两天,女朋友问我网页上的视频怎么下载,我心里想到,装逼的时候来了,于是我抢过鼠标,熟悉的点击右键审查元素,点击视频文件,找到对应的视频mp4链接,右键ctrl+s 一气呵成

然后就等着她对你不断的夸赞吧哈哈哈哈

然后我潇洒的转头离开

没想到过了一会她又来找我,问我说刚刚这个视频怎么下载呢

我说我不是刚给你说过嘛,她说:我有你就行了,学这些干嘛呢😶

我....

于是我嚣张的拿过鼠标,同样的审查元素,找mp4链接,但是我发现我错了,这个视频链接里的不是mp4,不是mp4链接而是blob流文件,这个流文件直接打不开,如下图

当时我就慌了...

解决问题

为了维护自己无所不能的形象,于是乎开始了无休止的查阅资料的过程,后面才了解到了相关资料

HLS

弄懂如何下载blob文件之前我们先要了解到什么是HLS

HLSHTTP Live Streaming的缩写,是由苹果公司提出的基于HTTP的流媒体网络传输协议,它可以同时支持直播和点播,还支持多清晰度、音视频双轨、字幕等功能。它的原理是将一整条视频分成多段小的视频,完整的播放是由这一个个片段拼接而成的。

整个HLS的工作流程是这样的:

  1. 收集音视频文件
  2. 服务端对音视频文件进行编码并且将编码后的文件流交给切片器
  3. 切片器创建音视频索引文件以及ts视频文件,索引文件是多端视频文件的有序列表,ts视频文件是切片器将完整视频切片后的视频片段
  4. 客户端请求服务器上的索引文件以及ts文件,浏览器通过索引文件找出要播放的视频片段

M3U8

M3U8又是什么呢,M3U8是实现上述HLS第三步的文件格式,让我们看看M3U8文件里面是什么内容,下面是从腾讯视频网页端找到了一个M3U8索引文件的内容,为了方便阅读,我把每一行代表的含义注释到代码中

#EXTM3U    表示文件格式的类型 是M3U类型
#EXT-X-VERSION:3    指示播放列表的兼容版本,当前为3
#EXT-X-MEDIA-SEQUENCE:0    代表的是视频索引起始值是从0开始的
#EXT-X-TARGETDURATION:13    代表每个播放片段的最大时长是13秒,当前索引文件内容的所有视频都不超过13秒
#EXT-X-PLAYLIST-TYPE:VOD    当前值为VOD,表示服务器不能改变索引文件;如果是EVENT,则0服务器不能改变或是删除索引文件中的任何部分,但是可以向该文件中增加新的一行内容。
#EXTINF:12.000,   当前片段的时长
00_gzc_1000102_0b53pqaasaaabmacsxdfi5q4a7gdbf3qadka.f321002.1.ts?index=0&start=0&end=12000&brs=0&bre=423187&ver=4&token=ca69857cfb8aff98abc6336a3ba84967  
#当前片段的相对链接
#EXTINF:11.280,
01_gzc_1000102_0b53pqaasaaabmacsxdfi5q4a7gdbf3qadka.f321002.1.ts?index=1&start=12000&end=23280&brs=423188&bre=1023095&ver=4&token=13bcff0fb3cccd71abaaed9d4006c55e
#EXTINF:11.760,
02_gzc_1000102_0b53pqaasaaabmacsxdfi5q4a7gdbf3qadka.f321002.1.ts?index=2&start=23280&end=35040&brs=1023096&bre=1728847&ver=4&token=f4fedc9ebf0286349111995272ac63da
#EXTINF:11.200,
03_gzc_1000102_0b53pqaasaaabmacsxdfi5q4a7gdbf3qadka.f321002.1.ts?index=3&start=35040&end=46240&brs=1728848&bre=2806839&ver=4&token=56755c9b693d440755ad2045962be46e
#EXTINF:10.440,
04_gzc_1000102_0b53pqaasaaabmacsxdfi5q4a7gdbf3qadka.f321002.1.ts?index=4&start=46240&end=56680&brs=2806840&bre=3643439&ver=4&token=7b1784945ade50bc0574d6b121175c38
#EXTINF:12.000,
05_gzc_1000102_0b53pqaasaaabmacsxdfi5q4a7gdbf3qadka.f321002.1.ts?index=5&start=56680&end=68680&brs=3643440&bre=4215523&ver=4&token=581f5a4a22d896f81ba600b451fa01b5
#EXTINF:10.480,
06_gzc_1000102_0b53pqaasaaabmacsxdfi5q4a7gdbf3qadka.f321002.1.ts?index=6&start=68680&end=79160&brs=4215524&bre=4800391&ver=4&token=5b1150dcbf43991c64d43cfd9c97026a
#EXTINF:10.840,
07_gzc_1000102_0b53pqaasaaabmacsxdfi5q4a7gdbf3qadka.f321002.1.ts?index=7&start=79160&end=90000&brs=4800392&bre=5464595&ver=4&token=748e5834a6980c1baa799272c1fe8871
#EXTINF:11.440,
08_gzc_1000102_0b53pqaasaaabmacsxdfi5q4a7gdbf3qadka.f321002.1.ts?index=8&start=90000&end=101440&brs=5464596&bre=5981595&ver=4&token=1ad56a68e98cdbc90770a9c15978f86e
#EXTINF:10.360,
09_gzc_1000102_0b53pqaasaaabmacsxdfi5q4a7gdbf3qadka.f321002.1.ts?index=9&start=101440&end=111800&brs=5981596&bre=6908059&ver=4&token=4e7674db60e90a19c86bd93fb02d1b93
#EXTINF:11.360,
010_gzc_1000102_0b53pqaasaaabmacsxdfi5q4a7gdbf3qadka.f321002.1.ts?index=10&start=111800&end=123160&brs=6908060&bre=8275195&ver=4&token=d822f1af441ea0e1ff36ee3392f5b45f
#EXTINF:11.960,
011_gzc_1000102_0b53pqaasaaabmacsxdfi5q4a7gdbf3qadka.f321002.1.ts?index=11&start=123160&end=135120&brs=8275196&bre=9496819&ver=4&token=c1a49eebde9abce2aec69c42e5693834
#EXTINF:12.000,
012_gzc_1000102_0b53pqaasaaabmacsxdfi5q4a7gdbf3qadka.f321002.1.ts?index=12&start=135120&end=147120&brs=9496820&bre=10699267&ver=4&token=02ae773935016abadce71ed2b2f1cc50
#EXTINF:5.648,
013_gzc_1000102_0b53pqaasaaabmacsxdfi5q4a7gdbf3qadka.f321002.1.ts?index=13&start=147120&end=152768&brs=10699268&bre=10831619&ver=4&token=4b9dbc8a63977559fec11989b1c098d9
#EXT-X-ENDLIST

很明显的可以看到一个M3U8文件里是整个视频比较详细的描述信息,描述了视频切片资源的路径和资源的时长,以及M3U8文件的一些基本内容

如何下载M3U8视频流文件

那么了解了这些基础的内容,我们怎么下载它呢

这里我们会用到一个工具,叫做ffmpeg,

ffmpeg

ffmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。FFmpeg有非常强大的功能包括:视频采集、视频格式转化、视频截图、视频添加水印、视频切片(m3u8、ts)、视频录制、视频推流、更改音视频参数(编码方式、分辨率、码率、比特率等)功能,等等...

这里我们使用到了它的视频格式转化功能,将m3u8流视频转化为mp4

环境准备

前期准备工作当然是安装本地电脑的ffmpeg环境了,具体的安装办法如下,因为我这个是mac系统,所以可以通过homebrew来安装

brew install ffmpeg

windows 的话可以直接去官网上下载exe文件直接傻瓜式安装即可(下载略慢,可能需要翻墙)

紧接着需要校验下ffmpeg是否安装成功

ffmpeg

能看到版本号就是安装成功了

开搞!!!

找到视频对应的m3u8文件

这里我用的是腾讯视频的一个视频,视频链接地址是 为什么国外叫宇航员,我们叫航天员呢

打开页面,调出network,过滤所有的资源,选择Fetch/XHR,这样得到的就是所有的接口资源,紧接着在过滤栏里面输入m3u8,在所有的接口资源里面过滤筛选出m3u8资源

这个时候会发现,好多个m3u8资源懵逼了,按查阅的资料说的,不是说一个流文件视频一般是一个索引文件(m3u8)和多个ts视频片段吗,怎么会有这么多m3u8

带着好奇,我挨个点开了所有的m3u8文件,经过一番瞎鸡儿乱点,我意外的发现了好多个接口里都有一个参数叫vurl的,并且这个参数的值就是我们需要的m3u8文件

而且我看了好几个接口,请求的地址都是同一个文件,于是我打开了这个文件链接,是我们所需要的m3u8清单文件

如何下载清单文件(索引文件)的ts视频片段

有了清单文件,那么对应的ts视频片段就很好找了,打开刚刚下载的m3u8文件

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-TARGETDURATION:19
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:7.400,
00_gzc_1000035_0b2etyaawaaag4agfmdjrvqzlhwdbopaac2a.f304110.1.ts?index=0&start=0&end=7400&brs=0&bre=174839&ver=4&token=7ffa05bc5f8fb4e06fb3c0ceffb01e25
#EXTINF:12.000,
01_gzc_1000035_0b2etyaawaaag4agfmdjrvqzlhwdbopaac2a.f304110.1.ts?index=1&start=7400&end=19400&brs=174840&bre=501583&ver=4&token=235ee39cec228476698845e8d28a3c3d
#EXTINF:12.000,
02_gzc_1000035_0b2etyaawaaag4agfmdjrvqzlhwdbopaac2a.f304110.1.ts?index=2&start=19400&end=31400&brs=501584&bre=808587&ver=4&token=8dee7b8a7f0180ddc9cea3fa24c7a30f
#EXTINF:12.000,
03_gzc_1000035_0b2etyaawaaag4agfmdjrvqzlhwdbopaac2a.f304110.1.ts?index=3&start=31400&end=43400&brs=808588&bre=1113523&ver=4&token=ed413f2ef2fe15d6e3404a9285dfd9f3
#EXTINF:12.000,
04_gzc_1000035_0b2etyaawaaag4agfmdjrvqzlhwdbopaac2a.f304110.1.ts?index=4&start=43400&end=55400&brs=1113524&bre=1625259&ver=4&token=ba46b354983d8bbc6947d6092f7ba0b1
#EXTINF:16.536,
05_gzc_1000035_0b2etyaawaaag4agfmdjrvqzlhwdbopaac2a.f304110.1.ts?index=5&start=55400&end=71936&brs=1625260&bre=2047131&ver=4&token=ee6613ebcc43f71c57cb0652966d88d3
#EXT-X-ENDLIST

当前清单里面就包含了所有的ts链接,不过这些链接都是相对路径,要单独下载的话需要手动将其拼接完整

全部地址就是当前m3u8文件前缀+ts地址

eg:

https://apd-2b5d5d0f3be697448afa51aed34d60f0.v.smtcdns.com/omts.tc.qq.com/ADsLVNV91XJRZyI9e_MJKm9CpwpGTOLjOd3_6Hz0cFVQ/uwMROfz2r55kIaQXGdGnC2dXOm7DLbvBwpViVuB3d6NGBLWa/svp_50069/Xmh_RNZ4x5Uo-TkdRJ9jrq3A4Dp2Eb2tJkJDlS0bnCWlVdH_poK3P4Y02og_SzA-fRSJ1aHWhBgkohMwnpgE87iYTQhyGcn3q_7PP3zeOrZsf5B0kCTPc54OWTlbqBHMkxrrUS9ylKezAAXbeN6Us1TWLeikS8VaNjbCTaiIeIKy-f0PpznnVQ/05_gzc_1000035_0b2etyaawaaag4agfmdjrvqzlhwdbopaac2a.f304110.1.ts?index=5&start=55400&end=71936&brs=1625260&bre=2047131&ver=4&token=ee6613ebcc43f71c57cb0652966d88d3

直接浏览器打开,就可以下载到当前的ts片段了

同理,把所有片段都下载下来,并且文件名称保持不变,放到同一个文件夹内,并且把最早下载的m3u8清单文件也放到同一个文件夹内

紧接着用编辑器打开m3u8文件,需要对文件做一些修改调整,需要把.ts后面的所有参数都删除掉,因为这里是相对路径,而本地的文件没有带参数,所以需要手动删除后面的参数

删除完成之后如下:

到此为止,准备工作已经做完了

片段合并,合成mp4

上面说到HLS中的一个步骤是将一个视频拆分为多个片段,那么接下来的操作就是反向操作,将多个片段合并成一个mp4文件

这个时候久用到了我们大名鼎鼎的ffmpeg了

用终端进入到咱们刚刚准备好的ts以及m3u8文件目录中

执行命令

ffmpeg -i ./gzc_1000035_0b2etyaawaaag4agfmdjrvqzlhwdbopaac2a.f304110.ts.m3u8 "test.mp4"

命令的意思是 转换xxxx.ts.m3u8这个清单为 test.mp4。 test.mp4是生成的文件名

生成成功。让我们在看下文件夹里的内容

已经生成了test.mp4这个文件

打开看看能否正常播放

好了,大功告成!!!

终于可以硬气起来了,又可以摆出很牛逼的表情告诉她,很简单的,一点也不难

后续

不知道什么时候,一次偶然间的机会,我把审查元素打开,然后切换成移动端模式,刷新页面

习惯性的去找video标签的src

瞧瞧我发现了什么

这里居然不是blob,而是可以直接打开的mp4文件!!!

算是一个小惊喜吧,以后下载视频就又多了一个途径了

自动化考虑

上面的过程显的复杂而又麻烦,后续会考虑将很多机械性的流程用代码来控制,做到填写一个视频链接,就能解析出来它的视频文件

甚至可以将ffmpeg 打包到docker里,发部到服务器,更加便捷

总结

  1. 将网页切换为h5模式,很方便的找出video标签的mp4链接
  2. 采用上述抓链接模式,通过ffmpeg进行视频合成

两种方式都可以,不过第二种方式更通用一些,第一种看各个平台h5段视频的播放模式,不一定是用mp4播放

Covh

2021/10/27  阅读:93  主题:橙心

作者介绍

Covh