最近看到某有色網站的視頻不錯,可是這個網站的網速不太理想,就想下載看,偏偏視頻又是加密的,遂破解之。
# -*- coding: utf-8 -*-
"""
Created on 2022-03-21 0021 21:45
@Software : PyCharm
@author: Administrator
"""
import requests, os, pyperclip, re
from tqdm import tqdm
path = r'E:\pojie'
headers = {
'Connection': 'keep-alive',
'其他header': '信息隱藏',
}
proxy = {
'http': None,
'https': None
}
def get_res(url, file_path):
"""
下載ts視頻流
:param url: ts流鏈接
:param file_path: 臨時文件路徑
:param key: 加密密鑰
"""
try:
response = requests.get(url=url, timeout=120, headers=headers)
with open(file_path, 'wb+') as f:
f.write(response.content)
except Exception as e:
print(e)
def get_list(url):
response = requests.get(url, headers=headers, proxies=proxy)
return response
def get_keys(url):
"""
獲取加密密鑰
:param url: 密鑰網址
:return:
"""
response = requests.get(url, proxies=proxy)
return response
def write_keys(response, filename):
"""
寫入密鑰文件
:param response: 返回的密鑰響應
:param filename: 密鑰文件名
:return:
"""
file_path = os.path.join(path, filename)
# print(file_path)
with open(file_path, 'wb+') as fp:
fp.write(response.content)
def get_links_from_file(path):
"""
從文件中批量讀取網址
:param path: 文件所在位置
:return:
"""
with open(path, 'r', encoding='utf-8') as fp:
st = fp.readlines()
return st
def write_list(list_path1, list_path2, keystring):
"""
重寫本地m3u8文件,用於ffmpeg合成用
:param list_path1:
:param list_path2:
:param keystring: 記錄密鑰信息的那一行的字符串,
例如''#EXT-X-KEY:METHOD=AES-128,URI="E:/pojie/videokey",IV=0x00000000000000000000000000000000\n'
:return: 不返回信息
"""
fp1 = open(list_path1, 'r', encoding='utf-8')
fp2 = open(list_path2, 'w+', encoding='utf-8')
st_list = fp1.readlines()
fp1.close()
index = 0
for st in st_list:
if st[:10] == '#EXT-X-KEY':
if index < 1:
fp2.write(keystring)
continue
elif st[:1] == "#":
fp2.write(st)
else:
if index < 9:
filename = f'00{index + 1}.ts'
elif index < 99:
filename = f'0{index + 1}.ts'
else:
filename = f'{index + 1}.ts'
fp2.write(filename + '\n')
index += 1
fp2.close()
def get_key_url(path):
"""
從下載好的m3u8文件里讀取密鑰網址
:param path:
:return:
"""
with open(path, 'r') as f:
st = f.read()
ur = re.findall('#EXT-X-KEY:METHOD=AES-128,URI="(.*?)"', st)
url = ur[0]
# print(url)
return url
def write_video(response, filename):
"""
下載視頻
:param response: response響應
:param filename: 視頻保存的文件名
:return:
"""
video_path = os.path.join(path, filename)
if not os.path.exists(path):
os.mkdir(path)
with open(video_path, 'wb+') as fp:
fp.write(response.content)
def join_video(listname, newfilename):
"""
利用ffmpeg合並加密的ts文件
:param listname: 本地m3u8文件路徑
:param newfilename: 待合成的文件名稱
:return:
"""
command = f'ffmpeg -allowed_extensions ALL -i {listname} -c copy {newfilename}'
command1 = 'cd /d E:/pojie'
print(command)
os.system(command1)
os.system(command)
def d_k(path):
"""
下載密鑰
:return:
"""
filename = 'videokey'
url = get_key_url(path)
res = get_keys(url)
write_keys(res, filename)
return res
def d_l(url):
"""
下載m3u8列表
:return:
"""
filename = '01.m3u8'
res = get_list(url)
write_video(res, filename)
def d_v(url_left, list_path, key):
"""
下載視頻
:return:
"""
url_list = get_links_from_file(list_path)
index = 0
for url in url_list:
if url[:1] == 'v':
if index < 9:
filename = f'00{index + 1}.ts'
elif index < 99:
filename = f'0{index + 1}.ts'
else:
filename = f'{index + 1}.ts'
new_url = url_left + url
new_url = new_url.strip()
file_path = os.path.join(path, filename)
downloadFile(new_url, file_path)
# time.sleep(2)
index += 1
else:
continue
def get_url_left(url):
"""
讀取m3u8的網址前綴
:param url:
:return:
"""
url_list = url.split('/')
url_list[1] = 'https:/'
new_url = '/'.join(url_list[1:-1])
new_url = new_url + '/'
return new_url
def rename():
"""
重命名合成后的文件
:return:
"""
txt_path = r'C:\Users\rabbit\PycharmProjects\utils\video\links.txt'
fp = open(txt_path, 'r', encoding='utf-8')
st_list = fp.readlines()
fp.close()
path1 = r'E:\pojie'
old_path = r"E:\pojie\03.mp4"
filename = st_list[0].strip() + '.mp4'
new_path = os.path.join(path1, filename)
os.rename(old_path, new_path)
fo = open(txt_path, 'w', encoding='utf-8')
for index, line in enumerate(st_list):
if index == 0:
continue
else:
fo.write(line)
fo.close()
return new_path
def delete_TS():
"""
永久刪除下載的ts視頻流分段
:return:
"""
path = r'E:\pojie'
file_list = os.listdir(path)
for file in file_list:
if file[-2:] == 'ts':
print(f'{file}已刪除')
file_path = os.path.join(path, file)
os.remove(file_path)
def downloadFile(url, name):
"""
下載實時顯示速度
:param url:
:param name:
:return:
"""
# print(url)
# 用流stream的方式獲取url的數據
resp = requests.get(url, stream=True, headers=headers, proxies=proxy)
# 拿到文件的長度,並把total初始化為0
total = int(resp.headers.get('content-length', 0))
# 打開當前目錄的fname文件(名字你來傳入)
# 初始化tqdm,傳入總數,文件名等數據,接着就是寫入,更新等操作了
with open(name, 'wb+') as file, tqdm(
desc=name,
total=total,
unit='iB',
unit_scale=True,
unit_divisor=1024,
) as bar:
for data in resp.iter_content(chunk_size=1024):
size = file.write(data)
bar.update(size)
def mainone():
"""
主程序入口
:return:
"""
# 讀取剪貼板中的m3u8鏈接
url = pyperclip.paste()
if not os.path.exists(path):
os.mkdir(path)
path1 = "E:\\pojie\\01.m3u8"
path2 = "E:\\pojie\\02.m3u8"
keystring = '#EXT-X-KEY:METHOD=AES-128,URI="E:/pojie/videokey",IV=0x00000000000000000000000000000000\n'
# 獲取m3u8鏈接前綴,用於拼接ts網址
url_left = get_url_left(url)
# 下載m3u8列表
d_l(url)
# 下載密鑰,保存到此文件中,E:/pojie/videokey
res = d_k(path1)
# 下載TS分段
d_v(url_left, path1, res.content)
# 下載完分段后,重寫本地的m3u8文件,方便后續使用ffmpeg合成
write_list(path1, path2, keystring)
filename = 'E:\\pojie\\03.mp4'
# 合並文件
join_video(path2, filename)
# 讀取目錄文件並重命名
np = rename()
# 刪除TS分段
delete_TS()
# 輸出已下載好的文件名
print(np)
if __name__ == '__main__':
mainone()
