1

I am using tkinter to make an application with youtube_dl. I have been having a lot of problems with a progress bar that shows the download progress. What it does is that it updates a couple of times during the first few percent then doesn't update again until the download has finished. Here is my code:

from tkinter import Tk, Label, Button, Entry, X

import tkinter
from tkinter import ttk
from tkinter import messagebox
import youtube_dl, multiprocessing





class Application(tkinter.Frame):
    def __init__(self, master=None):
        super().__init__()
        tkinter.Frame.__init__(self, master)
        self.pack()

        
        

        


        lbl = ttk.Label(self, text="Enter URL:")
        lbl.pack(fill=X)
        

        self.etr = ttk.Entry(self)
        self.etr.pack(fill=X)

        btn2 = ttk.Button(self, text="Download!", command=self.dnlURL)
        btn2.pack(fill=X)

        
        self.pb = ttk.Progressbar(self, length=300)
        self.pb.pack()
        
        '''
        ttk.Label(self, text='Select theme:').pack(pady=[50, 10])

        self.style = ttk.Style()
        self.combo = ttk.Combobox(self, values=self.style.theme_names())
        self.combo.pack(pady=[0, 10])
        button = ttk.Button(self, text='Apply')
        button['command'] = self.change_theme
        button.pack(pady=10)
        '''
        
            
        

    def callable_hook(self, response):
        if response["status"] == "downloading":
            #speed = response["speed"]
            downloaded_percent = (response["downloaded_bytes"]*100)/response["total_bytes"]
            self.pb["value"] = downloaded_percent
            self.update_idletasks()
            #youtube_dl.YoutubeDL.add_progress_hook()



        if response["status"] == "downloading":
            #speed = response["speed"]

            downloaded_percent = (response["downloaded_bytes"]*100)/response["total_bytes"]
            self.pb["value"] = downloaded_percent
            self.update_idletasks()
            return
            

    

    def button_press(self):
        print("pressed")



    def dnlURL(self):
        self.ydl_opts = {
            'format': 'bestaudio/best',
            'postprocessors': [{
                'key': 'FFmpegExtractAudio',
                'preferredcodec': 'mp3',
                'preferredquality': '192',
            }],
            "progress_hooks": [self.callable_hook,]
        }
        url = self.etr.get()

        with youtube_dl.YoutubeDL(self.ydl_opts) as ydl:
            
            ydl.download([url])
            
            
            
            #print(self.callable_hook())

    #def dnlPB(self):
        #p1 = multiprocessing.Process(target=self.dnlURL)
        #p1.start()
        #self.dnlURL()
        #while self.callable_hook() < 100:
            #self.progress = self.callable_hook()
            #self.update_idletasks()

            


root = tkinter.Tk()
root.title("YouTube Audio Downloader")
app = Application(master=root)


app.mainloop()

If you have any idea on how to make it update more often that would be good. I am open to doing it another way if that's what it takes.

Art
  • 2,836
  • 4
  • 17
  • 34
mumblety
  • 11
  • 1
  • Looking at the source code of yt-dl, there are a few places where yt-dl can call the progress hook, depending on the filetype. Could you provide the call stack when your progress hook gets called? Example of how to do this: https://stackoverflow.com/questions/1156023/print-current-call-stack-from-a-method-in-python-code – Nick ODell Oct 25 '21 at 04:58

0 Answers0