码迷,mamicode.com
首页 > 编程语言 > 详细

python解决m3u8直播视频的爬取

时间:2020-03-31 18:43:18      阅读:1475      评论:0      收藏:0      [点我收藏+]

标签:方案   tmm   requests   streaming   mode   播放   m3u   strong   eid   

一、背景

在爬虫方面包括图片,文字,视频,音频等的获取。受到速度的限制,视频的爬取较为麻烦,因为视频是进行切片处理的采取的方式是hls,这是苹果公司制定的一个方案。它会把内容切片,用.m3u8进行组织,在m3u8里面记录了断点的位置,将所有的片段下载下来在拼接就可以连接成整个视频。目前较大的视频都是采取这样的方式。同时m3u8的格式也可以被h5直接读取,这样从理论上和实际过程中解决了视频的传输问题。模型图如下。

技术图片

二、文件信息

2.1 .m3u8的头文件格式

用检索我们可以在source/media中看到一个.m3u8的文件,通过对这个文件进行访问,可以看到下面的结果。

这一部分包括了文件格式的定义,以及加密方式,和解密的密钥。

# EXTM3U:.m3u8文件的格式定义
# EXT-X-KEY: 密钥的信息
# METHOD: 加密的方法,这里采用的是AES-128的加密方式
# URI: 密钥的地址,需要获取访问得到密钥的信息
# IV: 偏移量,AES加密的方法,通过这个密钥就可以解密,获取正确的视频信息

结果:

技术图片

2.2 每个.ts的文件片段

每一个.m3u8的片段都包含了这个片段的密钥,加密方法,用于解析视频内容。

# EXINF:片段切割的大小,大概是10s左右
# v.f...:下载的地址,每一个.ts片段都保留一个地址,可能相同可能不同
# EXT-X-KEY:加密的方式和密钥,每一个视频都有一个密钥,可能相同,可能不同
# METHOD:加密方式,AES-128的加密方式

结果

技术图片

三、解密

3.1 PyCryptodome安装

在有密钥的情况下我们需要进行解密,不然下载的文件就是无法播放的。解密的方法参考加密的手法。这里的密钥是AES,因此使用AES的解密方法去解密。

使用以下的指令安装

# PyCryptodome的安装,由于版本的问题,在使用AES模块的时候,安装PyCryptodome
pip install PyCryptodome 

结果

技术图片

3.2 构建解码器与解码

首先获取到VI,然后获取到key,构建一个解码器

from Crypto.Cipher import AES
url_key = "key.key"  # 省略写法
content_key = requests.get(url_key).content  # 获取key值
vi = "0x00000000000000000000000000000000"  # vi值一样
vt = vi.replace("0x", "")[:16].encode()  # 偏移码
ci = AES.new(content_key, AES.MODE_CBC, vt)  # 构建解码器
content = requests.get(url_content_ts).content  # 获取加密视频内容
content_ts = ci.decrypt(content)  # 解码ts中的二进制格式

3.3 对获取的content解密

完整的代码

import requests
import os
import re
from Crypto.Cipher import AES

url = "https://1252524126.vod2.myqcloud.com/9764a7a5vodtransgzp1252524126/0176cbbd5285890799673243539/drm/v.f230.m3u8?"
data = {
    "time": ""
}

download_url = "https://1252524126.vod2.myqcloud.com/9764a7a5vodtransgzp1252524126/0176cbbd5285890799673243539/drm/"

"""
列举一个单位格大小:
#EXTINF:2.000000,
v.f230.ts?start=0&end=158495&type=mpegts
#EXT-X-KEY:METHOD=AES-128,URI="https://app.xiaoe-tech.com/get_video_key.php?edk=CiCTzP%2B6jBR9H5awSTdnrwcCQzZlldD%2BTYaAr%2FlaHOwsPBCO08TAChiaoOvUBCokYjRhNjFiNTgtMmVhNy00OWYxLTgwZGMtZTE0NTIyODc5YWIy&fileId=5285890799673243539&keySource=VodBuildInKMS",IV=0x00000000000000000000000000000000
"""


def download():
    url_key = "https://app.xiaoe-tech.com/get_video_key.php?edk=CiCTzP%2B6jBR9H5awSTdnrwcCQzZlldD%2BTYaAr%2FlaHOwsPBCO08TAChiaoOvUBCokYjRhNjFiNTgtMmVhNy00OWYxLTgwZGMtZTE0NTIyODc5YWIy&fileId=5285890799673243539&keySource=VodBuildInKMS"
    content_key = requests.get(url_key).content  # 获取key值
    download_path = os.getcwd() + r"\download"
    if not os.path.exists(download_path):
        os.mkdir(download_path)
    m3u8_content = requests.get(url, params=data).text
    print(m3u8_content)
    exit()
    result = re.compile(r"v\.f230\.ts\?start=[0-9]+&end=[0-9]+&type=mpegts", re.S).findall(m3u8_content)  # 匹配.ts的文件地址
    vi = "0x00000000000000000000000000000000"
    vt = vi.replace("0x", "")[:16].encode()  # 偏移码
    ci = AES.new(content_key, AES.MODE_CBC, vt)  # 构建解码器
    for i in enumerate(result):
        print(f"正在下载:{i[0]}")
        content_ts = requests.get(download_url + str(i[1])).content
        with open(download_path + "\\" + str(i[0] + 1) + ".mp4", ab) as f:
            f.write(ci.decrypt(content_ts))  # 将内容解码
            f.flush()


if __name__ == __main__:
    download()

四、总结

上述讲述了.m3u8文件的爬取和解析方法,例如直播的爬取,或者是是视频的爬取都涉及到上述的内容。此方法需要自己分析一下内容,没有写成接口的形式,同时这个解码是AES-128的方式,在遇到其他加密方法自行查阅相关解码方式。

五、参考:

下面的blog是一下参考

https://blog.csdn.net/weixin_40346015/article/details/102595690

https://www.jianshu.com/p/98756e274fa0

https://www.52pojie.cn/thread-971265-1-1.html

详细的介绍:https://pakchoi.me/2016/06/21/hls-fe/

包安装问题https://www.cnblogs.com/new-june/p/9401002.html

python解决m3u8直播视频的爬取

标签:方案   tmm   requests   streaming   mode   播放   m3u   strong   eid   

原文地址:https://www.cnblogs.com/future-dream/p/12582918.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!