下载 YouTube 视频时 python ttkbootstrap 进度条不更新

问题描述 投票:0回答:1

我对编程很生疏,对Python和ttkbootstrap一点也不熟悉,但我尽力了。

我创建了一个小实用程序来下载 YouTube 视频,它基本上可以工作,这意味着它可以下载所选目录中的视频。但是,下载时进度条不会更新,并且百分比文本最后显示 100%,下载时不会更新。

如果您能帮助我改进我的代码,并使事情按照我认为应该的方式工作,我将非常感激...

到目前为止,这是我的代码

import pathlib
from tkinter import ttk
import ttkbootstrap as ttkb
from ttkbootstrap.constants import *
import ttkbootstrap.style 
from tkinter.filedialog import askdirectory
from pytube import YouTube


class DataEntryForm(ttkb.Frame):
    
    def __init__(self, master):
        super().__init__(master, padding=(20,10))
        self.pack(fill =BOTH, expand=YES)
        
        #application variables
        self.repertoireChoisi = ttkb.StringVar()
        #self._path = pathlib.Path().absolute().as_posix()
                                                              
        #form variables
        self.URL = ttkb.StringVar(value="") 
        self.repertoire = ttkb.StringVar(value="" )     
        self.percentage_of_completion = ttkb.StringVar(value="0%")
        
        
        #form header  
        hdr_txt = "Entrez l'URL de la vidéo et le répertoire où les fichiers seront stockés"
        hdr = ttkb.Label(self, text=hdr_txt, width= 100)
        hdr.pack(fill = X, padx=10, pady=10)
        
        #form entries        
        self.create_form_entry("url", self.URL) 
        self.create_progressbar(0)
        self.create_repertoire_entry("repertoire", self.repertoire)
        self.create_buttonbox()
        
    def create_form_entry(self, label, variable):
        """Create a single form entry"""
        container = ttkb.Frame(self)
        container.pack(fill=X, expand=YES, pady=5)

        lbl = ttkb.Label(master=container, text=label.title(), width=10)
        lbl.pack(side=LEFT, padx=5)

        ent = ttkb.Entry(master=container, textvariable=self.URL, width = 80)
        ent.pack(side=LEFT, padx=5, fill=X, expand=YES)
        rep_button = ttkb.Button(
            master = container,
            text = "Télécharger",
            style=SUCCESS,
            command = self.on_download,
            width= 20
        )
        rep_button.pack(side=LEFT, padx=5, fill=X, expand=NO)
        
    def create_repertoire_entry(self, label, variable):
        container = ttkb.Frame(self)
        container.pack(fill=X, expand=YES, pady=5)
        lbl = ttkb.Label(master=container, text="Repertoire", width=10)
        lbl.pack(side=LEFT, padx=5)
        #self.create_form_entry("repertoire", self.repertoire)  
        ent = ttkb.Entry(master=container, width=80, textvariable=variable)        
        ent.pack(side=LEFT, padx=5, fill=X, expand=NO)
        rep_button = ttkb.Button(
            master = container,
            text = "Rechercher",
            style=SUCCESS,
            command = self.on_search,
            width= 20
        )
        rep_button.pack(side=LEFT, padx=5, fill=X, expand=NO)
                    
                    
    def create_progressbar(self, percent):
        """Create a progress bar"""
#        progress = ttkb.Frame(self,style=PRIMARY)
        #container = ttkb.Frame(self)
        progress = ttk.Progressbar(self)
        progress.pack(fill=X,expand=YES, pady=(15,10))
        # self.time_elapsed = ttk.Label(progress, text='00:00', font='Helvetica 12')
        # self.time_elapsed.pack(side='left')
        # self.time_scale = ttk.Scale(progress, orient='horizontal', style='info.Horizontal.TScale')
        # self.time_scale.pack(side='left', expand=True, padx=10)
        # self.time_remaining = ttk.Label(progress, text='00:00', font='Helvetica 12')
        # self.time_remaining.pack(side='right')
        self.percentage_of_completion = ttk.Label(self, width = 40, text=str(percent) + "%")
        self.percentage_of_completion.pack(fill=BOTH, expand=TRUE, padx = 215) 
        
        
    def create_buttonbox(self):
        """Create the application buttonbox"""
        container = ttkb.Frame(self)
        container.pack(fill=X, expand=YES, pady=(15, 10))        

        sub_btn = ttkb.Button(
            master=container,
            text="Envoyer",
            command=self.on_submit,
            style =SUCCESS,
            width=10,
        )
        sub_btn.pack(side=RIGHT, padx=5)
        sub_btn.focus_set()

        cnl_btn = ttkb.Button(
            master=container,
            text="Cancel",
            command=self.on_cancel,
            style=DANGER,
            width=10,
        )
        cnl_btn.pack(side=RIGHT, padx=5) 
        
    def on_submit(self):
        """Print the contents to console and return the values."""
        print("URL:", self.URL.get())
        print("repertoire:", self.repertoire.get())        
        return self.URL.get(), self.repertoire.get()

    def on_cancel(self):
        """Cancel and close the application."""
        self.quit()
        
    def on_search(self):        
        """Search directory where to download the files."""        
        #self.repertoire = askdirectory()
        self.repertoireChoisi.set(askdirectory(
            initialdir="/",
            title="Sélectionnez un répertoire"            
            ) 
        )
        self.repertoire.set(self.repertoireChoisi.get())
        
    def on_download(self):
        """get data from the video and dl it."""
        video = YouTube(self.URL.get())
        filters = video.streams.filter(file_extension='mp4')
        mp4_720 = filters.get_highest_resolution()
        # récupérer les infos de la vidéo ici
        # description = video.description
        # length = video.length # video length in seconds
        video.register_on_progress_callback(self.on_progress)
        mp4_720.download(self.repertoire.get())
        
        
        # filters = video.streams.filter(file_extension='mp4')
        # mp4_1080 = filters.get_highest_resolution()
        # mp4_1080.download(self.repertoire.get(), 'test2.mp4')   
        
    def on_progress(self, stream, chunk, bytes_remaining):
        """Update the progress bar."""
        total_size = stream.filesize
        bytes_downloaded = total_size - bytes_remaining
        self.percentage_of_completion.config(text=str((bytes_downloaded / total_size) * 100))
        


        
       
        
        
if __name__ == "__main__":
    app = ttkb.Window("Téléchargement de Vidéo YouTube", "superhero", resizable=(False, False))
    #app.geometry("500x400")
    DataEntryForm(app)
    app.mainloop()
        

 
    

# root = ttkb.Window(themename="darkly")

# b1 = ttkb.Button(root, text='Bouton Un', bootstyle = SUCCESS)
# b1.pack(side= LEFT, padx=5, pady = 10)

# b2 = ttkb.Button(root, text='Bouton Deux', bootstyle = (INFO, OUTLINE))
# b2.pack(side=LEFT,padx=5, pady =10) 

# root.mainloop()

在此处找到的以下示例中,我尝试了不同的组合来从“on_progress”更新进度条,但我想我遗漏了一些明显的东西。 (或者这应该是显而易见的,但对我来说不是):-)

感谢您的帮助, 伯纳德

python youtube progress-bar
1个回答
0
投票

我终于成功了。 首先,我注册回调的语法不正确。看起来必须这样做:

video = YouTube(self.URL.get(), on_progress_callback=self.on_progress)

而且我不知道进度更新方法

self.progress.update()

所以现在可以正常工作了。需要清理,但这现在是一个可以运行的小实用程序。最终这可以帮助其他人:

import pathlib
from tkinter import ttk
import ttkbootstrap as ttkb
from ttkbootstrap.constants import *
import ttkbootstrap.style 
from tkinter.filedialog import askdirectory
from pytube import YouTube
import time


class DataEntryForm(ttkb.Frame):
    
    def __init__(self, master):
        super().__init__(master, padding=(20,10))
        self.pack(fill =BOTH, expand=YES)
        
        #application variables
        self.repertoireChoisi = ttkb.StringVar()
        self.stuff = ttkb.IntVar()
        #self._path = pathlib.Path().absolute().as_posix()
                                                              
        #form variables
        self.URL = ttkb.StringVar(value="") 
        self.repertoire = ttkb.StringVar(value="" )     
        self.percentage_of_completion = ttkb.StringVar(value="0%")
        
        
        #form header  
        hdr_txt = "Entrez l'URL de la vidéo et le répertoire où les fichiers seront stockés"
        hdr = ttkb.Label(self, text=hdr_txt, width= 100)
        hdr.pack(fill = X, padx=10, pady=10)
        
        #form entries        
        self.create_form_entry("url", self.URL) 
        self.create_progressbar(0)
        self.create_repertoire_entry("repertoire", self.repertoire)
        self.create_buttonbox()
        
    def create_form_entry(self, label, variable):
        """Create a single form entry"""
        container = ttkb.Frame(self)
        container.pack(fill=X, expand=YES, pady=5)

        lbl = ttkb.Label(master=container, text=label.title(), width=10)
        lbl.pack(side=LEFT, padx=5)

        ent = ttkb.Entry(master=container, textvariable=self.URL, width = 80)
        ent.pack(side=LEFT, padx=5, fill=X, expand=YES)
        rep_button = ttkb.Button(
            master = container,
            text = "Télécharger",
            style=SUCCESS,
            command = self.on_download,
            width= 20
        )
        rep_button.pack(side=LEFT, padx=5, fill=X, expand=NO)
        
    def create_repertoire_entry(self, label, variable):
        container = ttkb.Frame(self)
        container.pack(fill=X, expand=YES, pady=5)
        lbl = ttkb.Label(master=container, text="Repertoire", width=10)
        lbl.pack(side=LEFT, padx=5)
        #self.create_form_entry("repertoire", self.repertoire)  
        ent = ttkb.Entry(master=container, width=80, textvariable=variable)        
        ent.pack(side=LEFT, padx=5, fill=X, expand=NO)
        rep_button = ttkb.Button(
            master = container,
            text = "Rechercher",
            style=SUCCESS,
            command = self.on_search,
            width= 20
        )
        rep_button.pack(side=LEFT, padx=5, fill=X, expand=NO)
                    
                    
    def create_progressbar(self, percent):
        """Create a progress bar"""
#        progress = ttkb.Frame(self,style=PRIMARY)
        #container = ttkb.Frame(self)
        self.progress = ttkb.Progressbar(self, style=PRIMARY,maximum = 100.00, mode=DETERMINATE)
        self.progress.pack(fill=X,expand=YES, pady=(15,10))
        # self.time_elapsed = ttk.Label(progress, text='00:00', font='Helvetica 12')
        # self.time_elapsed.pack(side='left')
        # self.time_scale = ttk.Scale(progress, orient='horizontal', style='info.Horizontal.TScale')
        # self.time_scale.pack(side='left', expand=True, padx=10)
        # self.time_remaining = ttk.Label(progress, text='00:00', font='Helvetica 12')
        # self.time_remaining.pack(side='right')
        self.percentage_of_completion = ttk.Label(self, width = 40, text=str(percent) + "%")
        self.percentage_of_completion.pack(fill=BOTH, expand=TRUE, padx = 215) 
        
        
    def create_buttonbox(self):
        """Create the application buttonbox"""
        container = ttkb.Frame(self)
        container.pack(fill=X, expand=YES, pady=(15, 10))        

        sub_btn = ttkb.Button(
            master=container,
            text="Envoyer",
            command=self.on_submit,
            style =SUCCESS,
            width=10,
        )
        sub_btn.pack(side=RIGHT, padx=5)
        sub_btn.focus_set()

        cnl_btn = ttkb.Button(
            master=container,
            text="Cancel",
            command=self.on_cancel,
            style=DANGER,
            width=10,
        )
        cnl_btn.pack(side=RIGHT, padx=5) 
        
    def on_submit(self):
        """Print the contents to console and return the values."""
        print("URL:", self.URL.get())
        print("repertoire:", self.repertoire.get())        
        return self.URL.get(), self.repertoire.get()

    def on_cancel(self):
        """Cancel and close the application."""
        self.quit()
        
    def on_search(self):        
        """Search directory where to download the files."""        
        #self.repertoire = askdirectory()
        self.repertoireChoisi.set(askdirectory(
            initialdir="/",
            title="Sélectionnez un répertoire"            
            ) 
        )
        self.repertoire.set(self.repertoireChoisi.get())
        
    def on_download(self):
        """get data from the video and dl it."""
        video = YouTube(self.URL.get(), on_progress_callback=self.on_progress)
        filters = video.streams.filter(file_extension='mp4')
        mp4_720 = filters.get_highest_resolution()
        # récupérer les infos de la vidéo ici
        # description = video.description
        # length = video.length # video length in seconds
        #video.register_on_progress_callback= self.on_progress
        mp4_720.download(self.repertoire.get())
        
        
        # filters = video.streams.filter(file_extension='mp4')
        # mp4_1080 = filters.get_highest_resolution()
        # mp4_1080.download(self.repertoire.get(), 'test2.mp4')   
        
    def on_progress(self, stream, chunk, bytes_remaining):        
        """Update the progress bar."""
        #percent = (bytes_remaining / stream.filesize) * 100
        
        total_size = stream.filesize
        #self.stuff += chunk
        bytes_downloaded = total_size - bytes_remaining
        self.percentage_of_completion.config(text=str(round((bytes_downloaded / total_size) * 100,2)) + "%")
        self.progress['value'] = round((bytes_downloaded / total_size) * 100,2)
        self.progress.update()            
        
if __name__ == "__main__":
    app = ttkb.Window("Téléchargement de Vidéo YouTube", "superhero", resizable=(False, False))
    #app.geometry("500x400")
    DataEntryForm(app)
    app.mainloop()
    
© www.soinside.com 2019 - 2024. All rights reserved.