Download YouTube Videos from any Playlist [Python + Pytube]

Automate and download all videos from any YouTube playlist of your choice.

Harsha Nanayakkara
4 min readJul 1, 2022

Most of the time, I am using YouTube to learn new stuff and I usually tend to download complete playlists so that I am able to refer them offline later. However, I was having great difficulty to find a way to download all videos in a playlist at once until TODAY! After much research I have found a solution with the help of Python’s Pytube library. While there can be many alternative ways to do this, in this article, I will show you how I managed to accomplish the task.

This code covers the below use-cases;

  • It is designed to capture and download all videos available in a playlist once the playlist URL is provided.
  • The code downloads progressive MP4 files.
  • It prioritizes the download of 480p videos. If not found it will check for 720p and finally for 360p.
  • The files will be downloaded to the current working directory.
  • Outputs number of videos in the playlist, video title, video quality which automatically selected for download, file size, download progress / status, download path and remaining video counter.

Now let me explain the code.

from pytube import YouTube
from pytube import Playlist

First of all, we need to import the Youtube and Playlist classes from pytube so that we can use them later on.

#Gives download progress
def on_progress(stream, chunk, bytes_remaining):
progress = f"{round(100 - (bytes_remaining/stream.filesize * 100),2)}%"
print(f"progress: {progress}")
#Do this on download completion
def on_complete(stream, file_path):
print("Download Completed")
print(f"Download path: {file_path}")

After importing the classes, I have defined 02 functions to get the download progress and completion, so that we can use them as we move on with the code.

def on_progress(stream, chunk, bytes_remaining): calculates the progress as a percentage during the download. The progress is rounded to 02 decimal points for better readability.

def on_complete(stream, file_path): prints out the path where the file got downloaded.

#get playlist url from user
pl_url = input("Please enter Playlist URL:\n")
#Create Playlist obj
pl = Playlist(pl_url)

Here, I am taking the playlist URL as user input and create new Playlist object with it.

#Num of videos in playlist
video_count = pl.length
remaining_video_count = 0
print(f"Number of videos in the playlist: {video_count}")
print("Download started...")

In this part, the number of videos available in the Playlist is calculated. Also, remaining_video_count variable is set and assigned zero for later use. Thereafter, video count and download start message is displayed for user.

Next part of the code has a for loop to iterate over each and every video of the entire playlist.

#for every video in the playlist
for vids in pl.videos:

vid_url = vids.watch_url
yt = YouTube(url = vid_url, on_progress_callback=on_progress, on_complete_callback=on_complete) #create YouTube obj
res_480p = yt.streams.get_by_resolution('480p')
res_720p = yt.streams.get_by_resolution('720p')
res_360p = yt.streams.get_by_resolution('360p')

Video URL is assigned to the variable vid_url which is then passed to YouTube class as the URL. Additionally, on_progress_callback and on_complete_callback parameters are set to the functions declared above appropriately. YouTube object is created as yt . Then 03 variables are declared according to the resolution. For instance, yt.streams.get_by_resolution(‘480p’) gets the streams with 480p resolution. However, Stream must be a progressive mp4 for us to use this function. More about streams can be found here.

if(res_480p and yt.streams.filter(file_extension='mp4', progressive=True)): #if the resolution match 480p
title = yt.title
print(f"Video title: {title}")
print("Video download quality: 480p")
file_size = round((res_480p.filesize / 1000000), 2)
print(f"File Size: {file_size} MB")
res_480p.download()
remaining_video_count += 1
print("\n")

There are if statements withing for loop to check my conditions. First if checks whether there are any video matches for 480p resolution and progressive MP4. If yes, it will display the video title, quality and file size in MB. Finally, it downloads the YouTube video and increments the remaining_video_count by 1.

elif(res_720p and yt.streams.filter(file_extension='mp4', progressive=True)): #if the resolution match 720p
title = yt.title
print(f"Video title: {title}")
print("Video download quality: 720p")
file_size = round((res_720p.filesize / 1000000), 2)
print(f"File Size: {file_size} MB")
res_720p.download()
remaining_video_count += 1
print("\n")

If the first condition is false, then it checks for any 720p videos available in the Playlist and perform the same tasks as the previous if statement.

elif(res_360p and yt.streams.filter(file_extension='mp4', progressive=True)): #if the resolution match 360p
title = yt.title
print(f"Video title: {title}")
print("Video download quality: 360p")
file_size = round((res_360p.filesize / 1000000), 2)
print(f"File Size: {file_size} MB")
res_360p.download()
remaining_video_count += 1
print("\n")
else:
print("Low quality video. No video will be downloaded")

The final if statement will check for 360p videos if both previous if statements were false. If none of the if conditions are met the else part will get executed and no video will be downloaded.

print(f"Remaining: {remaining_video_count} out of {video_count}")

As the last print statement inside the for loop it displays the remaining video count out of all videos. For instance, if the Playlist has 5 videos in total, it will display as Remaining: 1 out of 5, Remaining: 2 out of 5 and so on.

This completes the code and voila, now we can easily download full Playlists in YouTube.

You can see the code in GitHub. Please feel free to use the code to suit your particular needs.

Sample output for a particular YouTube Playlist download can be shown as below.

Sample output of the code after running it to download videos inside a Playlist

I sincerely hope this will help you to make your lives easier.

For more details on Pytube library please refer the official documentation.

Thank you for reading and stay safe!

--

--

Harsha Nanayakkara

An enthusiastic autodidact who is passionate to gain and freely share knowledge. I would really appreciate your feedback and support!