我開始使用 python 并為我的妻子開發一個 youtube 視頻/音頻下載器。它已經可以使用了,但我想通過放置一個可以確定或不確定的下載進度條來改善它的外觀。我搜索了幾個地方,甚至翻過stackoverflow,但我找不到自己的解決方案。也許我的代碼有點亂,但我正在努力。
因為我做了兩個單獨的程式,所以我只會發布視頻下載器。音頻包含更多行,只是從鏈接中更改我想要的檔案型別并將其轉換為 mp3,因為 tkinter 僅下載 mp4 音頻。然后我要把兩者合二為一。
from pytube import YouTube
from tkinter import *
from threading import Thread
def threading():
t1 = Thread(target=downloader)
t1.start()
def threading2():
t1 = Thread(target=downloader2)
t1.start()
def threading3():
t1 = Thread(target=downloader3)
t1.start()
def threading4():
t1 = Thread(target=downloader4)
t1.start()
def threading5():
t1 = Thread(target=downloader5)
t1.start()
def downloader():
url = YouTube(str(inp.get()))
video = url.streams.get_highest_resolution()
video.download()
Label(janela, text='Baixado', font='arial 15').grid(column=0, row=9)
def downloader2():
url = YouTube(str(inp2.get()))
video = url.streams.get_highest_resolution()
video.download()
Label(janela, text='Baixado', font='arial 15').grid(column=0, row=9)
def downloader3():
url = YouTube(str(inp3.get()))
video = url.streams.get_highest_resolution()
video.download()
Label(janela, text='Baixado', font='arial 15').grid(column=0, row=9)
def downloader4():
url = YouTube(str(inp4.get()))
video = url.streams.get_highest_resolution()
video.download()
Label(janela, text='Baixado', font='arial 15').grid(column=0, row=9)
def downloader5():
url = YouTube(str(inp5.get()))
video = url.streams.get_highest_resolution()
video.download()
Label(janela, text='Baixado', font='arial 15').grid(column=0, row=9)
janela = Tk()
janela.title('God Of YouTube Downloader - No AD Version')
janela.geometry('480x500')
janela.resizable(0, 0)
janela.config(background='#dde')
inp = StringVar()
inp2 = StringVar()
inp3 = StringVar()
inp4 = StringVar()
inp5 = StringVar()
imgLogo = PhotoImage(file='youtube.gif')
imagem_logo = Label(janela, image=imgLogo).grid(column=0, row=0, pady=20)
cole_aqui = Label(janela, text='Cole aqui, seu link!', font='arial 15 bold', background='#dde')
cole_aqui.grid(column=0, row=1, pady=5)
entrada_download = Entry(janela, width=50, textvariable=inp)
entrada_download.grid(column=0, row=2, padx=82, pady=3)
entrada_download2 = Entry(janela, width=50, textvariable=inp2)
entrada_download2.grid(column=0, row=4, padx=82, pady=3)
entrada_download3 = Entry(janela, width=50, textvariable=inp3)
entrada_download3.grid(column=0, row=5, padx=82, pady=3)
entrada_download4 = Entry(janela, width=50, textvariable=inp4)
entrada_download4.grid(column=0, row=6, padx=82, pady=3)
entrada_download5 = Entry(janela, width=50, textvariable=inp5)
entrada_download5.grid(column=0, row=7, padx=82, pady=3)
botao_download = Button(janela, text='Baixar', width=20,
command=lambda: [threading(), threading2(), threading3(), threading4(), threading5()])
botao_download.grid(column=0, row=8, pady=20)
identif = Label(janela, text='@God Of Python', font='arial 8 bold').place(x=380, y=470)
janela.mainloop()
uj5u.com熱心網友回復:
我創建了一個示例,用于Label顯示還有多少位元組要下載。

如果您獲得檔案長度,則可以將其計算為百分比。
YouTube()可以在下載程序中使用on_progress_callback和on_complete_callback執行功能,它們可以用來顯示進度。
這些函式在新執行緒中運行,它們不能直接更新小部件(它會產生錯誤),所以我Queue()用來將這些函式的值發送到主執行緒。主執行緒用于每 100 毫秒root.after()執行一次。update_status()這個函式從佇列中獲取資訊并更新標簽。
每個執行緒number稍后將其發回以及update_status()更新哪個標簽
類似的方式它可以與小部件 Progressbar 一起使用。
為了測驗,我直接在代碼中添加了一些鏈接——所以我不必在每次運行時手動放置它們。
因為我使用for-loopslist所以我減少了代碼但仍然有5個條目,并且可以同時下載5個檔案。如果我會使用 range(10),那么我可以下載 10 個檔案。
最初我創建all_threads以保留所有執行緒并用于is_alive()檢查已完成的執行緒,但現在我不使用此串列。
我試圖只保留在示例中非常重要的元素——所以我洗掉了字體、顏色、影像。
from pytube import YouTube
import tkinter as tk # PEP8: `import *` is not preferred
from threading import Thread
from queue import Queue
# --- functions ---
def update_status():
# check if there are new messages in queue and update correct label
while not queue.empty():
number, text = queue.get()
print('[update_status]:', number, text)
all_labels[number]['text'] = text
root.after(100, update_status) # run again after 100ms
def on_progress(number, queue, stream, chunk, bytes_remaining):
print('[on_progress] bytes_remaining:', bytes_remaining)
queue.put( (number, bytes_remaining) )
def on_complete(number, queue, stream, file_path):
print('[on_complete] file_path:', file_path)
queue.put( (number, file_path) )
def download(url, number, queue):
print('[download] started:', url)
queue.put( (number, 'started') )
yt = YouTube(url,
on_progress_callback=lambda *args:on_progress(number, queue, *args),
on_complete_callback=lambda *args:on_complete(number, queue, *args),
)
video = yt.streams.get_highest_resolution()
video.download()
all_threads[number] = None # inform that finished
print('[download] finished:', url)
#queue.put( (number, 'finished') )
def start_threads():
for number, (t, entry) in enumerate(zip(all_threads, all_entries)):
url = entry.get().strip()
if url:
print('[start_threads]:', number, 'starting')
t = Thread(target=download, args=(url, number, queue))
t.start()
else:
print('[start_threads]:', number, 'empty')
t = None
all_threads[number] = t
# --- main ---
all_threads = [None] * 5 # to have all values at start
all_entries = []
all_labels = []
root = tk.Tk()
queue = Queue()
for n in range(5):
entry = tk.Entry(root, width=50)
entry.grid(column=0, row=n)
all_entries.append(entry)
label = tk.Label(root, width=15, text='-')
label.grid(column=1, row=n)
all_labels.append(label)
button = tk.Button(root, text='Start', command=start_threads)
button.grid(column=0, row=n 1, columnspan=2)
# for test I put some links so I don't have to do it manually
all_entries[0].insert('end', 'https://www.youtube.com/watch?v=aqz-KE-bpKQ')
all_entries[1].insert('end', 'https://www.youtube.com/watch?v=bNfYUsDSrOs')
all_entries[2].insert('end', 'https://www.youtube.com/watch?v=W7LWny6c4wI')
all_entries[3].insert('end', 'https://www.youtube.com/watch?v=A8LRxIANzQs')
update_status()
root.mainloop()
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/446458.html
