问题描述
以下代码中的进度栏永远不会更新,对于方法show_progress
,从if
语句开始的代码也永远不会运行。
每当下载开始时,我需要更新进度条和标签downloading_progress_value
,并在下载完成时停止进度条。谁能告诉我错误在哪里?
注意:为简单起见,我删除了一些控件。 Python版本:3.7和 Pytube版本:9.6.4
import threading
from tkinter import *
from tkinter import messageBox as mBox
from tkinter import ttk
from pytube import YouTube
class Application:
def __init__(self,root):
self.root = root
self.video_url = "https://www.youtube.com/watch?v=fjHW5kBvonY"
########################### This label used to show the progress when download starts ###########################
self.downloading_progress_value = StringVar()
self.downloading_progress = Label(self.root,text=" ",textvariable=self.downloading_progress_value)
self.downloading_progress.place(x=114,y=190)
self.progress_bar = ttk.Progressbar(self.root,orient=HORIZONTAL,length=425,mode="determinate")
self.progress_bar.place(x=114,y=215)
########################### starting the dowload ###########################
def start_download(self):
self.app_download = DownloadApp(self.progress_bar,self.video_url.get(),self.folder_name,self.choices_var.get(),self.downloading_progress_value)
########################### the class responsible for downloading operations ###########################
class DownloadApp:
def __init__(self,progress_bar,youtube_url,media_folder,media_choice,downloading_progress_value):
self.progress_bar = progress_bar
self.youtube_url = youtube_url
self.media_folder = media_folder
self.media_choice = media_choice
self.downloading_progress_value = downloading_progress_value
self.youtube = YouTube(url=youtube_url)
if self.media_choice == "1":
self.youtube_stream = self.youtube.streams.filter(progressive=True,file_extension="mp4").order_by('resolution').desc().first()
self.youtube_stream.download(output_path=self.media_folder,filename=self.youtube_stream.title)
self.max_file_size = self.youtube_stream.filesize
if self.media_choice == "2":
self.youtube_stream = self.youtube.streams.filter(only_audio=True,file_extension="webm").first()
self.youtube_stream.download(output_path=self.media_folder,filename=self.youtube_stream.title)
self.max_file_size = self.youtube_stream.filesize
self.downloading_progress_value.set("Downloading is in progress....")
threading.Thread(target=self.youtube.register_on_progress_callback(self.show_progress)).start()
threading.Thread(target=self.download_file).start()
def show_progress(self,stream=None,chunk=None,file_handle=None,bytes_remaining=None):
self.percent_count = float("%.2f" (100 - ( 100 * (bytes_remaining /self.max_file_size))))
mBox.showinfo("Test 1","test the method 1")
print(self.percent_count)
if self.percent_count < 100:
self.downloading_progress_value.set(str(self.percent_count))
self.progress_bar['value'] = self.percent_count
else:
self.progress_bar.stop()
self.downloading_progress_value.grid_forget()
self.progress_bar.grid_forget()
mBox.showinfo("Test 2","test the method 2")
def download_file(self):
if self.media_choice == "1":
self.youtube_stream = self.youtube.streams.filter(progressive=True,file_extension="mp4").order_by('resolution').desc().first().download(output_path=self.media_folder,filename=self.youtube_stream.title)
if self.media_choice == "2":
self.youtube_stream = self.youtube.streams.filter(only_audio=True,file_extension="webm").first().download(output_path=self.media_folder,filename=self.youtube_stream.title)
mBox.showinfo("Download Finished","Video downloaded successfully")
if __name__ == "__main__":
window = Tk()
window.title("Youtube Downloader")
window.geometry("1020x550+400+210")
window.resizable(0,0)
app = Application(window)
mainloop()
解决方法
在show_progress()
中进行字符串转换时出错。
percent_count = float("%.2f" % (100 - ( 100 * (bytes_remaining/max_file_size))))
# missing -------------------^
您收到此错误吗?还是行得通?如果是这样,您从转化中获得了什么价值?
,def show_progress(self,stream=None,chunk=None,file_handle=None,bytes_remaining=None):
show_progress()
函数应仅接受3个参数-stream
,chunk
和bytes_remaining
,按此顺序。这样做的方式是,pytube将bytes_remaining
参数传递给file_handle
参数。
此外,我认为您应该在计算percent_count的表达式前放置一个'%'字符,像这样-
self.percent_count = float("%.2f" %(100 - ( 100 * (bytes_remaining /self.max_file_size))))
请告知是否可以解决问题。
编辑:我还要指出的另一件事是,即使在注册on_progress_callback或调用download_file()方法之前,DownloadApp类的 init 方法实际上仍会下载文件。这不仅意味着您的进度回调不会在第一次下载时被调用,而且还可以确保也不会在第二次调用时(因为pytube在文件已经存在的情况下会跳过下载)。