下载合并ts流媒体文件

基本原理,通过浏览器“开发者工具”,找到 m3u8 文件(如果有2个m3u8,注意查看其响应内容,确保是包含 ts 文件列表的那个,通常是第2个),再使用爬虫下载所有的 ts 文件到本地,最后通过 ffmpeg 工具合并为 mp4。

一、遇到的坑

1、使用以下命令,在线下载并生成 mp4 时,文件过多时,中途会卡死。

ffmpeg -i http://ip:port/abc/index.m3u8 -c copy -bsf:a aac_adtstoasc output.mp4
解决办法:自己把所有的 ts 文件下载到本地,再合并。

2、循环使用 requests 下载多个文件时,卡死,其实是链接超时,但因为某种原因它既不报错也不退出。

解决办法:在 requests.get 中增加超时参数,重新链接。

3、本地合并时报“Invalid data found when processing input”错误。原因在于 ts 文件被加密。

解决办法:将 m3u8 中的 key 文件路径改为本地,并在 ffmpeg 中增加 -protocol_whitelist "file,http,https,crypto,tcp" 选项。

二、操作过程

1、下载 index.m3u8 文件到本地,通过 python 的 m3u8 模块读取解析,获得所有 ts 地址,并全部下载之。

2、下载 key 文件(地址在 m3u8 中)保存到本地当前目录,并修改 m3u8 中的 key 地址为当前目录。

3、修改 m3u8 中所有的 ts 文件地址为本地地址。

4、当前目录执行命令:

ffmpeg -allowed_extensions ALL -protocol_whitelist "file,http,https,crypto,tcp" -i index.m3u8 -c copy out.mp4

三、代码

import m3u8, requests

m3u8_file = 'index.m3u8'
start = 0

def get_ts(url):
    i = 0
    while i < 3:
        try:
            rep = requests.get(url, timeout=(5.05, 27)).content
            return rep
        except requests.exceptions.RequestException:
            i += 1

def down_seg(i):
    uri = data["segments"][i]['uri']
    pos = uri.rfind('/')
    ts_filename = uri[pos+1:]
    print(i, ts_filename, "...", end='\t')
    ts = get_ts(uri)
    f = open('ts/'+ts_filename, 'wb')
    f.write( ts )
    f.close()
    print('DONE')

data = m3u8.load(m3u8_file).data
for i in range(start, len(data["segments"])):
    down_seg(i)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容