这段代码是一个使用Python的asyncio
和aiohttp
库来下载m3u8格式的视频文件的示例。m3u8是一种常用的视频流媒体播放列表格式,它将视频分割为一系列的小文件(.ts文件),通过播放列表进行调度播放。下面是代码的主要流程:
- 导入所需的模块和库。
- 设置下载相关的路径、URL和headers。
- 使用
aiohttp
异步获取第一次URL,该URL是一个m3u8文件的地址。 - 使用
aiohttp
异步获取m3u8文件的URL,该URL是m3u8播放列表文件的地址。 - 使用
aiohttp
异步获取ts文件的URL,并将ts文件的完整URL存储到列表中。 - 并发地下载所有的ts文件,存储在指定的目录中。
- 使用
ffmpeg
命令将下载的ts文件合并成一个完整的视频文件。
请注意,要运行这段代码,需要满足以下条件:
- 安装所需的Python库:
aiohttp
、ffmpeg-python
。 - 确保已安装并配置好了
ffmpeg
,以便能够执行合并操作。 - 根据需要,可以修改路径、URL、文件名等设置。
- 请注意合并操作可能需要一些时间,具体取决于视频文件的大小和下载速度。
此外,要注意这段代码在下载过程中禁用了证书验证,这在正式环境中是不安全的做法。在实际使用中,应该考虑启用证书验证以确保安全性。
import os.path
import urllib.parse
import asyncio
import aiohttp
import re
# 禁用证书验证警告
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
path = 'ts'
# 目标URL
url = 'https://www.99meijutt.com/play/102788-1-0.html'
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'
}
ts_url_list = []
# 获取第一次url
async def get_url(url):
async with aiohttp.ClientSession(headers=headers) as session:
async with session.get(url, verify_ssl=False) as response:
data = await response.text()
url_m3u8 = re.search('now="(.*?)"', data).group(1)
return url_m3u8
# 获取m3u8文件的URL
async def get_m3u8url(url_m3u8):
async with aiohttp.ClientSession(headers=headers) as session:
async with session.get(url_m3u8, verify_ssl=False) as response:
data = await response.text()
# 使用最后一行的URL拼接完整的m3u8文件URL
url2 = urllib.parse.urljoin(url_m3u8, data.split()[-1])
return url2
# 获取ts文件的URL并下载
async def get_tsurl(url2, base_url):
i = 0
async with aiohttp.ClientSession(headers=headers) as session:
async with session.get(url2, verify_ssl=False) as response:
data = await response.content.read()
with open('u8m3_url.m3u8', 'wb') as f:
f.write(data)
with open('u8m3_url.m3u8', 'r') as f:
get_tsurll = f.readlines()
aa = open(os.path.join(path, 'do_m3u8.m3u8'), 'w')
for ts_url in get_tsurll:
if ts_url.startswith("#"):
aa.write(ts_url)
continue
else:
aa.write(str(i) + f'.{path}\n')
# 拼接完整的ts文件URL
full_ts_url = urllib.parse.urljoin(base_url, ts_url.strip())
ts_url_list.append(full_ts_url)
i += 1
# 下载ts文件
async def download(full_ts_url, i):
async with aiohttp.ClientSession(headers=headers) as session:
async with session.get(full_ts_url, verify_ssl=False) as response:
data = await response.content.read()
if not os.path.exists(path):
os.mkdir(path)
with open(os.path.join(path, str(i) + '.ts'), 'wb') as f:
f.write(data)
print('下载完成')
def merge(filename='output'):
'''
进行ts文件合并 解决视频音频不同步的问题 建议使用这种
:param filePath:
:return:
'''
print('开始')
c = os.chdir(path)
print(c)
cmd = f'ffmpeg -i do_m3u8.m3u8 -c copy {filename}.mp4'
os.system(cmd)
print('结束')
async def main():
# 获取第一次的URL
first_url = await get_url(url)
print('第一次的URL:', first_url)
# 获取m3u8文件的URL
m3u8_url = await get_m3u8url(first_url)
print('m3u8文件的URL:', m3u8_url)
# 获取ts文件的URL并下载
await get_tsurl(m3u8_url, first_url)
# 并发下载TS文件
tasks = []
for i, ts_url in enumerate(ts_url_list):
tasks.append(download(ts_url, i))
await asyncio.gather(*tasks)
merge()
if __name__ == '__main__':
asyncio.run(main())
评论前必须登录!
注册