# -*- coding: UTF-8 -*-
import sys
sys.path.append("C:\\Python36-32\\Lib\\site-packages")
import tkinter
import re
import urllib3
import threadpool
import threading
import os
import shutil
import time
import glob
from tkinter.ttk import *
from PIL import Image, ImageTk
import pyperclip
from tkinter.filedialog import askdirectory
def get_image(filename,width,height):
im = Image.open(filename).resize((width,height))
return ImageTk.PhotoImage(im)
def get_resource_path(relative_path):
if hasattr(sys, '_MEIPASS'):
return os.path.join(sys._MEIPASS, relative_path)
return os.path.join(os.path.abspath("."), relative_path)
def getrealtask(link):
global key
rooturl1 = ''
rooturl2 = ''
pattern3 = re.compile(r'^.*[\/]', re.M)
result11 = pattern3.findall(link)
if result11:
rooturl1 = result11[0]
pattern4 = re.compile(r'^http[s]?:\/\/[^\/]*', re.M)
result114 = pattern4.findall(link)
if result114:
rooturl2 = result114[0]
res = http.request('GET', link)
content = str(res.data, 'utf8')
list = content.split('\n')
reallist = []
for one in list:
if one.endswith('"key.key"'):
keyurl = rooturl1 + "key.key"
res = http.request('GET', keyurl)
key = str(res.data, 'utf8')
if one.endswith('.ts') or one.endswith('.image'):
if re.match(r'http', one, re.M | re.I):
reallist.append(one)
elif re.match(r'\/', one, re.M | re.I):
reallist.append(rooturl2 + one)
else:
reallist.append(rooturl1 + one)
if one.endswith('.m3u8'):
if re.match(r'\/', one, re.M | re.I):
reallist = getrealtask(rooturl2 + one)
else:
reallist = getrealtask(rooturl1 + one)
break
return reallist
def download_ts(result):
url = result['url']
name = result['name']
num = result['num']
rootpath = result['root']
m3u8Name = result['m3u8name']
t= str(result['total'])
if num % 10000 == 0:
print(str(num)+' / '+t)
basepath = os.path.join(rootpath,m3u8Name)
fullpath = os.path.join(basepath,name)
isExist = os.path.exists(fullpath)
if not isExist:
http = urllib3.PoolManager(timeout=10.0)
while(1):
try:
f = http.request('GET', url)
break
except:
print("URL ERRO: " + url)
time.sleep(2)
d = f.data
with open(fullpath, "wb") as code:
code.write(d)
print("SAVE: " + url)
def clock2(num,path):
global window
global key
v3 = tkinter.StringVar();
v4 = tkinter.StringVar();
l3 = tkinter.Label(window, text='', textvariable=v3, font=('Arial', 10))
l4 = tkinter.Label(window, text='', textvariable=v4, font=('Arial', 10))
l3.place(x=10, y=130, anchor='nw')
l4.place(x=10, y=160, anchor='nw')
v3.set("下載中。。。")
while(1):
path_file_number = len(glob.glob(path+'/*.ts'))
mp4_file_number = len(glob.glob(path + '/*.mp4'))
numberstr = str(path_file_number) + '/'+str(num)
v4.set(numberstr)
if mp4_file_number==1:
v3.set("下載完成!")
key = ''
break
def clock1():
global v
global v2
global rootpath
m3u8Name = v2.get()
url = v.get()
print(url)
urls = getrealtask(url)
total = len(urls)
i = 0
tasks = []
tsNames = []
for one in urls:
task = {}
task['root'] = rootpath
task['m3u8name'] = m3u8Name
task['url'] = one
task['num'] = i
task['total'] = total
task['name'] = str(i) + '.ts'
tsNames.append(str(i) + '.ts')
i = i + 1
tasks.append(task)
print('tasks: ' + str(len(tasks)))
targetpath = os.path.join(rootpath, m3u8Name)
if not os.path.exists(targetpath):
os.makedirs(targetpath)
timer2 = threading.Thread(target=clock2,args=(len(tasks),targetpath))
timer2.daemon = True
timer2.start()
requests = threadpool.makeRequests(download_ts, tasks)
[task_pool.putRequest(req) for req in requests]
task_pool.wait()
mp4targetfile = os.path.join(targetpath, m3u8Name + '.mp4')
with open(mp4targetfile, 'wb') as f:
for ts in tsNames:
tstargetfile = os.path.join(targetpath, ts)
with open(tstargetfile, 'rb') as mergefile:
shutil.copyfileobj(mergefile, f)
print(tstargetfile + ' merged.')
for tts in tsNames:
tstargetfile = os.path.join(targetpath, tts)
os.remove(tstargetfile)
print(total)
def hit_me():
global on_hit
timer = threading.Thread(target=clock1)
timer.daemon = True
timer.start()
return
def choose_dir():
global v5
global rootpath
rootpath = askdirectory()
v5.set('文件夾: '+rootpath+'/')
return
def about():
window = tkinter.Toplevel()
window.geometry('600x100')# Note Toplevel, NOT Tk.
msg = 'Rax m3u8下載器 v1.4\n寫這個程序主要是為了學(xué)習(xí)Tk,順便滿足下自己看視頻的需求。\n家里的移動網(wǎng)絡(luò)看在線視頻還是有些卡頓的。 '
label = tkinter.Label(window, text=msg,font=('Arial', 15))
label.grid()
def update():
window = tkinter.Toplevel()
window.geometry('250x200')
msg = 'Rax m3u8下載器 v1.5\n可以選擇保存的目錄了\nRax m3u8下載器 v1.4\n增加了菜單欄'
label = tkinter.Label(window, text=msg,font=('Arial', 13))
label.place(x=30, y=30, anchor='nw')
def donate():
window = tkinter.Toplevel()
window.geometry('500x400')
msg = '軟件免費(fèi)使用\n歡迎喜歡此軟件的各位大佬打賞,謝謝。'
label = tkinter.Label(window, text=msg, font=('Arial', 20))
i1 = tkinter.PhotoImage(file=get_resource_path("images\\wx.png"))
i2 = tkinter.PhotoImage(file=get_resource_path("images\\zfb.png"))
imagelabel = tkinter.Label(window, text='aaa', image=i1, font=('Arial', 10))
imagelabel2 = tkinter.Label(window, text='vvv', image=i2, font=('Arial', 10))
imagelabel.place(x=10, y=145, anchor='nw')
imagelabel2.place(x=230, y=145, anchor='nw')
label.place(x=40, y=50, anchor='nw')
window.mainloop()
def clear():
global v
v.set("")
def paste():
global v
v.set(pyperclip.paste())
key = ''
on_hit = False
rootpath = "d:\\"
#最高50線程
task_pool = threadpool.ThreadPool(50)
http = urllib3.PoolManager(timeout=5.0)
urllib3.disable_warnings()
#主窗口初始化
window = tkinter.Tk()
window.style = Style()
window.style.theme_use("clam")
window.title("Rax m3u8視頻下載器")
window.geometry('500x300')
window.resizable(0,0)
#飛機(jī)背景圖
canvas_root = tkinter.Canvas(window,width=500,height=300)
im_root = get_image(get_resource_path('images\\feiji.jpeg'),500,300)
canvas_root.create_image(250,240,image=im_root)
canvas_root.pack()
#各控件初始狀態(tài)
l1 = tkinter.Label(window, text='m3u8地址:', font=('Arial', 10))
l1.place(x=10, y=0, anchor='nw')
# 地址欄
v = tkinter.StringVar();
e2 = tkinter.Entry(window, show=None, textvariable = v,font=('Arial', 10),width=40)
v.set('')
e2.place(x=10, y=30, anchor='nw')
# 視頻名稱
l6 = tkinter.Label(window, text = ' 視頻文件名稱:', font=('Arial', 10))
l6.place(x=0, y=90, anchor='nw')
# 視頻名稱欄
v2 = tkinter.StringVar();
e3 = tkinter.Entry(window, show=None, textvariable = v2,font=('Arial', 10),width=15)
v2.set('')
e3.place(x=105, y=90, anchor='nw')
# 保存位置
v5 = tkinter.StringVar();
l2 = tkinter.Label(window, textvariable = v5, font=('Arial', 10))
v5.set('文件夾: D:/')
l2.place(x=10, y=60, anchor='nw')
# 下載按鈕
b = tkinter.Button(window, text='下載', font=('Arial', 10), width=10, command=hit_me)
b.place(x=400, y=100, anchor='nw')
# 選擇路徑按鈕
pathselectButton = tkinter.Button(window, text='選擇路徑', font=('Arial', 10), width=10, command=choose_dir)
pathselectButton.place(x=400, y=60, anchor='nw')
# 清空按鈕
b2 = tkinter.Button(window, text='清空', font=('Arial', 10), width=10, command=clear)
b2.place(x=300, y=25, anchor='nw')
# 粘貼地址按鈕
b3 = tkinter.Button(window, text='粘貼地址', font=('Arial', 10), width=10, command=paste)
b3.place(x=400, y=25, anchor='nw')
# 求捐贈按鈕
l5 = tkinter.Label(window, text='軟件免費(fèi)使用,歡迎各位喜歡此軟件的大佬打賞,謝謝。\nQQ討論群:519565890', font=('Arial', 10))
l5.place(x=100, y=160, anchor='nw')
window.option_add('*tearOff', False)
#菜單欄
menubar = tkinter.Menu(window)
window['menu'] = menubar
help_menu = tkinter.Menu(menubar)
menubar.add_command(label='捐助作者',command=lambda: donate())
menubar.add_cascade(menu=help_menu, label='幫助')
#幫助 下拉菜單
help_menu.add_command(label='更新內(nèi)容',command=lambda: update())
help_menu.add_command(label='關(guān)于',command=lambda: about())
# 進(jìn)入消息循環(huán)
window.mainloop()
以上就是python基于tkinter制作m3u8視頻下載工具的詳細(xì)內(nèi)容,更多關(guān)于python m3u8視頻下載的資料請關(guān)注腳本之家其它相關(guān)文章!