Python3爬虫通过m3u8文件下载ts视频 Python爬虫

什么是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,

ts 文件一般怎么处理?  

1 只有m3u8文件,需要下载ts文件

2 有ts文件,但因为被加密无法播放,需要解码

3 ts文件能正常播放,但太多而小,需要合并

4 本篇文章处理第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,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)

        try:

            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))

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

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

合并ts文件     使用copy命令 如果不清楚,就去百度即可

在windows系统下面,直接可以使用:copy/b *.ts video.mp4  把所有ts文件合成一个mp4格式文件

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

备注部分

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,440评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,814评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,427评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,710评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,625评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,014评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,511评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,162评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,311评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,262评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,278评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,989评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,583评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,664评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,904评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,274评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,856评论 2 339

推荐阅读更多精彩内容