-1

I have a working pytube script but am struggling a little with where the extra pieces of code should go to create the progress bar.

#! usr/bin/python3

import sys
from pytube import YouTube

if len(sys.argv) < 2:
    print('Argument 1 must be the YouTube URL. Argument 2 must be a location to save it.')

yt = YouTube(sys.argv[1])

print()
print("Knocking on YouTube's Door....")
print(f'Downloading: {yt.title}')
print()

yt = YouTube(sys.argv[1]).streams.first().download(sys.argv[2])

print('Download Complete!')
balter
  • 25
  • 1
  • 9

3 Answers3

1

I managed to make a nice and simple progress function, with only a few lines of code:

def progress_func(stream, chunk, bytes_remaining):
    curr = stream.filesize - bytes_remaining
    done = int(50 * curr / stream.filesize)
    sys.stdout.write("\r[{}{}] ".format('=' * done, ' ' * (50-done)) )
    sys.stdout.flush()

Then use this function when creating a YouTube object

YouTube(url, on_progress_callback=progress_func)

This way, we'll get a progress bar similar to the one below, filling up

[===================================               ]
VanDavv
  • 836
  • 2
  • 13
  • 38
0

You should call register_on_progress_callback(func) on your YouTube object, where func is a function, that takes stream, chunk, file_handle and bytes_remaining as parameters. For your code it would be:

def on_progress(stream, chunk, file_handle, bytes_remaining):
    total_size = stream.filesize
    bytes_downloaded = total_size - bytes_remaining 
    percentage_of_completion = bytes_downloaded / total_size * 100

yt.register_on_progress_callback(on_progress)

Then you have to use percentage_of_completion variable to draw the progress bar, but it's a little bit out of the scope of this question. Remember on_progress function will be called each time chunk will be downloaded. I hope now you will be able to make what you wanted.

Gieted
  • 835
  • 6
  • 21
  • Thanks for the tip... I thought thats what I had to do, but I am unsure where to put the code and where to call the function... – balter Apr 17 '19 at 21:35
  • @a5pire You can add call it right before downloading. – Gieted Apr 17 '19 at 21:44
  • Again, thats what I thought, however when I run the code, the file still downloads but theres no sign of the progress bar. What am I missing? – balter Apr 17 '19 at 22:47
  • Have you checked if the on_progress function is called? – Gieted Apr 18 '19 at 15:57
  • I have it sorted - In your code above there is no print function so nothing prints to the screen.... I added the last line within your function print(percentage_of_completion) Thanks :) – balter Apr 18 '19 at 21:55
0

got the same problem, i have tested all your solution but nothing work for me :/ here is my code :

#importing libraries
from pytube import YouTube
from pytube.cli import on_progress
from customtkinter import *

#set the color theme
set_appearance_mode("System")
set_default_color_theme("blue")

# set the window
root = CTk()
root.title("Youtube Audio Downloader")
root.geometry("400x400")
root.iconbitmap("./assets/icone_ytb.ico")

#label
label = CTkLabel(root, text = "Entrez l'url de votre vidéo :", width = 250)
label.place(relx = 0.5, rely = 0.32, anchor = CENTER)

# input field
input = CTkEntry(master = root, width = 250, border_width = 0)
input.bind("<Button-1>", lambda e: input.delete(0, END))
input.place(relx = 0.5, rely = 0.4, anchor = CENTER)

# progress bar
progress_bar = CTkProgressBar(root, orient = 'horizontal')
progress_bar.place(relx = 0.5, rely = 0.58, anchor = CENTER)
progress_bar.set(0.0)

def on_complete(stream, file_path) :
    print("Done !")

def on_progress(stream, chunk, file_handle, bytes_remaining):
    total_size = stream.filesize
    bytes_downloaded = total_size - bytes_remaining
    percentage_of_completion = bytes_downloaded / total_size * 100

#function that download the video
def telecharger() :
    url = str(input.get())
    path = "./audios"
    youtube = YouTube(url)
    youtube.register_on_progress_callback(on_progress)
    video = youtube.streams.get_highest_resolution()
    video.download(path)
    progress_bar.set(1)

# button
btn = CTkButton(master = root, text = "Valider", command = telecharger, width = 250)
btn.place(relx = 0.5, rely = 0.5, anchor = CENTER)

#run the window
root.mainloop()