Reputation: 728
I am trying to show progress in pytube while its downloading a video. but it only shows 99 and 100, and then Completed.
Here is my code:
from pytube import YouTube
import os
max_file_size = 0
def on_progress(stream, data_chunk, bytes_remaining):
percent = int(100 - (100 * (bytes_remaining/max_file_size)))
print(percent)
def on_comp(stream, path):
print('Completed')
yt = YouTube('https://www.youtube.com/watch?v=qxYbHzn8bbU&t=84s',
on_progress_callback=on_progress, on_complete_callback=on_comp)
video = yt.streams.first()
max_file_size = video.filesize
video.download(os.getcwd())
Output:
99
100
Completed
Thanks!
Upvotes: 0
Views: 773
Reputation: 142641
Digging in source code I found in pytube.request line
default_range_size = 9437184 # 9MB
which is used as chunk size in lines
stop_pos = min(downloaded + default_range_size, file_size) - 1
range_header = f"bytes={downloaded}-{stop_pos}"
so it download 9MB
in one chunk.
You download file which has only ~9MB
so it downloads almost all in one chunk and it can display only 99%
or 100%
.
If you try with longer file using
video = yt.streams[2]
# or
video = yt.streams.get_by_itag(22)
# or
video = yt.streams.get_highest_resolution()
then it will download ~45MB
and it will display 20%, 40%, 60%, 80%, 100%
Maybe if you could change default_range_size
into smaller value then it will display percent for smaller files too - but I think it would need to change it directly in source code, so you can't do it in easy way.
Minimal working code - with other small changes.
I use
f'{percent:.0%}'
to display 0.20
as 20%
so I don't have to calculate it as on my own,f'{max_file_size:_}'
to display size as 104_465_890
instead of 104465890
,end='\r'
to display percent in in the same line and replace previous value.from pytube import YouTube
def on_progress(stream, data_chunk, bytes_remaining):
#print('bytes_remaining:', bytes_remaining)
downloaded = max_file_size - bytes_remaining
percent = downloaded/max_file_size
print(f'Downloaded: {percent:.0%}', end='\r')
def on_complete(stream, path):
print('Completed:', path)
# --- main ---
url = 'https://www.youtube.com/watch?v=aqz-KE-bpKQ' # "Big Buck Bunny" ~100MB
#url = 'https://www.youtube.com/watch?v=qxYbHzn8bbU' # ~45MB
yt = YouTube(url,
on_progress_callback=on_progress,
on_complete_callback=on_complete)
#for item in yt.streams:
# print(item)
#video = yt.streams[2]
#video = yt.streams.get_by_itag(22)
video = yt.streams.get_highest_resolution()
max_file_size = video.filesize
print(f'Size: {max_file_size:_} bytes')
video.download(skip_existing=False)
Upvotes: 2