Прогресс в Pytube показывает только 99 и 100

#python #youtube #pytube

Вопрос:

Я пытаюсь показать прогресс в pytube во время загрузки видео. но он показывает только 99 и 100, а затем завершен.

Вот мой код:

 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=qxYbHzn8bbUamp;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())
 

Выход:

 99
100
Completed
 

Спасибо!

Комментарии:

1. возможно, видео слишком короткое, и оно загружается одним куском. Вы проверяли, какой большой файл вы получаете?

2. Размер файла составляет 9 МБ.

3. это очень маленький файл. Попробуйте что — нибудь гораздо более продолжительное.

4. или вам следует выбрать другой формат, потому что ваш код всегда загружается, .3gpp и это всегда очень маленький файл.

5. попробуйте video = yt.streams[2] или video = yt.streams.get_highest_resolution() вместо video = yt.streams.first() этого, и он загрузит .mp4 то, что есть 45MB , и отобразит 20%, 40%, 60%, 80%, 100%

Ответ №1:

Покопавшись в исходном коде, который я нашел в строке запроса pytube.

 default_range_size = 9437184  # 9MB
 

который используется в качестве размера блока в строках

 stop_pos = min(downloaded   default_range_size, file_size) - 1
range_header = f"bytes={downloaded}-{stop_pos}"
 

таким образом, он загружается 9MB одним куском.

Вы загружаете файл, который имеет только ~9MB то, что он загружает почти все в одном куске, и он может отображать только 99% или 100% .

Если вы попытаетесь использовать более длинный файл с помощью

 video = yt.streams[2] 
# or 
video = yt.streams.get_by_itag(22)
# or
video = yt.streams.get_highest_resolution()
 

затем он загрузится ~45MB и отобразится 20%, 40%, 60%, 80%, 100%


Возможно, если бы вы могли изменить default_range_size значение на меньшее, оно также отображало бы процент для файлов меньшего размера, но я думаю, что его нужно было бы изменить непосредственно в исходном коде, поэтому вы не можете сделать это простым способом.


Минимальный рабочий код — с другими небольшими изменениями.

Я использую

  • f'{percent:.0%}' чтобы отобразить 0.20 как 20% так, мне не нужно вычислять его как самостоятельно,
  • f'{max_file_size:_}' для отображения размера как 104_465_890 вместо 104465890 ,
  • end='r' чтобы отобразить процент в той же строке и заменить предыдущее значение.
 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)