目录

加密类型

需要的库

总体思路

解码代码

实例代码

运行结果

伪装类型

总体思路

修改头部代码

实例代码

嵌套类型

实例代码


加密类型

如下图所示,该m3u8文件采用了AES的加密方式,这个加密的密钥就在这个URI中(根据情况不同密码获取会有略微差别)

然后我们复制URI中的网址到浏览器,会发现他直接下载了一个key.key的文件,然后我们将后缀名进行修改,更改为txt类型,密码就在txt文件中显示出来了。

需要的库

然后就是去对每一个ts文件进行解码,一般m3u8文件的加密采取AES加密方式,在这里我们需要用到python中的几个库,分别去下载一下

# 这两个是AES解码
pip install pycryptodome
pip install pycrypto
# 这个是对文件夹进行操作
pip install shutilwhich
# 这个是爬取信息用
pip install requests
# 这个用来合并视频,注意:ffmpy的使用首先要安装ffmpeg环境
pip install ffmpy3
# 这个用来模拟进程,进度条显示的作用
pip install tqdm

总体思路

仅提供个人对处理加密型m3u8的思路

解码代码

from Crypto.Cipher import AES
import requestskey="你文件解析用的密码"
cryptor = AES.new(key.encode('utf-8'), AES.MODE_CBC)
# 以字节流形式写入ts文件
with open('你的ts文件名.ts', 'ab') as code:headers={"你的请求头信息"}# 也可以不添加请求头datas = requests.get("你ts文件所在的url",headers=headers).contentcode.write(cryptor.decrypt(datas))# 如果你的ts在本地就先读取数据再重新写入

实例代码

本代码只是作为例子使用,并不能保证对所有的m3u8文件都起作用

import os
import re
import shutil
import requests
from ffmpy3 import FFmpeg
from urllib import request
from Crypto.Cipher import AES
from tqdm import tqdm   #这个库用来反应进程,相当于进度条,可以不要# 1.获取密码
def get_key(name):"""根据m3u8内容的不同,有的可能需要在网页中的js文件中寻找,正则匹配可能也会有所变化,请根据自己的实际代码进行操作:param name: 自己的m3u8文件名称,不用加后缀“.m3u8”:return: 返回这个AES的解码密码"""with open(f"Temporary\\{name}.m3u8","r") as m3u8:text=m3u8.read()keypath=re.findall('URI="(.+)"',text)request.urlretrieve(keypath[0], f'{os.getcwd()}\\Temporary\\{name}.txt')with open(f"Temporary\\{name}.txt","r") as key:password=str(key.read())return password
# 2.下载m3u8文件中的ts
def download_ts(key,name,headers,times):"""先下载部分ts文件到tslib文件夹中,然后先将这一部分内容进行合并存入together文件夹下,然后将together文件夹中的ts文件全部合并成MP4文件:param key: 用来给ts文件解码用的密码:param name: m3u8文件的名字,可以自己定:param headers: 向网页发送的请求头信息,需要根据自己爬取的网页不同进行相应的调整:param times: 分开循环的次数,由于自己下载的文件体量比较大,就进行了分批处理,防止在一次性合并中出现问题(暂时还不会多进程,之后会更新):return:"""cryptor = AES.new(key.encode('utf-8'), AES.MODE_CBC)web_list = []with open(fr"{os.getcwd()}\Temporary\{name}.m3u8", "r") as files:lines_list = files.readlines()for https in lines_list:web = re.search("https://.+\.ts", https)if web:web_list.append(web.group())os.remove(f"Temporary\\index.m3u8")os.remove(f"Temporary\\index.txt")length = len(web_list)with open(f"Temporary\\filesname.txt", "a+") as to:to.write("\n")              #该格式请勿变动for time in range(times):remove_or_set(f"{os.getcwd()}\\tslib")to.write(f"file  '{os.getcwd()}\\together\\{time}.ts'\n")           #该格式请勿变动with open(f"Temporary\\filesname{time}.txt", "a+") as file:file.write("\n")for num in tqdm(range(int(length/times*time),int(length/times*(time+1)))):file.write(f"file  '{os.getcwd()}\\tslib\\{num}.ts'\n")             #该格式请勿变动with open(f'{os.getcwd()}\\tslib\\{num}.ts', 'ab') as code:datas = requests.get(web_list[num],headers=headers).contentcode.write(cryptor.decrypt(datas))together_ts(time)os.remove(f"Temporary\\filesname{time}.txt")
def together_ts(times):"""先合并一些ts放到together中的函数操作:param times: 分批的次数,方便找对应的filename{times}.txt文件:return:"""ff = FFmpeg(inputs={fr"{os.getcwd()}\Temporary\filesname{times}.txt": "-f concat -safe 0"},outputs={fr"{os.getcwd()}\together\{times}.ts": "-c copy"})# print(ff.cmd)ff.run()
# 3.将ts文件转化成MP4格式
def together_mp4(name):"""将together文件夹中的ts文件转化成MP4文件,也就是最后一步:param name::return:"""ff = FFmpeg(inputs={fr"{os.getcwd()}\Temporary\filesname.txt": "-f concat -safe 0"},outputs={fr"{os.getcwd()}\MP4\{name}.mp4": "-c copy"})# print(ff.cmd)ff.run()
# 这个拿来清理使用
def remove_or_set(filepath):"""清理文件夹使用,如果没有这个文件夹,就创建,有就清楚该目录下的所有内容:param filepath: 要清理或创建的文件夹"""if not os.path.exists(filepath):os.mkdir(filepath)else:shutil.rmtree(filepath)os.mkdir(filepath)
def clear(filepath,times):remove_or_set(filepath)try:os.remove("Temporary\\index.m3u8")os.remove("Temporary\\index.txt")os.remove("Temporary\\filesname.txt")except:passfor num in range(times):try:os.remove(f"Temporary\\filesname{num}.txt")except:continuedef main():headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.71"}m3u8_key_name='你在Temporary文件夹中的m3u8文件名称'mp4_name='你要转换的MP4叫什么'download_ts(get_key(m3u8_key_name), m3u8_key_name, headers, times=10)together_mp4(mp4_name)clear(f'{os.getcwd()}\\tslib', times=10)

运行结果

由于速度比较慢,这里给出了进度条画面

伪装类型

如下图所示,该m3u8文件本来的ts文件后缀全部变成了png格式

总体思路

仅提供个人对处理加密型m3u8的思路

修改头部代码

with open(f"没有修改的ts文件名.ts", "rb") as infile:with open(f"将修改后的数据写入的ts的名称.ts", "wb") as outfile:data = infile.read()outfile.write(data)outfile.seek(0x00)outfile.write(b'\xff\xff\xff\xff')outfile.flush()outfile.close()

实例代码

本代码只是作为例子使用,并不能保证对所有的m3u8文件都起作用

from tqdm import tqdm
import requests
import os
import re
from ffmpy3 import FFmpeg# 1.直接下载ts文件,不管后缀是什么直接改为ts后缀
def download_ts(name):"""以字节流形式下载ts文件:param name: 我们下载过来的m3u8文件:return: 返回尚未处理的ts文件"""web_list = []with open(fr"{os.getcwd()}\{name}.m3u8", "r") as files:lines_list = files.readlines()for https in lines_list:web = re.search("https://.+", https)if web:web_list.append(web.group())files.close()headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.71"}# print("正在下载ts文件......")print("ts视频加载进度:")length = len(web_list)with open("filesname.txt","a+") as file:file.write("\n")for url, num in tqdm(zip(web_list, range(1, length + 1))):file.write(f"file  '{os.getcwd()}\\tslib\{num}.ts'\n")resp = requests.get(url, headers=headers)with open(fr"tslib\{num}.ts", "wb") as codes:codes.write(resp.content)return length
# 2.处理这些经过伪装的ts文件,直接对ts文件的头部进行修改
def change(num):"""由于这个m3u8文件比较特殊,里面头部信息为png,我们要将它修改成ts:param num: 这个就是总共的ts数:return: 返回修改过后的ts文件"""with open(fr"{os.getcwd()}\filelist.txt", "a+") as file:file.write("\n")print("\n\n正在转化ts文件......")print("ts视频转化进度:")for i in tqdm(range(1, num + 1)):  # num+1file.write(f"file  '{os.getcwd()}\\outlib\\{i}.ts'\n")with open(f"{os.getcwd()}\\inlib\\{str(i)}.ts", "rb") as infile:with open(f"{os.getcwd()}\\outlib\\{str(i)}.ts", "wb") as outfile:data = infile.read()outfile.write(data)outfile.seek(0x00)outfile.write(b'\xff\xff\xff\xff')outfile.flush()outfile.close()
# 3.将ts文件合并成MP4文件
def together(name,num):"""合并outlib列表中的所有ts文件:param name: 爬取视频的名字:return: 返回一个MP4文件"""ff = FFmpeg(inputs={fr"{os.getcwd()}\filesname.txt": "-f concat -safe 0"},outputs={fr"{os.getcwd()}\{name}\{name}-第{num}集.mp4": "-c copy"})# print(ff.cmd)ff.run()def main():m3u8_name='你的m3u8名称'ts_num=download_ts(m3u8_name)change(ts_num)together('你要看的影视的名字','集数')

嵌套类型

如下图所示,该m3u8文件就只有这么短短的几行

这种情况还是比较简单的,首先我们要明确这个代码是哪里来的,那个网站,然后将后面这一串   /20220104/22Mp6rI2/1000kb/hls/index.m3u8  拼接到域名上重新回去一遍就行了

实例代码

本代码只是作为例子使用,并不能保证对所有的m3u8文件都起作用

import re
from urllib import parse
from urllib import requesturl='下载嵌套m3u8文件的地址'
request.urlretrieve(url,f'下载下来存在嵌套的m3u8文件名.m3u8')    # 下载m3u8文件
result = parse.urlparse(url)      # 解析url
with open(f"下载下来存在嵌套的m3u8文件名.m3u8","r") as m3u8:text=m3u8.read()                # 读取m3u8文件中的数据
m3u8path=re.findall("/.+index\.m3u8",text)  # 运用正则匹配url域名后的路径
true_m3u8_url=result.netloc+m3u8path[0]   # 拼接域名和路径
request.urlretrieve(f'https://{true_m3u8_url}', f'你要存储的m3u8名.m3u8')   # 重新发送请求获取真正的m3u8文件

关于m3u8转MP4的几种情况相关推荐

  1. 某站视频python抓取: m3u8转mp4

    之前利用python简单爬虫抓过一些图片,最近想到了抓取视频.由于很多地方视频不提供下载.所以觉得有必要学习一下,以备不时之需.备注:这里仅记录碰到的网站视频实例,不保证适用所有情况. 基本概念与思路 ...

  2. 安卓手机m3u8转为mp4格式100%有效的方法

    本文以图片形式手把手演示,请读者耐心 首先推荐两款安卓手机上全网视频下载神器 X浏览器和QQ浏览器 虽然我平时用安卓手机的X浏览器(这款浏览器强烈推荐使用)的嗅探资源媒体功能就已经能下载90%的网络视 ...

  3. 进一步封装axios并调用其读取数据(吐槽~在安卓9.0以下或者IOS10.X以下手机端H5页面不支持,在这两种情况下的系统只能使用ajax或者原生js请求后台数据)

    注意!!!(修改于2020年7月18日) 在安卓9.0以下或者IOS10.X以下手机端H5页面不支持,在这两种情况下的系统只能使用ajax或者原生js请求后台数据 报错截图如下 报错内容: {&quo ...

  4. bartender外部表不是预期格式_批量合并Excel数据时“外部表不是预期格式”或“文件包含损坏数据”的两种情况...

    很多朋友在用Power Query合并(汇总)Excel数据时,碰到过"DataFormat.Error:外部表不是预期格式"或"DataFormat.Error:文件包 ...

  5. 对象的notify方法的含义和对象锁释放的三种情况

    1,notify的含义     (1)notify一次只随机通知一个线程进行唤醒 (2)在执行了notify方法之后,当前线程不会马上释放该对象锁,呈wait状态的线程也不能马上获得该对象锁, 要等到 ...

  6. linux下mv命令移动目录的二种情况

    mv 移动目录分为2种情况: 第一种:目标目录为空,使用mv命令可以直接移动,使用绝对路径执行或加参数-f 不会提示是否移动. [root@localhost ~]# mkdir 1 [root@lo ...

  7. C++对象模型2——编译器生成构造函数的几种情况

    如果程序员没有提供构造.析构.拷贝构造以及operator=,编译器并不会总是提供一个合成版本,比如下面的代码 class test{};int main(int argc, char const * ...

  8. Error LNK2001 无法解析的外部符号 的几种情况及解决办法

    Error LNK2001 无法解析的外部符号 的几种情况及解决办法 多线程下的单例模式 这里要处理的是懒汉模式. [cpp] view plain copy  class Singleton { p ...

  9. SSO单点登录三种情况的实现方式详解

    SSO单点登录三种情况的实现方式详解 单点登录(SSO--Single Sign On)对于我们来说已经不陌生了.对于大型系统来说使用单点登录可以减少用户很多的麻烦.就拿百度来说吧,百度下面有很多的子 ...

最新文章

  1. 程序员的自我救赎---13.1:职场招聘与面试心得
  2. c#实现规约文本自动添加到尾部并且不影响操作
  3. 斐波那契问题的递归和动态规划
  4. tensorflow就该这么学--6(多层神经网络)
  5. VTK:可视化算法之CarotidFlowGlyphs
  6. operator new,new operator,placement new的区别
  7. linux 安卓git,在Linux系统上安装Git
  8. 200个 jquery插件
  9. VC6.0多线程例程
  10. C# 利用SQLite对.DB和.logdb加密和解密和SQLite创建数据库
  11. 服务器常规维修与判断方法,服务器常规维修与判断方法88119.doc
  12. linux系统上安装远程软件下载,如何安装向日葵远程控制软件Linux被控端?
  13. MIPS中lw指令运行时间最长
  14. Java中BigDecimal用法
  15. Bootstrap文字排版
  16. SQL SERVER 窗口函数4 偏移函数:LAG、LEAD 、FIRST_VALUE、 LAST _VALUE、NTH_VALUE
  17. GBase 8c产品高级特性介绍
  18. java学习---类与对象
  19. PG的管道模式如何工作
  20. vue文件流导出excel表格打不开

热门文章

  1. selenium+java发送cookie,绕过验证码登录
  2. 蚁群算法求最值c语言实现,蚁群算法代码(求函数最值)
  3. 为什么mysql不建议执行超过3表以上的多表关联查询?
  4. VC中鼠标移动点击操作
  5. 新手小白想要成为软件测试工程师,必须要学会的这些基础知识!
  6. Excel序号类操作实例
  7. 极米、当贝、坚果3000内的投影仪有什么推荐?
  8. Docker查看container的详细信息啥的*
  9. 《图解HTTP》全文笔记梳理
  10. 论文研究范围从什么角度怎么写?