How to Create a Simple YouTube Download Program with a Progress Indicator in Python 3 with pytube

Python 3, pytube, os in Windows 10

Some of my friends live in an area that really struggles to get decent internet speeds in the afternoons and evenings. So much so that they can barely watch a YouTube video at 144p some days, and that is not particularly useful if they are trying watch a video with code or some technical specs on the screen.

They really needed to download the videos, but really did not trust the programs available online to download videos for me without spamming them with advertising or adding some malicious malware to their beloved computers.

Fortunately, someone developed a Python 3 library to do just that – pytube.  In an earlier post I dive into some of the main aspects pytube:

How do I download YouTube videos with Python 3 using Pytube?

In this post I am going to show you a quick app that can be run in the Python shell to download videos that features a progress indicator (not quite a progress bar).

I’ve intentional kept the program fairly limited so you can focus on the important parts. I’ll show you the code and an example of what it looks like when it is running first and then give you the breakdown where you can focus on what you need to know and ignore the rest.

The Code

The Program Running



First we grab the YouTube module from the pytube library in line 9. We will also need the os library to work with file locations (line 10).

Before we run the start function, that erh…starts the program, we will create a global variable for file_size that will change later once we have the data (line 54-55).


The start function does the main work of running the program. On line 25 we inform the user where the file will be saved to. The curly brackets “{}” are a placeholder for whatever goes in the .format(something).  In our case it is the file_path function that will find the users file path to their Downloads folder.

Lines 27-29 gather the YouTube url (we hope) prints it out for the users reference and then informs the user why they are waiting so long.

Lines 32-36 asks pytube to try and find the YouTube url. It also does something special. on_progress_callback allows us to create a callback function, in our case progress_check, that will give us some values to create our progress indicator.

We use try and except here to cover a whole variety of sins. But essentially, if the user puts in a url that does not point to a YouTube video or just any old gibberish then the exception will be called and the whole process with start() again. The exception might also be called if the user does not have an internet connection or even sometimes when YouTube gets sick of you running test programs and blocks you for a little while – it happened.

Next we are evaluating the possible video types that YouTube can provide (I covered this in an earlier post here). I filter out all the possible video types by progressive and with a mp4 file extension. We take the first one of these options which will be the one with the best resolution.

I can use the video variable that we created in line 33 to also grab the title of the video with the um…video.title method in line 42. We then go on to print the title and inform the user that we are getting the file for download.

On line 46-47 it’s time to update the file_size of the video we selected by using the .filesize method once we have decided on our video back in video_type.

Finally we get around to what we came here to do, download the video in line 49. While the video is downloading, callbacks will be made to help us update our progress indicator.

We then start all over again by calling the start() function on line 52.



This function will take four parameters from pytube on_progress_callback method:

  • stream: the stream we chose. In our case the best resolution for an mp4 video.
  • chunk: the different packets of data that are downloading.
  • file_handle: the location the the file will go in.
  • remaining: how many bytes remaining.

This is all gathered automatically by pytube and we don’t have to put any values in here.

For our purposes we are going to only use the remaining value. On line 15 we get the percentage of what has be downloaded by subtracting the file_size by the remaining bytes, dividing it by the file_size and then multiplying it by 100.

This will result in a number will a large tail of decimals. We really don’t need that so I did some snazzy format work to only show the percentage as a whole number (line 16).

progress_check will then be called as the file downloads.


In the file_path function we look for the users home director on line 20 and then join that to the Downloads so we can form the path to the users download file. Like this:


There is a lot more on this in an earlier post:

How to Check a Users Home Directory for a Folder – Python 3


This is a very basic example. There is no option to change the download file location or to change to another file format. We could also add he option to download audio only or download a whole playlist with the help of pytube.




Leave a Reply

Your email address will not be published. Required fields are marked *