将m3u8.sqlite格式的文件转码成mp4的过程
个人习惯,比较偏爱将某些视频资料下载到线下进行离线播放。
分析m6u8.sqlite的数据内容
这次想看某投资app的视频,于是先利用app自带的下载功能将视频下载到手机上。发现手机上保存的是 m3u8.sqlite
格式,为了方便分析,于是把这些文件全部转到电脑上,文件大小200M,基本确认视频内容就保存在这个文件中。传到电脑上之后,直接开始使用Linux的sqlite3命令进行分析。
$ sqlite3 demo.m3u8.sqlite
SQLite version 3.22.0 2018-01-22 18:45:57
Enter ".help" for usage hints.
sqlite> .head on
sqlite> .tables
caches metadata
sqlite> select * from caches limit 2;
key|value
xxxx/v.f240.m3u8 | #EXTM3U xxx
xxx/v.f2401004.ts | xxx
通过sqlite3
的命令行,发现有caches和metadata这2个表,从caches表的前两行来看(内容很复杂,做了处理),这个表的第一列是key
,对应数据是文件路径,第二列是value
,是二进制乱码,猜测是文件的视频部分数据。从行来看,第一行是视频文件的扩展信息,对应的是 m3u8
格式文件,之后的行都是ts
格式文件。
提取 m3u8.sqlite的内容到文件中
根据以上的猜测,写了一小段Python
代码demo.py
,将 demo.m3u8.sqlite
的内容解码到本地:
# coding: utf-8
import sys
import os
import sqlite3
def from_sqlite_to_file(filename):
conn = sqlite3.connect(filename)
c = conn.cursor()
data = c.execute('select key, value from caches')
dirname = filename.split('.')[0]
os.mkdir(dirname)
for key, value in data.fetchall():
save_dest = "{}/".format(dirname) + key.split('/')[-1]
with open(save_dest, 'wb') as f:
f.write(value)
if __name__ == '__main__':
filename = sys.argv[1]
from_sqlite_to_file(filename)
执行结果如下:
$ python demo.py demo.m3u8.sqlite
$ ls demo
v.f2400.ts v.f240160.ts v.f240.m3u8
...
$ ls demo/*ts | wc -l
1005
可以看出从 demo.m3u8.sqlite
文件中解码了一个m3u8
格式文件,和多个ts文件,测试了一下, ts文件确实是可以播放的视频,而且一共有1005个ts文件。通过播放器也可以打开v.f240.m3u8
播放视频。
m3u8文件转码成MP4
一千多个小文件,看起来还是很头疼,接下来把m3u8
和ts
转成一段mp4
。
$ cd demo
$ ffmpeg -i "v.f240.m3u8" -bsf:a aac_adtstoasc -vcodec copy -c copy -crf 50 demo.mp4
...
frame=241195 fps=41366 q=-1.0 Lsize= 185697kB time=02:47:29.95 bitrate= 151.4kbits/s speed=1.72e+03x
video:118155kB audio:58874kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 4.896357%
大概几秒钟执行完成之后,可以看到有一个demo.mp4在目录下,这个就是我们最后需要的产物。这段使用ffmpeg
进行文件转码的命令行我没有仔细研究,来源于网上资料,感兴趣的朋友可以研究下。
参考资料:
https://gist.github.com/tzmartin/fb1f4a8e95ef5fb79596bd4719671b5d
当前暂无评论 »