pythontkinterpytubecustomtkinter

Progressbar doesn´t update with pytube and tkinter


I have a YouTube Videodownloader with PyTube and customtkinter. I now wanted to have a progressbar that shows the download progress. I then used the on_progress_callback as explained in the PyTube documentation. Everything works when I print the percentage of completeted download. I get something like this in the terminal:

14%

36%

...

Now when I try to set() the Progressbar to the current percentage end then update it with update_idletask(), the Progressbar is completed after only about 20% of the download is completed. I can see this with the print(percentage) in the terminal.

Is there a way to fix this? Here´s my code:

import customtkinter as ctkt
from pytube import YouTube
import os

path = os.getcwd()

ctkt.set_appearance_mode("dark")
ctkt.set_default_color_theme("dark-blue")

root = ctkt.CTk()
root.geometry("500x500")
root.title("Youtube Downloader")
root.resizable(False, False)

progress = ctkt.CTkProgressBar(master=root)
progress.set(0)

def progress_func(stream, chunk, bytes_remaining):
    """Callback function"""
    total_size = stream.filesize
    bytes_downloaded = total_size - bytes_remaining
    pct_completed = bytes_downloaded / total_size * 100
    percent_status = round(pct_completed, 0)
    percent_int = int(percent_status)
    progress.set(percent_int)
    progress.update_idletasks()
    print(percent_int)



def downloadVid():
    try:
        ytLink = link.get()
        ytObject = YouTube(ytLink, on_progress_callback=progress_func)


        video = ytObject.streams.get_highest_resolution()
        video.download()
        succeededMessage = ctkt.CTkLabel(master=root, text="[+] Dowload Complete")
        succeededMessage.pack()



    except:
        errorMessage = ctkt.CTkLabel(master=root, text="[-] This Link Is Invalid")
        errorMessage.pack()



link = ctkt.CTkEntry(master=root, width=300, height=20, placeholder_text="Paste the video link here...")
link.pack(pady=15, padx=15)



dowloadBtn = ctkt.CTkButton(master=root, command=downloadVid, text="Download")
dowloadBtn.pack(pady=15, padx=15)

def open_videos():
    os.startfile(path)

open_folder = ctkt.CTkButton(master=root, command=open_videos, text="Saved videos")
open_folder.pack()

progress.pack(pady=20, padx=20)




root.mainloop()


Solution

  • According to the official document on CTkProgressBar.set(), it accepts values from 0 to 1.

    So the value passed to it should be bytes_download/total_size:

    def progress_func(stream, chunk, bytes_remaining):
        """Callback function"""
        total_size = stream.filesize
        bytes_downloaded = total_size - bytes_remaining
        pct_completed = bytes_downloaded / total_size
        progress.set(pct_completed)
        progress.update_idletasks()
        print(f"{int(pct_completed*100)}%")