大家好,又见面了,我是你们的朋友全栈君。
1 背景
利用UC浏览器App可以很方便地将一些网页视频下载至本地,如果运气好,打开缓存目录就可以看到对应的mp4文件。但大多数时候,你看到的却是m3u8文件加上一个由数字和字母组成的文件夹,如下所示。
进入该文件夹,你会发现一堆数据文件,虽然没有后缀名,但其实它们都是ts(Transport Stream)媒体分片文件。其中每一个都可以用播放器单独打开,也都是几秒钟的分段视频。如果想观看完整版,也只能在手机浏览器中离线体验了。
2 HLS和M3U8简介
HLS(HTTP Live Streaming)是苹果公司针对iPhone、iPod、iTouch和iPad等移动设备而开发的基于HTTP协议的流媒体解决方案。在HLS技术中,Web服务器向客户端提供接近实时的音视频流,同时采用标准的HTTP协议。所以,只要使用HLS的技术,就能在普通的HTTP应用上直接提供点播和直播。在App Store中的视频相关应用,基本都是应用的此种技术。其基本原理是将视频文件或视频流切分成小片(ts)并建立索引文件(m3u8)。支持的视频流编码为H.264,音频流编码为AAC。 也就是说,真正的视频文件是在第一张图中文件夹里,每一个文件夹对应的m3u8用来告诉视频插件如何依次播放里面的ts文件,从而呈现给用户一个完整的视频。
3 命令行操作
3.1 软件工具
需要用到ffplay和ffmpeg命令行。
3.2 利用ffplay观看
将m3u8文件视为文本打开,可以看到里面存储着每一个ts文件的绝对路径。
代码语言:javascript复制#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:8
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:4.000000,
/storage/896D-1F02/Android/data/com.UCMobile/files/UCDownloads/VideoData//94bad5572f90065418914b4481bf7d1ae19403dc/Y2hlbmppbmdjb25n0
#EXTINF:6.360000,
/storage/896D-1F02/Android/data/com.UCMobile/files/UCDownloads/VideoData//94bad5572f90065418914b4481bf7d1ae19403dc/Y2hlbmppbmdjb25n1
#EXTINF:4.000000,
/storage/896D-1F02/Android/data/com.UCMobile/files/UCDownloads/VideoData//94bad5572f90065418914b4481bf7d1ae19403dc/Y2hlbmppbmdjb25n2
#EXTINF:2.080000,
……
毫无疑问,视频文件拷到linux文件系统中后,首先就要将这些指向安卓机的绝对路径替换成电脑上的绝对路径或相对路径。如下所示。
代码语言:javascript复制#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:8
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:4.000000,
./94bad5572f90065418914b4481bf7d1ae19403dc/Y2hlbmppbmdjb25n0
#EXTINF:6.360000,
./94bad5572f90065418914b4481bf7d1ae19403dc/Y2hlbmppbmdjb25n1
#EXTINF:4.000000,
./94bad5572f90065418914b4481bf7d1ae19403dc/Y2hlbmppbmdjb25n2
#EXTINF:2.080000,
……
此时,在保证m3u8文件和对应的94bad5572f90065418914b4481bf7d1ae19403dc文件夹处于同一父目录的条件下,再键入
代码语言:javascript复制ffplay XXX.m3u8
好了,真以为这就大功告成了吗?请看下面的报错。
代码语言:javascript复制Filename extension of './94bad5572f90065418914b4481bf7d1ae19403dc/Y2hlbmppbmdjb25n1395' is not a common multimedia extension, blocked for security reasons.
显然,基于安全考虑,官方补丁将没有后缀名的ts文件屏蔽掉了,具体可参见FFmpeg任意文件读取漏洞分析。
最直接的解决办法,就是分别在m3u8文件和对应文件夹中批量加上后缀名ts。前一个好说,后一个得在该文件目录下借助命令
代码语言:javascript复制ls -A | xargs -i mv {
} {
}.ts
当然,我们有更简单的办法,就是在ffplay命令中添加选项
代码语言:javascript复制ffplay -allowed_extensions ALL XXX.m3u8
ffplay命令成功运行后,会出来一个播放界面,但是没有控制按钮,只能通过鼠标和快捷键进行一些简单的互动操作。如空格是暂停/继续,方向键的左右是前进和后退,鼠标左键双击是全屏,鼠标右键左右滑动是快进和快退等。
3.3 利用ffmpeg转码
只需很简单的一行命令就能将整个视频转成mp4格式。
代码语言:javascript复制ffmpeg -allowed_extensions ALL -i XXX.m3u8 -c copy aaa.mp4
其中: -i选项后面跟输入文件,即m3u8索引; -c copy表明要拷贝所有的流,等价于-acodec copy -vcodec copy; aaa.mp4是输出文件。
4 图形界面操作
如果安装了Videos等图形操作界面,那么只需要将m3u8中的路径信息参照上一节修改后,就可以直接添加播放了,根本不用考虑filename extension的事(当然,这会存在一定的安全隐患),而且控制按钮会比较齐全。 然而在转码时,我实在没有找到很好的图形界面操作软件。试用了一下wine 格式工厂,即不管m3u8索引信息,强行合并ts媒体流,却发现格式工厂在合并时,添加的视频数量是有限的,对于一些大电影来讲,成百上千的ts文件早就超了。而且,格式工厂默认好像不会直接拷贝拼接ts流,而是把所有音视频流都从头到尾再编码一遍,硬件资源开销不小。个人感觉,针对m3u8的转码,好多图形界面都是坑,还是ffmpeg命令行最简单可靠。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/129157.html原文链接:https://javaforall.cn