参考了这位仁兄的blog, 有加密的m3u8视频下载以及解码方法_baidu_41902768的博客-CSDN博客_m3u8加密视频怎么解密

对其进行了进一步包装,支持直接输入网页页面的url直接下载视频,仅匹配到页面中第一个m3u8

分享给大家

此python脚本基于linux环境编写,如需在windows上使用,需开启WSL,然后在windows软件商店安装ubuntu后使用

废话不多说,直接上代码

#!/usr/bin/pythonimport requests
import os
import re
from Crypto.Cipher import AES
import time
import tempfile
import sys
import optparseclass DownloadError(RuntimeError):def __init__(self, arg):self.args = argclass UrlError(RuntimeError):def __init__(self, arg):self.args = argdef progressbar(tot, pre, content = None):'''max_bar means the total number of tasks.i means the number of finished tasks.'''con_str = ""if  content != None:con_str = " " + contentmax_bar = 30finish = int(pre*max_bar/tot)unfinish = (max_bar - finish)bar = "[{}{}]".format(finish * "=", unfinish * " ")counts = " (%d/%d) " % (pre, tot)percent = str(int(pre * 100/tot)) + "%"if pre < tot:sys.stdout.write(bar + counts + percent + con_str + "\r")else:sys.stdout.write(bar + counts + percent + con_str + "\n")sys.stdout.flush()def del_path(path):if os.path.isdir(path):del_list = os.listdir(path)for f in del_list:file_path = os.path.join(path, f)del_path(file_path)os.rmdir(path)else:os.remove(path)def cal_time(fun):def inner_wrapper(*args):start = time.time()fun(*args)end = time.time()print('Time spent is ' + str(round(end - start,1)))return inner_wrapperdef request_net_content(url):headers = {'user-agent': 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50'}request_res = Noneretry_times = 0while retry_times < 10:try:request_res = requests.get(url, timeout=(5, 15), headers = headers)breakexcept requests.exceptions.RequestException:retry_times += 1print("\nrequest timeout for: '%s' and retry again (%d/10)" % (url, retry_times))if retry_times >= 10:raise DownloadError("download retry 10 times, and always no response!")return request_resdef get_real_url(last_url, url):matchUrl = re.match(r'(http[s]?://.*)', url)if matchUrl is not None:real_url = matchUrl.group(1)else:if url[0] == '/':base_url_match = re.match(r'(http[s]?://[^/]*)/.*', last_url)if base_url_match is None:raise UrlError("last_url '%s' is not valid !!!" % (last_url,))base_url = base_url_match.group(1)real_url = base_url + urlelse:path_end_name = os.path.basename(last_url)parent_url = last_url[:-len(path_end_name)]real_url = parent_url + urlreturn real_urldef write_split_to_out_fd(split_content, out_fd, cryptor):if len(split_content) > 0:if cryptor is not None:split_content = cryptor.decrypt(split_content)out_fd.write(split_content)else:raise ValueError("no value")def download_split(index, count, name, path, out_fd, url, cryptor):if os.path.exists(path):split_fd = Noneproc_ok = Truetry:progressbar(count, index, "proc '" + name + "'")split_fd = open(path, 'rb')split_content = split_fd.read()write_split_to_out_fd(split_content, out_fd, cryptor)except ValueError:proc_ok = Falseprint("\n'%s' zero content, redownload from '%s'" % (name, url,))if split_fd is not None:split_fd.close()if proc_ok:returndownload_count = 0while True:download_count += 1if download_count >= 6:print("\ndownload '%s' from '%s' always failed, ignore" % (name, url,))breaktry:progressbar(count, index, "download '" + name + "'")split_content = request_net_content(url).contentwith open(path, 'wb+') as split_fd:split_fd.write(split_content)write_split_to_out_fd(split_content, out_fd, cryptor)breakexcept ValueError:print("\n'%s' zero content, %dth redownload" % (name, download_count,))except DownloadError:print("\n'%s' download error, %dth redownload" % (name, download_count,))def download_m3u8(m3u8_url, temp_dir, out_fd):m3u8_res = request_net_content(m3u8_url)m3u8_text = m3u8_res.textprint("download m3u8: '%s'" % (m3u8_url,))lines = m3u8_text.splitlines()if lines[0] != "#EXTM3U" :print("not a valid m3u8 file, first line is '%s'\n" % (lines[0],))returnm3u8_split_cryptor = Noneitem_count = 0for line in lines:matchInfo = re.match(r'#EXT.*', line)info_key = Noneif matchInfo is None:item_count += 1else:matchInfo = re.match(r'#(EXT[^:]*):(.*)', line)if matchInfo is not None:info_key = matchInfo.group(1)info_val = matchInfo.group(2)#print("info_key is '%s'" % (info_key,))#print("info_val is '%s'" % (info_val,))if info_key == "EXT-X-KEY":key_url_search = re.search(r'URI="(.*)"', info_val)if key_url_search is None:print("error! can not get url for key")exit(1)key_url = get_real_url(m3u8_url, key_url_search.group(1))#print("key_url is '%s'" % (key_url,))key_url_res = request_net_content(key_url).textprint('key text is ' + key_url_res)m3u8_split_cryptor = AES.new(key_url_res, AES.MODE_CBC, b'0000000000000000')item_index = 0for line in lines:matchInfo = re.match(r'#EXT.*', line)itemUrl = Noneinfo_key = Noneif matchInfo is None:itemUrl = get_real_url(m3u8_url, line)if itemUrl is not None:# proc url, m3u8 or video splitdl_url_match = re.match(r'(http[s]?://[^\?]*)[\?]?.*', itemUrl)url_no_para = itemUrlif dl_url_match is not None:url_no_para = dl_url_match.group(1)if url_no_para.endswith("m3u8"):print("redirect to: '%s'" % (itemUrl,))download_m3u8(itemUrl, temp_dir, out_fd)else:item_index += 1split_name = os.path.basename(url_no_para)split_path = os.path.join(temp_dir, split_name)# download ts filedownload_split(item_index, item_count, split_name, split_path, out_fd,itemUrl, m3u8_split_cryptor)@cal_time
def video_downlowner(options):url = options.urlout_file = options.out_fileif options.temp is None:temp_dir = tempfile.mkdtemp(suffix='', prefix='m3u8_', dir='/tmp')print("temp file save to dir: " + temp_dir)else:temp_dir=options.tempout_name = os.path.basename(out_file)m3u8_url = Noneif options.m3u8 is not None:m3u8_url = urlelse:result = request_net_content(url)html_txt = re.sub("\\\/", "/", result.text)searchObj = re.search(r'"url":"(http[s]?://.*?\.m3u8)"', html_txt)if searchObj is not None:m3u8_url = searchObj.group(1)else:print("no m3u8 in given url")if m3u8_url is not None:out_fd = open(out_file, "wb+")download_m3u8(m3u8_url, temp_dir, out_fd)out_fd.close()if options.temp is None:del_path(temp_dir)def main():usage =  "usage: %prog <-u url> <-o out_file> [-t/--temp]"usage += "       %prog <-m m3u8> <-o out_file> [-t/--temp]"parse = optparse.OptionParser(usage)parse.add_option('-u', '--url', dest='url', action='store', \type='str', help='the url of webpage play this video')parse.add_option('-o', '--output-file', dest='out_file', action='store', \type='str', help='name of output video file')parse.add_option('-t', '--temp', dest='temp', action='store', \type='str', help='give the temp dir which save split video')parse.add_option('-m', '--m3u8', dest='m3u8', action='store_true', \help='if <url> is m3u8, add this option')options,args=parse.parse_args()if options.url is None and options.m3u8 is None:print("please give url or m3u8 to download\n")exit(1)if options.out_file is None:print("please give out file\n")exit(1)video_downlowner(options)if __name__ == '__main__':main()

m3u8视频下载工具相关推荐

  1. m3u8 视频提取工具(下载web中的ts文件)

    m3u8 视频提取工具(下载web中的ts文件) 开发背景 m3u8视频格式简介(借用他人描述) m3u8视频格式原理:将完整的视频拆分成多个 .ts 视频碎片,.m3u8 文件详细记录每个视频片段的 ...

  2. M3U8视频下载合并工具

    M3U8视频下载合并工具 M3U8视频下载合并工具是一款将网络上切片的M3U8文件下载合并成视频的工具,软件操作简单实用方便. 使用方法 将M3U8地址填入文件地址内,填入文件名 点击添加任务,在点击 ...

  3. 影视剪辑高清视频素材怎么找?附全网视频下载工具使用教程方法

    剪辑圈自媒体今天分享的是,教你如何在网络上找到自己喜欢的视频素材,找到视频原片出处 .全网视频下载软件的操作方法. 视频下载工具使用步骤* 剪辑圈视频批量下载器的一个简单易学的m3u8文件视频下载工具 ...

  4. Python 实现 m3u8 视频下载

    Python 实现 m3u8 视频下载 m3u8 是一种基于文本的媒体播放列表文件格式,通常用于指定流媒体播放器播放在线媒体流.它是一个简单的文本文件,其中包含多个由 URI 引用的媒体资源文件的 U ...

  5. 一款开源的Hitomi-Downloader视频下载工具,几乎支持所有主流视频网站

    一款开源的Hitomi-Downloader视频下载工具,几乎支持所有主流视频网站 用过IDM的朋友可能知道IDM有个强大的功能就是可以嗅探网站各种视频.音频等资源,然后提供快捷下载,可不巧的是IDM ...

  6. 一款b站视频下载工具软件mac版

    是一款开源的哔哩哔哩视频下载工具,b站视频下载软件 mac能够快速为您下载Bilibili的视频!哔哩哔哩视频下载软件在您选择下载视频时会提示登录,登录后可以获取你的SESSDATA来用做下载,日常账 ...

  7. You-Get--基于Python3的开源网络视频下载工具

    CSDN GitHub You-Get–基于Python3的开源网络视频下载工具 AderXCoding/system/tools/you-get 本作品采用知识共享署名-非商业性使用-相同方式共享 ...

  8. 哔哩下载姬v1.3.3 B站视频下载工具

    介绍: 哔哩下载姬(downkyi)是一个简单易用的哔哩哔哩视频下载工具,具有简洁的界面,流畅的操作逻辑. 哔哩下载姬可以下载几乎所有的B站视频,并输出mp4格式的文件:采用Aria下载器多线程下载, ...

  9. 安装lux:推荐一款网页视频下载工具。并简单使用。(win)

    lux是一个视频下载工具,它可以快速简单地下载各种视频网站的视频,支持多种操作系统和语言. 功能大概如下: 下载各种视频网站的视频,包括YouTube,Bilibili,Youku等(完整的支持列表见 ...

  10. 一些造好的轮子-视频下载工具

    一些造好的轮子 视频下载工具 -- 科技改变生活 几个很好用的工具推荐及一些基本的使用方法: YOU-GET You-Get是一个基于Python3的下载工具.使用You-Get可以很轻松的下载网上的 ...

最新文章

  1. 人工智能重构下的金融场景
  2. 按照文件名最后数字进行排序
  3. Java获取文件路径获取访问路径、域名、项目名、请求入参
  4. SAP Spartacus B2B User 页面的数据读取逻辑设计
  5. 机床使用教学_2020沧州cnc培训20年教学经验颁发职业
  6. 小程序支付成功后跳转页面失败
  7. 2021信服云创新峰会:托管云成上云第三种选择
  8. np.copysign_带有Python示例的math.copysign()方法
  9. 我的python之行
  10. 会计的思考(37):“弱水三千,只取一瓢饮”--业务人员的财务意识
  11. java jpanel 数据刷新6_刷新swing
  12. APISpace 二维码生成器API
  13. 【错误记录】Kotlin 报错 ( Some kotlin libraries attached to this project were compiled with a newer kotlin )
  14. 计算机主机中包,百度地图脱机包最终可以在计算机上导入
  15. Spring中多语言页面适配方案总结
  16. 免费的编程中文书籍索引
  17. OSGEarth解决南北极空洞问题
  18. 利用PYTHON出小学数学题
  19. 大数据的4v特征、数据预处理
  20. Qt Windows安装教程

热门文章

  1. 斐讯路由器k2编程器救砖教程
  2. 雷云云服务器文件夹,配置文件云存储 雷蛇Synapse2.0_雷蛇鼠标_键鼠评测-中关村在线...
  3. 建立数据地图,盘活数据资产!
  4. 右键添加cmd命令快捷键,右键cmd快捷键丢失
  5. 机器学习周志华第一章
  6. 软件工程各种UML总结
  7. python分离gif_python图片合成与分解gif方法
  8. kodi电视smb android,小米/天猫魔盒KODI(XBMC)SMB协议播放测试
  9. word转Html的实现方案
  10. python xlsxwriter dict_使用python库xlsxwriter库来输出各种xlsx文件的示例