什么是m3u8文件 M3U8文件是指UTF-8编码格式的M3U文件。M3U文件是记录了一个索引纯文本文件,打开它时播放软件并不是播放它,而是根据它的索引找到对应的音视频文件的网络地址进行在线播放。 原视频数据分割为很多个TS流,每个TS流的地址记录在m3u8文件列表中 比如我这里有一个m3u8文件...

什么是m3u8文件

M3U8文件是指UTF-8编码格式的 M3U文件
M3U文件 是记录了一个 索引纯文本文件
打开它时播放软件并不是播放它,而是根据它的索引找到对应的音视频文件的网络地址进行在线播放。

原视频数据分割为很多个TS流,每个TS流的地址记录在m3u8文件列表中

比如我这里有一个m3u8文件,文件内容如下

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:15
#EXTINF:6.916667,
out000.ts
#EXTINF:10.416667,
out001.ts
#EXTINF:10.416667,
out002.ts
#EXTINF:1.375000,
out003.ts
#EXTINF:1.541667,
out004.ts
#EXTINF:7.666667,
out005.ts
#EXTINF:10.416667,

ts 文件一般怎么处理

  • 只有m3u8文件,需要下载ts文件
  • 有ts文件,但因为被加密无法播放,需要解码
  • ts文件能正常播放,但太多而小,需要合并
  • 本篇文章处理第1和第2条内容,加密部分跳过。

    上面我提供的ts文件中并没有加密,也就是没有关键字key ,下载ts文件之后直接合并即可

    ts文件路径获取

    由于上面的m3u8文件中所有的ts文件都是相对地址,所以需要依据上篇博客中获取到的链接

    {'url': 'https://videos5.jsyunbf.com/2019/02/07/iQX7y3p1dleAhIv7/playlist.m3u8', 'ext': 'dplay', 'msg': 'ok', 'playertype': None}
    

    其中前面的部分是ts的播放地址的前缀地址

    # https://videos5.jsyunbf.com/2019/02/07/iQX7y3p1dleAhIv7/out005.ts import datetime import requests # m3u8是本地的文件路径 def get_ts_urls(m3u8_path,base_url): urls = [] with open(m3u8_path,"r") as file: lines = file.readlines() for line in lines: if line.endswith(".ts\n"): urls.append(base_url+line.strip("\n")) return urls

    ts文件下载

    所有的路径读取完毕之后,需要对ts文件进行下载,文件的下载办法很多

    def download(ts_urls,download_path):
        for i in range(len(ts_urls)):
            ts_url = ts_urls[i]
            file_name = ts_url.split("/")[-1]
            print("开始下载 %s" %file_name)
            start = datetime.datetime.now().replace(microsecond=0)
                response = requests.get(ts_url,stream=True,verify=False)
            except Exception as e:
                print("异常请求:%s"%e.args)
                return
            ts_path = download_path+"/{0}.ts".format(i)
            with open(ts_path,"wb+") as file:
                for chunk in response.iter_content(chunk_size=1024):
                    if chunk:
                        file.write(chunk)
            end = datetime.datetime.now().replace(microsecond=0)
            print("耗时:%s"%(end-start))
    

    下载过程显示,表示下载成功,剩下的就是拼网速的时候了。
    image

    下载完毕,是一大堆ts文件,记住,只要一个可以看,就可以合并了
    image

    合并ts文件

    使用copy命令 如果不清楚,就去百度即可

    copy/b D:\newpython\doutu\sao\ts_files\*.ts d:\fnew.ts
    
    import os
    from os import path
    def file_walker(path):
        file_list = []
        for root, dirs, files in os.walk(path): # 生成器
            for fn in files:
                p = str(root+'/'+fn)
                file_list.append(p)
        print(file_list)
        return file_list
    def combine(ts_path, combine_path, file_name):
        file_list = file_walker(ts_path)
        file_path = combine_path + file_name + '.ts'
        with open(file_path, 'wb+') as fw:
            for i in range(len(file_list)):
                fw.write(open(file_list[i], 'rb').read())
    if __name__ == '__main__':
        #urls = get_ts_urls("playlist.m3u8","https://videos5.jsyunbf.com/2019/02/07/iQX7y3p1dleAhIv7/")
        #download(urls,"./tsfiles")
        combine("./ts_files","d:/ts","haha")
    

    最终合并之后,形成一个ts文件,当然你还可以用软件把视频转换成mp4格式

    也可以利用FFMPEG可以直接实现m3u8 转MP4

    愉快的下载下来看VIP视频吧
    image

    m3u8文件中的 m3u8标签与属性说明

    #EXTM3U
    每个M3U文件第一行必须是这个tag,请标示作用
    #EXT-X-VERSION:3 
    该属性可以没有
    #EXT-X-MEDIA-SEQUENCE:140651513 
    每一个media URI在PlayList中只有唯一的序号,相邻之间序号+1, 
    一个media URI并不是必须要包含的,如果没有,默认为0
     #EXT-X-TARGETDURATION
    指定最大的媒体段时间长(秒)。所以#EXTINF中指定的时间长度必须小于或是等于这
    个最大值。这个tag在整个PlayList文件中只能出现一 次(在嵌套的情况下,一般有
    真正ts url的m3u8才会出现该tag)
    #EXT-X-PLAYLIST-TYPE
    提供关于PlayList的可变性的信息,这个对整个PlayList文件有效,是可选的,格式
    如下:#EXT-X-PLAYLIST-TYPE::如果是VOD,则服务器不能改变PlayList 文件;
    如果是EVENT,则服务器不能改变或是删除PlayList文件中的任何部分,但是可以向该
    文件中增加新的一行内容。
    #EXTINF
    duration指定每个媒体段(ts)的持续时间(秒),仅对其后面的URI有效,title是
    下载资源的url
    #EXT-X-KEY
    表示怎么对media segments进行解码。其作用范围是下次该tag出现前的所有media 
    URI,属性为NONE 或者 AES-128。NONE表示 URI以及IV(Initialization 
    Vector)属性必须不存在, AES-128(Advanced EncryptionStandard)表示URI
    必须存在,IV可以不存在。
    #EXT-X-PROGRAM-DATE-TIME
    将一个绝对时间或是日期和一个媒体段中的第一个sample相关联,只对下一个meida 
    URI有效,格式如#EXT-X-PROGRAM-DATE-TIME:
    For example: #EXT-X-PROGRAM-DATETIME:2010-02-19T14:54:23.031+08:00
    #EXT-X-ALLOW-CACHE
    是否允许做cache,这个可以在PlayList文件中任意地方出现,并且最多出现一次,作
    用效果是所有的媒体段。格式如下:#EXT-X-ALLOW-CACHE:
    #EXT-X-ENDLIST
    表示PlayList的末尾了,它可以在PlayList中任意位置出现,但是只能出现一个,格
    式如下:#EXT-X-ENDLIST
                    R和Python平台下操作读写稀疏矩阵(matrix.mtx.gz格式文件)的基本方法
                
    将大型矩阵保存为稀疏矩阵格式特别有助于减少存储空间和提高数据处理的效率,因此本文将分享在R和Python平台下操作读写稀疏矩阵的基本方法。