关于m3u8转MP4的几种情况

目录

加密类型

需要的库

总体思路

解码代码

 实例代码

运行结果

 伪装类型

总体思路

修改头部代码

 实例代码

嵌套类型

实例代码


加密类型

        如下图所示,该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 requests

key="你文件解析用的密码"
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).content
    code.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).content
                        code.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:
        pass
    for num in range(times):
        try:
            os.remove(f"Temporary\\filesname{num}.txt")
        except:
            continue

def 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+1
            file.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 request

url='下载嵌套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文件

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
m3u8格式换为mp4格式的原因有几个。首先,m3u8格式在许多播放器中不受支持,只能在浏览器中进行在线观看。然而,在线观看可能不太方便,并且由于网络卡顿而导致播放体验不佳。其次,一些m3u8格式可能是加密的,即使使用一些工具下载后也无法播放。因此,将m3u8格式换为mp4格式可以解决这些问题,以便能够在更多的播放器上正常播放。\[1\] 要将m3u8格式换为mp4格式,可以使用一些工具或命令行操作。例如,可以使用FFmpeg工具将m3u8格式的文件合并为mp4格式的文件。具体的命令行操作可以参考引用\[2\]中提供的示例。\[2\] 总的来说,m3u8格式是一种将视频分成多个小部分的格式,方便视频的加载。而将m3u8格式换为mp4格式可以提供更广泛的播放支持,并提高播放体验。\[3\] #### 引用[.reference_title] - *1* [m3u8mp4无损换的方法和技巧](https://blog.csdn.net/zhr0835/article/details/122285442)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [使用ffmpeg把mp4m3u8相互换的操作](https://blog.csdn.net/m0_60259116/article/details/125301521)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值