How to add "pytube" downloading info to tqdm Progress Bar?

Question:

I am trying make a YouTube video downloader.
I want make a progress bar while downloading the YouTube video but I cant get any info (how many MB have been downloaded or how many video MB).
I don’t know if this is possible with python or not. Here is my code so far:

import time , os
from pytube import YouTube
from tqdm import tqdm


al = str(input("C4ommand:"))


if al == "4":
    af = input("Link:")
    you = YouTube(af)

    try:
        os.mkdir("Download")
    except:
        pass

    time.sleep(2)
    time.sleep(1)
    res = you.streams.get_highest_resolution()
    a = res.download()
    with tqdm(total=100) as pbar:
        for i in range(10):
            time.sleep(0.5)
            pbar.update(10)
    print(af + "Link downloading....")
    b = open("Download", "w")
    b.write(a)
    b.close()
    print("Downloaded")
Asked By: W3gor

||

Answers:

To access the progress of the download, you can use the on_progress_callback argument when creating a YouTube instance.

The pytube quickstart says the following:

The on_progress_callback function will run whenever a chunk is downloaded from a video, and is called with three arguments: the stream, the data chunk, and the bytes remaining in the video. This could be used, for example, to display a progress bar.

from pytube import Stream
from pytube import YouTube
from tqdm import tqdm


def progress_callback(stream: Stream, data_chunk: bytes, bytes_remaining: int) -> None:
    pbar.update(len(data_chunk))


url = "http://youtube.com/watch?v=2lAe1cqCOXo"
yt = YouTube(url, on_progress_callback=progress_callback)
stream = yt.streams.get_highest_resolution()
print(f"Downloading video to '{stream.default_filename}'")
pbar = tqdm(total=stream.filesize, unit="bytes")
path = stream.download()
pbar.close()
print(f"Saved video to {path}")

Sample output:

Downloading video to 'YouTube Rewind 2019 For the Record  YouTubeRewind.mp4'
100%|██████████████████████████████| 87993287/87993287 [00:17<00:00, 4976219.51bytes/s]
Saved video to /tmp/testing/YouTube Rewind 2019 For the Record  YouTubeRewind.mp4

Pytube has a built-in progress bar, but it does not use tqdm. Please see https://stackoverflow.com/a/60678355/5666087 for more information.

Answered By: jkr

This is what you want. I made it just now and it can be documented a bit better:

from tqdm import tqdm
from pytube import Stream, YouTube

class TqdmForPyTube(tqdm):

    def on_progress(self, stream: Stream, chunk: bytes, bytes_remaining: int):
        """
        :param stream: pytube object.
        :param bytes chunk: segment of media file binary data,
            not yet written to disk.
        :param int bytes_remaining: the delta between the total file size
            in bytes and amount already downloaded.
        """
        self.total = stream.filesize
        bytes_downloaded = self.total - bytes_remaining
        return self.update(bytes_downloaded - self.n)

And to use it, as explain in the tqdm documentation:

with TqdmForPyTube(unit='B', unit_scale=True, unit_divisor=1024, delay=2) as t:
    print('downloading video...')
    YouTube(video_url, on_progress_callback=t.on_progress).
            streams.filter(...).download(output_path=output_path)
    print(video downloaded')

I used the delay=2 argument to avoid printing the first null tqdm iteration in the case you want to print something in console before calling the download function, as in the line print('downloading video...'), but it’s not needed otherwise.

Answered By: Carlos P
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.