python递归下载m3u8视频文件

check()与check_de_ts()

check():

检查ts是否全部下载完成,如果没有全部下载,将对未下载的ts进行第二次或更多次的下载.

check_de_ts():

检查ts是否全部解密,如果有ts没有解密,将对未解密的ts进行重新下载,再解密.

lst

注意:lst在整个代码执行过程中始终没有发生变化

1.导入模块

import os
import requests
from concurrent.futures import ThreadPoolExecutor
from Crypto.Cipher import AES

2.执行过程

def main():
    if not os.path.isdir('video'):
        os.mkdir('video')
    lst, lst_n = get_lst()
    thread_download(lst, lst_n)
    thread_decode(lst, lst_n)
    merge(len(lst))
    delete_ts(len(lst))

3.获取ts网址列表

# 返回两个列表,task是url列表,num是task列表的索引列表
def get_lst():
    task = []
    num = []
    with open('1.m3u8', 'r', encoding='utf-8') as f:
        for line in f:
            line = line.strip()
            if line.startswith('#'):
                continue
            line = line
            task.append(line)
    for i in range(len(task)):
        num.append(i)
    return task, num

4.多线程下载

# 1 创建多线程任务
def thread_download(lst, lst_n):
    with ThreadPoolExecutor(50) as t:
        for i in lst_n:
            t.submit(download, name=i, url=lst[i])
    check(lst, lst_n)
# 2 ts下载函数
def download(url, name):
    resp = requests.get(url, timeout=10) # 请求超时10秒
    with open(f'video/{name}', 'wb') as f1:
        f1.write(resp.content)
        print(f'{name}下载完成')
# 3 递归:检查ts是否全部下载完成,把没下载的ts索引装在lst_ns里面,再重新下载,直到全部下载完成为止.
# 注意:lst始终没有发生变化
def check(lst, lst_n):
    lst_ns = []
    for i in lst_n:
        if not os.path.isfile(f'video/{i}'):
            lst_ns.append(i)
    if lst_ns:
   		print(lst_ns)
        print('开始递归==================================================')
        thread_download(lst, lst_ns)
    else:
        print('全部下载完成')

5.解密ts

如果ts被加密了,就再解密,key网址一般在m3u8文件里面

# 1.创建多线程任务
def thread_decode(lst, lst_n):
    with ThreadPoolExecutor(50) as t:
        for i in lst_n:
            t.submit(decode_ts, name=i)
    check_de_ts(lst, lst_n)
# 2.ts解密函数
def decode_ts(name):
    resp = requests.get('https://*****/key.key')
    key = resp.content
    iv = b'0000000000000000'
    aes = AES.new(key, AES.MODE_CBC, iv)
    with open(f'video/{name}', 'rb') as f:
        de_f = aes.decrypt(f.read())
        with open(f'video/{name}_1', 'wb') as f1:
            f1.write(de_f)
    print(f'{name}解码完成')
# 3.检查ts是否全部解密,如果有没有解密的,再重新下载ts,再解密,因为解密不成功,有可能是下载的文件有问题.
# 注意:lst始终没有发生改变
def check_de_ts(lst, lst_n):
    lst_ns = []
    for i in lst_n:
        if not os.path.isfile(f'video/{i}_1'):
            lst_ns.append(i)
    if lst_ns:
        print(lst_ns)
        print('开始递归==================================================')
        thread_download(lst, lst_ns)
        thread_decode(lst, lst_ns)
    else:
        print('全部ts解密完成')

6.合并

# 1.合并解密好的ts文件
def merge(num):
    with open('video/1.mp4', 'wb') as f:
        for i in range(num):
            with open(f'video/{i}_1', 'rb') as f1:
                f.write(f1.read())
            # os.remove(f'video/{i}')
            # os.remove(f'video/{i}_1')
    print('合并完成')
# 2.删除所有的ts文件
def delete_ts(num):
    for i in range(num):
        os.remove(f'video/{i}')
        os.remove(f'video/{i}_1')

完整代码

import os
import requests
from concurrent.futures import ThreadPoolExecutor
from Crypto.Cipher import AES


def get_lst():
    task = []
    num = []
    with open('1.m3u8', 'r', encoding='utf-8') as f:
        for line in f:
            line = line.strip()
            if line.startswith('#'):
                continue
            line = line
            task.append(line)
    for i in range(len(task)):
        num.append(i)
    return task, num


def download(url, name):
    resp = requests.get(url, timeout=10)
    with open(f'video/{name}', 'wb') as f1:
        f1.write(resp.content)
        print(f'{name}下载完成')


def thread_download(lst, lst_n):
    with ThreadPoolExecutor(50) as t:
        for i in lst_n:
            t.submit(download, name=i, url=lst[i])
    check(lst, lst_n)


def check(lst, lst_n):
    lst_ns = []
    for i in lst_n:
        if not os.path.isfile(f'video/{i}'):
            lst_ns.append(i)
    if lst_ns:
        print(lst_ns)
        print('开始递归==================================================')
        thread_download(lst, lst_ns)
    else:
        print('全部下载完成')


def merge(num):
    with open('video/1.mp4', 'wb') as f:
        for i in range(num):
            with open(f'video/{i}_1', 'rb') as f1:
                f.write(f1.read())
            # os.remove(f'video/{i}')
            # os.remove(f'video/{i}_1')
    print('合并完成')


def decode_ts(name):
    resp = requests.get('https://******/key.key')
    key = resp.content
    iv = b'0000000000000000'
    aes = AES.new(key, AES.MODE_CBC, iv)
    with open(f'video/{name}', 'rb') as f:
        de_f = aes.decrypt(f.read())
        with open(f'video/{name}_1', 'wb') as f1:
            f1.write(de_f)
    print(f'{name}解码完成')


def thread_decode(lst, lst_n):
    with ThreadPoolExecutor(50) as t:
        for i in lst_n:
            t.submit(decode_ts, name=i)
    check_de_ts(lst, lst_n)


def check_de_ts(lst, lst_n):
    lst_ns = []
    for i in lst_n:
        if not os.path.isfile(f'video/{i}_1'):
            lst_ns.append(i)
    if lst_ns:
        print(lst_ns)
        print('开始递归==================================================')
        thread_download(lst, lst_ns)
        thread_decode(lst, lst_ns)
    else:
        print('全部ts解密完成')


def delete_ts(num):
    for i in range(num):
        os.remove(f'video/{i}')
        os.remove(f'video/{i}_1')


def main():
    if not os.path.isdir('video'):
        os.mkdir('video')
    lst, lst_n = get_lst()
    thread_download(lst, lst_n)
    thread_decode(lst, lst_n)
    merge(len(lst))
    delete_ts(len(lst))


if __name__ == '__main__':
    main()

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值