这段代码是一个使用aiohttp库和asyncio库来下载和处理M3U8视频的脚本。M3U8是一种视频播放列表格式,常用于分片视频流的传输。
主要步骤如下:
- 导入需要的库,设置一些变量,如
path
为保存视频文件的路径,url
为M3U8视频的URL,ts_url
用于保存分片视频的URL。 getindex_m3u8
函数获取M3U8播放列表文件,解析出index.m3u8
和enc.m3u8
的URL,并请求这两个文件的内容。mkdir_path
函数用于创建文件夹、保存index.m3u8
和enc.m3u8
,并对index.m3u8
文件进行转换,重命名其中的TS文件名,并将TS的URL保存在ts_url
列表中。download
函数用于异步下载TS分片文件。ffmpeg
函数使用FFmpeg将所有的TS文件合并成一个MP4视频。main
函数是整个脚本的主控制函数。在main
函数中,先调用getindex_m3u8
获取播放列表文件内容,然后调用mkdir_path
进行目录创建和文件保存,接着使用asyncio.gather
并发下载所有的TS分片文件,最后使用ffmpeg
函数将下载的分片文件合并为一个MP4视频。- 在
if __name__ == '__main__':
部分,调用asyncio.run(main())
来执行整个异步任务。
这段代码实现了使用异步方法下载、合并M3U8视频的功能。注意,由于涉及到视频下载和处理,确保你了解所使用的M3U8格式和视频下载的合法性。
import asyncio
import os.path
import re
import os
import aiohttp
import requests
path = '影院'
# 自行替换该影院URL 主页:http://www.cdhxjdsb.com/
url = 'http://www.cdhxjdsb.com/dongzuopian/zhetianjinqu/1-1.html'
ts_url = []
headers = {
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
}
async def getindex_m3u8(url):
'''
:param url: 要下载的视频URL
:return: 返回m3u8和key的数据
'''
# 获取index.m3u8的链接
async with aiohttp.ClientSession(headers=headers) as session:
async with session.get(url, verify_ssl=False) as get_url:
data = await get_url.text()
r = re.search('"url":"(.*?)"', data).group(1)
# 去除转义符获得正确的index.m3u8链接
env_key = r.strip().replace("\\", '')
print(env_key)
# 获取key加密文件后边进行解密
key = env_key.replace('index.m3u8', 'enc.key')
print(key)
# 请求m3u8链接数据
async with aiohttp.ClientSession(headers=headers) as session2:
async with session2.get(env_key) as gei_m3u8:
m3u8 = await gei_m3u8.text()
# 请求key数据
async with aiohttp.ClientSession(headers=headers) as session3:
async with session3.get(key) as gei_key:
m3u8_key = await gei_key.text()
return m3u8, m3u8_key
async def mkdir_path(m3u8, m3u8_key):
'''
:param m3u8: 传入数据
:param m3u8_key: 传入数据
:return:
'''
# 创建文件夹,进行路径判断
if not os.path.exists(path):
# 创建文件夹
os.mkdir(path)
# 获取到的m3u8进行写入保存
with open(os.path.join(path, 'index.m3u8'), 'w') as f:
f.write(m3u8)
# 获取到的key进行写入保存
with open(os.path.join(path, 'enc.m3u8'), 'w') as a:
a.write(m3u8_key)
# 进行读取转换成自己的ts文件名
with open(os.path.join(path, 'index.m3u8'), 'r') as r:
date = r.readlines()
aa = open(os.path.join(path, 'index2.m3u8'), 'w')
e = 0
# 遍历原m3u8文件
for i in date:
# 判断进行转换成自己的ts文件名
if i.startswith("#"):
# 判断URL是否存在
if i.find('URI') != -1:
uu = i
i = re.sub(r'(#EXT-X-KEY:METHOD=AES-128,URI=)"(.*?)"',
f'#EXT-X-KEY:METHOD=AES-128,URI="enc.m3u8"', uu)
aa.write(i)
continue
else:
# 重写ts文件名
aa.write(str(e) + '.ts' + '\n')
ts_url.append(i.strip())
e += 1
async def dowmlaod(index, value):
'''
:param index: 接受下标
:param value: 接受URL
:return:
'''
# 请求URL获取字节数据
async with aiohttp.ClientSession(headers=headers) as session:
async with session.get(value, verify_ssl=False) as get_url:
data = await get_url.content.read()
# 开始写入保存ts视频文件
with open(os.path.join(path, f'{index}.ts'), 'wb') as f:
f.write(data)
print('下载完成' + str(index))
#
# # '''
# # 进行ts文件合并 解决视频音频不同步的问题 建议使用这种
# # :param filePath:
# # :return:
# # '''
# print('开始')
#
# ccc = os.chdir(path)
#
# os.system("ffmpeg -i index2.m3u8 -c copy cccc.mp4")
# print('结束')
async def ffmpeg():
'''
用ffmpeg合并处理加密
:return:
'''
print('开始')
ccc = os.chdir(path)
os.system("ffmpeg -i index2.m3u8 -c copy cccc.mp4")
print('结束')
async def main():
m3u8, m3u8_key = await getindex_m3u8(url)
print(m3u8)
print(m3u8_key)
await mkdir_path(m3u8, m3u8_key)
task = []
# 遍历下载所有ts文件 (获取ts的URL和索引)
for index, value in enumerate(ts_url):
task.append(dowmlaod(index,value))
await asyncio.gather(*task)
await ffmpeg()
if __name__ == '__main__':
asyncio.run(main())
评论前必须登录!
注册