Python通过m3u8文件下载合并ts视频的操作


Posted in Python onApril 16, 2021

前段时间,接到一个需求,要求下载某一个网站的视频,然后自己从网上查阅了相关的资料,在这里做一个总结。

1. m3u8文件

m3u8是苹果公司推出一种视频播放标准,是一种文件检索格式,将视频切割成一小段一小段的ts格式的视频文件,然后存在服务器中(现在为了减少I/o访问次数,一般存在服务器的内存中),通过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,

2. ts文件处理

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

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

但因为被加密无法播放,需要解码

在这里我只记录下前两个步骤,因为,我目前研究的比较少,还没有遇到ts被加密的情况。

3. 分析举例

那么下面,我就正式举一个网站,第一财经网(直接点击)跟大家正式的讲解下。

这是该网站的视频。如下图:

Python通过m3u8文件下载合并ts视频的操作

点击第一个视频,这就是我们这次要爬取的视频。

Python通过m3u8文件下载合并ts视频的操作

然后鼠标右键点击,选择"检查" 或者按F12键,进入开发者模式,查看网页代码。

然后,点击Network ,再点击other,寻找请求地址中带有m3u8和ts标记的请求地址。

不懂,请看下图。有一点,很重要。网站通过切割后ts加载视频,并不是没有规律的,而是通过m3u8文件附带的。也就说,网站一定是先加载m3u8文件,然后根据m3u8文件,去请求ts文件。所以,如果你找不到m3u8文件的话,你可以先找第一个ts文件,然后往上面翻,一定能找到m3u8文件。

Python通过m3u8文件下载合并ts视频的操作

再点击这个m3u8文件,右侧对应的就是它的请求地址。

Python通过m3u8文件下载合并ts视频的操作

请求地址如下:

https://ycalvod.yicai.com/record/live/cbn/ca233887-1443-4bdf-b762-3b4b3a217085_LD.m3u8?auth_key=1575703722-0-0-6f09e9a156491f027a035e31c238c48c&ycfrom=yicaiwww

你可以把上面那个地址,输入浏览器地址框内,下载下来。也可以通过查看源码,找到该功能的对应的html代码。

这是下载下来的m3u8文件。

Python通过m3u8文件下载合并ts视频的操作

Python通过m3u8文件下载合并ts视频的操作

从图片可以看出来,每一个ts文件都是相对的地址,所以下面我们就需要找到绝对地址。

Python通过m3u8文件下载合并ts视频的操作

ts文件地址如下:

https://ycalvod.yicai.com/record/live/cbn_yld/1575111614_3446078.ts

上面,我们已经把这个网站的视频加载模式分析的很透彻,下面就开始撸代码了。

4. 获取ts文件

def getTsUrl():
    ts_url_list = []
    baseUrl = "https://ycalvod.yicai.com/record/live"
    with open("ca233887-1443-4bdf-b762-3b4b3a217085_LD.m3u8", "r", encoding="utf-8") as f:
        m3u8Contents = f.readlines()
        for content in m3u8Contents:
            if content.endswith("ts\n"):
                ts_Url = baseUrl + content.replace("\n", "").replace("..", "")
                ts_url_list.append(ts_Url)
                print(ts_Url)
    return ts_url_list

5. 下载ts文件

def download_ts_video(download_path, ts_url_list):
    download_path = r"C:\Users\Administrator\Desktop\AiShu\下载视频\TS视频"
    for i in range(len(ts_url_list)):
        ts_url = ts_url_list[i]
        try:
            response = requests.get(ts_url, stream=True, verify=False)
        except Exception as e:
            print("异常请求:%s" % e.args)
            return
        ts_path = download_path + "\{}.ts".format(i)
        with open(ts_path, "wb+") as file:
            for chunk in response.iter_content(chunk_size=1024):
                if chunk:
                    file.write(chunk)
    print("TS文件下载完毕!!")

这就是我本地下载好的ts切割视频

Python通过m3u8文件下载合并ts视频的操作

6. 合并TS视频

def heBingTsVideo(download_path,hebing_path):
    all_ts = os.listdir(download_path)
    with open(hebing_path, 'wb+') as f:
        for i in range(len(all_ts)):
            ts_video_path = os.path.join(download_path, all_ts[i])
            f.write(open(ts_video_path, 'rb').read())
    print("合并完成!!")

最后的结果如下:

Python通过m3u8文件下载合并ts视频的操作

7. 完整的代码

有兴趣的小伙伴,可以研究下。

import requests,os
def getTsUrl():
    ts_url_list = []
    baseUrl = "https://ycalvod.yicai.com/record/live"
    with open("ca233887-1443-4bdf-b762-3b4b3a217085_LD.m3u8", "r", encoding="utf-8") as f:
        m3u8Contents = f.readlines()
        for content in m3u8Contents:
            if content.endswith("ts\n"):
                ts_Url = baseUrl + content.replace("\n", "").replace("..", "")
                ts_url_list.append(ts_Url)
                print(ts_Url)
    return ts_url_list
def download_ts_video(download_path, ts_url_list):
    download_path = r"C:\Users\Administrator\Desktop\AiShu\下载视频\TS视频"
    for i in range(len(ts_url_list)):
        ts_url = ts_url_list[i]
        try:
            response = requests.get(ts_url, stream=True, verify=False)
        except Exception as e:
            print("异常请求:%s" % e.args)
            return
        ts_path = download_path + "\{}.ts".format(i)
        with open(ts_path, "wb+") as file:
            for chunk in response.iter_content(chunk_size=1024):
                if chunk:
                    file.write(chunk)
    print("TS文件下载完毕!!")
def heBingTsVideo(download_path,hebing_path):
    all_ts = os.listdir(download_path)
    with open(hebing_path, 'wb+') as f:
        for i in range(len(all_ts)):
            ts_video_path = os.path.join(download_path, all_ts[i])
            f.write(open(ts_video_path, 'rb').read())
    print("合并完成!!")
if __name__ == '__main__':
    download_path = r"C:\Users\Administrator\Desktop\AiShu\下载视频\TS视频"
    hebing_path = r"C:\Users\Administrator\Desktop\AiShu\下载视频\合并TS视频\第一财经.mp4"
    ts_url_list = getTsUrl()
    download_ts_video(download_path, ts_url_list)
    heBingTsVideo(download_path,hebing_path)

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。如有错误或未考虑完全的地方,望不吝赐教。

Python 相关文章推荐
Python3 正在毁灭 Python的原因分析
Nov 28 Python
MySQL最常见的操作语句小结
May 07 Python
Python编程之字符串模板(Template)用法实例分析
Jul 22 Python
python生成密码字典的方法
Jul 06 Python
Python企业编码生成系统总体系统设计概述
Jul 26 Python
python django model联合主键的例子
Aug 06 Python
Python Web框架之Django框架文件上传功能详解
Aug 16 Python
Django中自定义模型管理器(Manager)及方法
Sep 23 Python
Python实现将蓝底照片转化为白底照片功能完整实例
Dec 13 Python
Pytorch 神经网络—自定义数据集上实现教程
Jan 07 Python
python多线程方法详解
Jan 18 Python
Python用tkinter实现自定义记事本的方法详解
Mar 31 Python
Python实现Telnet自动连接检测密码的示例
AI:如何训练机器学习的模型
python 用递归实现通用爬虫解析器
MATLAB 如何求取离散点的曲率最大值
用Python远程登陆服务器的步骤
Matlab求解数组中的最大值及它所在的具体位置
Apr 16 #Python
python 机器学习的标准化、归一化、正则化、离散化和白化
Apr 16 #Python
You might like
php的正则处理函数总结分析
2008/06/20 PHP
PHP中的strtr函数使用介绍(str_replace)
2011/10/20 PHP
php魔术方法与魔术变量、内置方法与内置变量的深入分析
2013/06/03 PHP
PHP magento后台无法登录问题解决方法
2016/11/24 PHP
PHP实现图片的等比缩放和Logo水印功能示例
2017/05/04 PHP
PHP中递归的实现实例详解
2017/11/14 PHP
Laravel如何使用Redis共享Session
2018/02/23 PHP
分享5个非常有用的Laravel Blade指令
2018/05/30 PHP
Ext中下拉列表ComboBox组件store数据格式用法介绍
2013/07/15 Javascript
javascript获得网页窗口实际大小的示例代码
2013/09/21 Javascript
js 操作符汇总
2014/11/08 Javascript
JS实现仿QQ面板的手风琴效果折叠菜单代码
2015/09/11 Javascript
javascript鼠标滑过显示二级菜单特效
2020/11/18 Javascript
JS公共小方法之判断对象是否为domElement的实例
2016/11/25 Javascript
微信小程序去哪里找 小程序到底如何使用(附小程序名单)
2017/01/09 Javascript
jQuery插件开发发送短信倒计时功能代码
2017/05/09 jQuery
js中let和var定义变量的区别
2018/02/08 Javascript
js装饰设计模式学习心得
2018/02/17 Javascript
vue组件创建的三种方式小结
2020/02/03 Javascript
介绍Python的Django框架中的QuerySets
2015/04/20 Python
Python3读取zip文件信息的方法
2015/05/22 Python
Django后台admin的使用详解
2019/07/08 Python
python 发送get请求接口详解
2020/11/17 Python
CSS3制作苹果风格键盘特效
2015/02/26 HTML / CSS
时尚设计师手表:The Watch Cabin
2018/10/06 全球购物
高中竞选班长演讲稿
2014/04/24 职场文书
汽车检测与维修专业求职信
2014/07/04 职场文书
债务纠纷委托书
2014/08/30 职场文书
领导班子对照检查材料
2014/09/22 职场文书
2014年公务员个人工作总结
2014/11/22 职场文书
护士长2015年终工作总结
2015/04/24 职场文书
2015年学校教科室工作总结
2015/07/20 职场文书
2016年大学校运会广播稿件
2015/12/21 职场文书
2019年销售人员的职业生涯规划书
2019/03/25 职场文书
PostgreSQL将数据加载到buffer cache中操作方法
2021/04/16 PostgreSQL
深入理解Pytorch微调torchvision模型
2021/11/11 Python