源代码展示

import threading #使用多线程
import requests  #使用requests请求下载
import time
import os
import re
from Crypto.Cipher import AES  #需要安装pycryptodome模块,用于key解密 D:\PythonLocat\Lib\site-packages\crypto\cipher\路径下有个AES.py文件,Crypto.Cipher区分大小写,否则报错
import ctypes #禁用cmd快速编辑模式Headers={
"User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36"
}def disable_cmd():#禁用cmd快速编辑模式kernel32 =  ctypes.windll.kernel32  kernel32.SetConsoleMode(kernel32.GetStdHandle(-10),128)
def del_log():#删除上一个视频的信息  print("布置环境……")    os.system("del *.ts") #删除tsif os.path.exists('./filelist.txt'):          os.system("del filelist.txt")print("正在删除 filelist.txt文件")if os.path.exists('./contras.log'):          os.system("del contras.log")print("正在删除 contras.log文件")if os.path.exists('./index.m3u8'):          os.system("del index.m3u8")print("正在删除 index.m3u8文件")if os.path.exists('./key.m3u8'):          os.system("del key.m3u8")print("正在删除 key.m3u8文件")if os.path.exists('./unplayerror.log'):          os.system("del unplayerror.log")print("正在删除 unplayerror.log文件")if os.path.exists('./exsislist.log'):          os.system("del exsislist.log")print("正在删除 exsislist.log文件")os.system("cls")def down_play_list(play_list_url,name):  #下载try:play_url =requests.get(url=play_list_url,headers=Headers,timeout=None).contentwith open (name,mode='wb') as ts:if not key:ts.write(play_url)else:cryptor = AES.new(key,AES.MODE_CBC,key) #解密ts.write(cryptor.decrypt(play_url))     #解密后写入except ValueError:print(play_list_url + "第一次下载失败,尝试重新下载")play_url=play_list_urlplay_url =requests.get(url=play_list_url,headers=Headers,timeout=None).contentwith open (name,mode='wb') as ts:if not key:ts.write(play_url)else:cryptor = AES.new(key,AES.MODE_CBC,key)ts.write(cryptor.decrypt(play_url))
def self_check():  #检查视频是否完全下载,如果还未下载完全,则重新下载缺失的ts文件。print("正在校验ts文件是否下载完全……")times=0while times < 3:#设置自检次数为三次if os.path.exists('./exsislist.log'):print("正在删除exsislist.log文件")os.system("del exsislist.log")time.sleep(20)file_list = os.listdir()#获取路径文件列表num = 0list_ts = []for ts_list in file_list:split_list = os.path.splitext(ts_list)#分割文件if split_list[1] == ".ts":if os.path.getsize(r'./' + ts_list) <1024*10:#获取每一个ts文件的大小,如果小于10k,则删除os.system("del " + ts_list)else:with open ('exsislist.log','a') as f: #将已存在的ts序号写入exsislist.log文件。f.write(split_list[0] + '\n')f.close()with open ('contras.log','r') as r:#打开contras.log文件,与exsislist.log文件进行对比,将缺失的的ts打印出来,并进行下载list_contrat = r.readlines()for i in list_contrat:i =i.split(' ')number = i[0]url = i[1]with open ('exsislist.log','r') as r_exsist:r_exsist_list = r_exsist.readlines()if number not in str(r_exsist_list):#这里需要将r_exsist_list转换成字符(str)形式,否则无法正确打印出time.sleep(2)threading.Thread(target=down_play_list,args=(url,str(number)+'.ts',)).start()print("正在下载缺失的ts文件:" + str(number)+'.ts')print(number + " " + i[1].replace('\n',''))#使用replace去除回车符f.close()times +=1def output():  #输出print("正在合成mp4,请稍等……")if os.path.exists('./filelist.txt'):print("正在删除filelist.txt文件")os.system("del filelist.txt")time.sleep(5)if os.path.exists('./unplayerror.log'):print("正在删除unplayerror.log文件")os.system("del unplayerror.log")time.sleep(5)file_list = os.listdir()num = 0list_ts = []for ts_list in file_list:split_list = os.path.splitext(ts_list)if split_list[1] == ".ts":if os.path.getsize(r'./' + ts_list) < 1024*10:#获取每一个ts文件的大小,如果小于10k,则删除with open('unplayerror.log','a') as f:f.write(ts_list + '\n')f.close()os.system("del " + ts_list)#删除ts小于10k的ts,否则合成视频时报错else:file_ts =split_list[0]list_ts.append(file_ts)time.sleep(60) #等待60秒list_ts.sort() #对list_ts字典进行升序排序for index in list_ts:with open('filelist.txt',mode = 'a') as f:f.write('file ' + "'" +str(index) + '.ts' + "'"+'\n')f.close()os.system("ffmpeg -f concat -safe 0 -i filelist.txt -c copy " + outname) #使用ffmpeg工具合成为mp4视频格式time.sleep(5)print("视频合成完成")
def main(): #主函数with open ('index.m3u8',mode='r') as f:  #从index.m3u8文件中获取ts列表lists = f.readlines()nu = 0ts_list = []for i in lists[0:]:if  '#' not in i:   #如果存在'#',则去掉i = i.replace('\n','')ts_list.append(i)number =len(str(len(ts_list))) #str(len(ts_list)) ts_list长度转换成字符串形式print("共有" + str(len(ts_list)) + "个ts文件") #打印出ts的个数index=0for i in ts_list:change = '%0' + str(number) +'d'num = change % index #进行数据的转换,如果ts有99个,则命名为01、02、……,如果是999个,则为001.ts、002、……,方便合成视频if 'http' not in i:#判断ts文件是否完整(含有http头)if i[0] == '/': #如果ts是从/开始的如 /202203/dfdf/dkdkg/dkdddk.ts,则使用这条路径下载threading.Thread(target=down_play_list,args=(base_url_1 + i,str(num)+'.ts',)).start()print(num + ' ' + base_url_1 + i)with open ('contras.log',mode='a') as f:     #生成对照表,将每个序号对应的链接写入f.write(num + ' ' + base_url_1 + i + '\n') f.close()else:           #如果ts是从http开始的如 http:/vs.cskd.cn/202203/dfdf/dkdkg/dkdddk.ts,则使用这条路径下载threading.Thread(target=down_play_list,args=(base_url_2 + i,str(num)+'.ts',)).start()print(num + ' ' + base_url_2 + i)with open ('contras.log',mode='a') as f:f.write(num + ' ' + base_url_2 + i + '\n') f.close()else:threading.Thread(target=down_play_list,args=(i,str(num)+'.ts',)).start()print(num + ' ' + i)with open ('contras.log',mode='a') as f:     #生成对照表,将每个序号对应的链接写入f.write(num + ' ' + i + '\n') f.close()index+=1time.sleep(1)
def choose_menu():  #选择菜单,下载完成以后可以选择菜单while True:print("输入0-->退出")print("输入1-->手动合成视频(通常在文件较大,自动合成失败的形况下)")print("输入2-->手动下载缺失的视频,并合成mp4")print("输入3-->删除上一个视频相关文件(ts片段、log信息、filelist、m3u8))")choose = int(input("请输入:"))if choose ==0:breakif choose ==1:os.system("del filelist.txt")time.sleep(3)output()if choose ==2:self_check()output()if choose ==3:del_log()
if __name__=='__main__':while True:del_log()#删除上一条视频的相关文件while True:try:m3u8_url = str(input("请输入m3u8链接:"))outname = input("请输入视频名称:") + '.mp4'start_time = time.time()get_url = m3u8_url.split('/')base_url_1 = get_url[0]+'//' + get_url[2]     #得到http://***  get_url[0]=http: get_url[2]=***  第一种情况base_url_2 = m3u8_url.replace(get_url[-1],'') #替换掉m3u8_url链接最后部分,主要针对ts前部分没有http的情况 第二种情况print("正在下载index.m3u8文件……")             #下载index.m3u8m3u8_index = requests.get(m3u8_url).contentbreakexcept IndexError:print('m3u8网址不正确')disable_cmd()#禁用cmd快速编辑模式with open(f"index.m3u8", mode='wb') as f:f.write(m3u8_index)response = requests.get(m3u8_url).text#打印index.m3u8文本形式if "#EXT-X-KEY" not in response: #判断是否存在key加密print("视频未加密")key=Falsemain() #进入main()方法else:print("视频已加密,查找密钥")key_search =re.compile(get_url[0] + r"//.*?\.key")#有的网址开头是https,有的是http,所以用get_url[0]来确定#key_search =re.compile(r"\/.*?\.key")#找key,有的key不是以https形式开头的,可能是一个/开头key_url = key_search.findall(response)[0]   #获取到的是字典的形式,所以加上[0]取出字典里面的值print("获得key链接",key_url)#key = requests.get(base_url_1+key_url).contentkey = requests.get(key_url).contentprint("获得密钥:",key)with open('key.m3u8','wb') as key_f:key_f.write(key)main()self_check() #自检output()    #输出MP4stop_time = time.time()print("总共用时(秒):",stop_time-start_time)choose_menu() #完成后进入操作菜单

使用Python+多线程下载M3U8格式视频(小白)相关推荐

  1. python多线程下载视频_python 实现多线程下载m3u8格式视频并使用fmmpeg合并

    电影之类的长视频好像都用m3u8格式了,这就导致了多线程下载视频的意义不是很大,都是短视频,线不线程就没什么意义了嘛. 我们知道,m3u8的链接会下载一个文档,相当长,半小时的视频,应该有接近千行ts ...

  2. python多线程下载m3u8文件,python 实现多线程下载m3u8格式视频并使用fmmpeg合并

    如何把m3u8格式转换成mp4格式? 可以按照如下方式进行操作: 抑郁的人在水底,正常人在水面,小编沉浮在中间,上不去也下不来. 手机上面找到m3u8格式文件的存储位置,在打开方式里边选择" ...

  3. python 实现多线程下载m3u8格式视频,使用FFmpeg合并(升级修订自s_kangkang_A)

    基本代码源自: https://blog.csdn.net/s_kangkang_A/article/details/103071822. 感谢 s_kangkang_A https://blog.c ...

  4. python下载大文件mp4_Python 下载 m3u8 格式视频

    Python requests 下载 m3u8 格式 视频 最近爬取一个视频网站,遇到 m3u8 格式的视频需要下载. 抓包分析,视频文件是多个 ts 文件,什么是 ts文件,请去百度吧: 附图:抓包 ...

  5. python下载m3u8视频_使用python 下载m3u8格式视频,并使用ffmpeg 合成视频

    使用python 下载m3u8格式视频,并合成 # -*- coding: utf-8 -*- # Created on 2018/07/26 import os import requests &q ...

  6. python爬取m3u8格式视频

    python爬取m3u8格式视频 m3u8原理 脚本环境 爬取步骤 步骤的具体实现 python细节处理说明 参考代码 m3u8原理 当我们在网页播放视频时,网页向服务器发起一个以.m3u8结尾的连接 ...

  7. 【python】多线程下载m3u8分段视频

    1.说明 m3u8是一种传输数据的方式,比如说一集20分钟的完整视频被分割成一千多段一两秒的小视频,客户端播放的时候是感觉是连续,但如果你要下载这集视频,那就要把一千多个小视频全都下载然后自己拼接成一 ...

  8. 如何优雅的批量下载m3u8 格式视频

    我们去很多网站上 去下载视频,解析出的地址 是m3u8格式视频, 使用 普通的下载方式下载就是一个m3u8文件.里面装的是一段一段的视频.一方面,不做特殊处理播放器可能播放不了,另一方面该格式可能是加 ...

  9. Python爬取m3u8格式视频并解密ts文件合并转为mp4格式

    一. m3u8是什么格式 m3u8是苹果公司推出的视频播放标准,是m3u的一种,只是编码格式采用的是UTF-8. m3u8准确来说是一种索引文件,使用m3u8文件实际上是通过它来解析对应的放在服务器上 ...

  10. 怎么下载m3u8格式视频?Python爬取A站m3u8格式视频案例讲解

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. 本篇文章流程 一. 数据来源分析 确定需求 (确定要爬的内容是什么?).只有知道数据要的是什 ...

最新文章

  1. Java开发中的23种设计模式详解(转)
  2. 操作系统---Systemd
  3. 【附段错误原因,最后两个测试点】1052 Linked List Sorting (25 分)【链表类题目总结】
  4. emqx 使用端口_数据传输、存储、展现,EMQ X + TDengine 搭建 MQTT 物联网数据可视化平台...
  5. 异步请求中jetty处理ServletRequestListener的坑
  6. matlab采样频谱,Matlab对采样数据进行频谱分析
  7. 非插件实现回复可见效果
  8. php 如何设置后台,phpcms怎么重新设置后台网址
  9. redisTemplate批量写入数据
  10. 使用slf4j和log4j记录日志
  11. Tomcat的设置3——设置虚拟主机
  12. 2020CID|阿里云韩伟东:云原生底层系统思考
  13. brew 安装pip_pip brew wget 安装
  14. Unreal Engine UE4虚幻引擎,生成Cubemap(HDR高动态范围贴图)
  15. xposed框架安装使用教程(第一篇)
  16. python 删除word 某一章节_聊聊python 办公自动化之 Word(中)
  17. Xcode failed to get reply to handshake packet
  18. 堆积木——GBQ4.0设置“统一设置安装费用”中的“高层建筑增加费”
  19. JavaScript中文与阿拉伯数字互相转换
  20. python猜数字游戏编程入门_Python实现猜数字游戏

热门文章

  1. 《Sass 基础教程》共40节宁皓网课程
  2. LVS+Keepalived高可用
  3. gtx1050ti最稳定的驱动_英伟达gtx1050ti现在用什么版本驱动比较好?
  4. “匠心之韵,数据之美”之数字营销专访【友盟+】一周年:不忘初心,从整合到融合,从合并到合力...
  5. 67tool.com 即用即走的在线工具箱
  6. 攻略:大陆人成立香港公司以后如何运营?
  7. 大陆居民可以在香港汇丰银行开私人账户
  8. C语言实现创建游戏角色(包含文件写入)
  9. simplest tensor core gemm sample
  10. Elasticsearch索引yellow修复