Python下载加密m3u8视频

一些网站会提供m3u8视频地址,以供下载观看。或者一些网站经过分析后发现是使用m3u8格式进行播放的,这时使用m3u8的地址链接就可以下载到相应的视频。

一、关于m3u8:(https://blog.csdn.net/baidu_34418350/article/details/64922512)

m3u8是苹果公司推出一种视频播放标准,是m3u的一种,不过 编码方式是utf-8,是一种文件检索格式,将视频切割成一小段一小段的ts格式的视频文件,然后存在服务器中(现在为了减少I/o访问次数,一般存在服务器的内存中),通过m3u8解析出来路径,然后去请求。

http://t.elecfans.com/live/749.html?room=1

直接F12查看视频播放列表链接

Python下载加密m3u8视频_第1张图片

## 一、实际地址获取

#EXTM3U

#EXT-X-VERSION:3

#EXT-X-TARGETDURATION:22

#EXT-X-MEDIA-SEQUENCE:0

#EXT-X-KEY:METHOD=AES-128,URI="video.key"

#EXTINF:16.666667,

index0.ts

#EXTINF:16.666667,

index1.ts

#EXTINF:16.666667,

index2.ts

#EXTINF:16.666667,

index3.ts

#EXTINF:8.333333,

index4.ts

看到ts结尾的文件,这才是视频真正的存放路径:

下载到本地,视频软件无法播放:

## 二、视频下载

可以用python脚本自动下载这些ts文件,但实际上有些网站的ts文件是用AES-128加密过的,所以需要解密才能播放。

加密过的视频在第二层m3u8中会有一个key文件链接:

#EXTM3U

#EXT-X-VERSION:3

#EXT-X-TARGETDURATION:22

#EXT-X-MEDIA-SEQUENCE:0

#EXT-X-KEY:METHOD=AES-128,URI="video.key"

#key密钥文件

需要去读取这个key文件,才能拿到解密密钥。

然后开始【Python抄写】

# -*- coding:utf-8 -*-  
import os
import sys
import requests
import datetime
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
 
#reload(sys)
#sys.setdefaultencoding('utf-8')
 
def download(url):
    download_path = os.getcwd() + "\download"
    if not os.path.exists(download_path):
        os.mkdir(download_path)
        
    #新建日期文件夹
    download_path = os.path.join(download_path, datetime.datetime.now().strftime('%Y%m%d_%H%M%S'))
    #print download_path
    os.mkdir(download_path)
        
    all_content = requests.get(url).text  # 获取第一层M3U8文件内容
    if "#EXTM3U" not in all_content:
        raise BaseException("非M3U8的链接")
 
    if "EXT-X-STREAM-INF" in all_content:  # 第一层
        file_line = all_content.split("\n")
        for line in file_line:
            if '.m3u8' in line:
                url = url.rsplit("/", 1)[0] + "/" + line # 拼出第二层m3u8的URL
                all_content = requests.get(url).text
 
    file_line = all_content.split("\n")
 
    unknow = True
    key = ""
    for index, line in enumerate(file_line): # 第二层
        if "#EXT-X-KEY" in line:  # 找解密Key
            method_pos = line.find("METHOD")
            comma_pos = line.find(",")
            method = line[method_pos:comma_pos].split('=')[1]
            print ("Decode Method:", method)
            
            uri_pos = line.find("URI")
            quotation_mark_pos = line.rfind('"')
            key_path = line[uri_pos:quotation_mark_pos].split('"')[1]
            
            key_url = url.rsplit("/", 1)[0] + "/" + key_path # 拼出key解密密钥URL
            res = requests.get(key_url)
            key = res.content
            print ("key:" , key)
            
        if "EXTINF" in line: # 找ts地址并下载
            unknow = False
            pd_url = url.rsplit("/", 1)[0] + "/" + file_line[index + 1] # 拼出ts片段的URL
            #print pd_url
            
            res = requests.get(pd_url)
            c_fule_name = file_line[index + 1].rsplit("/", 1)[-1]
            
            if len(key): # AES 解密
                cryptor = AES.new(key, AES.MODE_CBC, key)  
                with open(os.path.join(download_path, c_fule_name + ".mp4"), 'ab') as f:
                    f.write(cryptor.decrypt(res.content))
            else:
                with open(os.path.join(download_path, c_fule_name), 'ab') as f:
                    f.write(res.content)
                    f.flush()
    if unknow:
        raise BaseException("未找到对应的下载链接")
    else:
        print ("下载完成")
    merge_file(download_path)
 
def merge_file(path):
    os.chdir(path)
    cmd = "copy /b * new.tmp"
    os.system(cmd)
    os.system('del /Q *.ts')
    os.system('del /Q *.mp4')
    os.rename("new.tmp", "new.mp4")
    
if __name__ == '__main__': 
    url = "http://media.elecfans.com/topic/gongkaike/2019/03/d220246a27f399509fc2022731b8ae3b/30/hls/index.m3u8" 
    download(url)

代码照搬--------------------- 
作者:a33445621 
来源:CSDN 
原文:https://blog.csdn.net/a33445621/article/details/80377424 
 

你可能感兴趣的:(Python下载加密m3u8视频)