Youtube Playlist Free Downloader Python Script May 2026

Run:

pip install yt-dlp tqdm
#!/usr/bin/env python3
"""
youtube_playlist_downloader.py
Downloads all videos from a YouTube playlist using yt-dlp.
Usage:
    python youtube_playlist_downloader.py PLAYLIST_URL /path/to/output_dir
"""
import sys
import os
import time
import argparse
from yt_dlp import YoutubeDL
from yt_dlp.utils import sanitize_filename
def parse_args():
    p = argparse.ArgumentParser(description="Download all videos from a YouTube playlist.")
    p.add_argument("playlist_url", help="YouTube playlist URL")
    p.add_argument("output_dir", nargs="?", default=".", help="Directory to save videos")
    p.add_argument("--format", default="mp4", help="Container format (mp4/mkv/webm). yt-dlp will pick best video+audio.")
    p.add_argument("--sleep", type=float, default=0.5, help="Seconds to sleep between downloads")
    p.add_argument("--retries", type=int, default=3, help="Retries per video on failure")
    return p.parse_args()
def ensure_dir(path):
    os.makedirs(path, exist_ok=True)
    return os.path.abspath(path)
def build_outtmpl(output_dir):
    # Keep playlist index prefix for ordering
    return os.path.join(output_dir, "%(playlist_index)03d - %(title)s.%(ext)s")
def download_playlist(url, output_dir, fmt="mp4", sleep=0.5, retries=3):
    outtmpl = build_outtmpl(output_dir)
    ydl_opts = 
        "format": f"bestvideo[ext!=webm]+bestaudio/best",
        "outtmpl": outtmpl,
        "merge_output_format": fmt,
        "noplaylist": False,
        "ignoreerrors": True,
        "continuedl": True,
        "nooverwrites": False,
        "writesubtitles": False,
        "quiet": True,
        "progress_hooks": [progress_hook],
        # Restrict filenames to safe chars
        "restrictfilenames": False,
        "allow_unplayable_formats": False,
attempts = {}
    with YoutubeDL(ydl_opts) as ydl:
        info = ydl.extract_info(url, download=False)
        if not info:
            print("Failed to fetch playlist info.")
            return
        entries = info.get("entries") or [info]
        print(f"Found len(entries) entries in playlist.")
        for i, entry in enumerate(entries, start=1):
            if entry is None:
                print(f"[i] Skipping unavailable entry.")
                continue
            video_url = entry.get("webpage_url") or entry.get("url")
            title = entry.get("title") or f"video_i"
            index = entry.get("playlist_index") or i
            safe_title = sanitize_filename(title)
            ext = fmt
            filename = f"index:03d - safe_title.ext"
            outpath = os.path.join(output_dir, filename)
            if os.path.exists(outpath):
                print(f"[index] Already downloaded: filename")
                continue
attempt = 0
            while attempt < retries:
                attempt += 1
                try:
                    print(f"[index] Downloading (attempt/retries): title")
                    ydl.download([video_url])
                    # Small pause to be polite
                    time.sleep(sleep)
                    break
                except Exception as e:
                    print(f"[index] Error on attempt attempt: e")
                    if attempt >= retries:
                        print(f"[index] Failed after retries attempts, skipping.")
                    else:
                        time.sleep(2 ** attempt)
        print("Done.")
def progress_hook(d):
    if d.get("status") == "downloading":
        eta = d.get("eta")
        speed = d.get("speed")
        downloaded = d.get("downloaded_bytes", 0)
        total = d.get("total_bytes") or d.get("total_bytes_estimate")
        pct = ""
        if total:
            pct = f"downloaded/total*100:5.1f%"
        print(f"Downloading: d.get('filename','') pct ETA:eta speed:speed", end="\r")
    elif d.get("status") == "finished":
        print(f"\nFinished downloading: d.get('filename')")
if __name__ == "__main__":
    args = parse_args()
    out = ensure_dir(args.output_dir)
    download_playlist(args.playlist_url, out, fmt=args.format, sleep=args.sleep, retries=args.retries)

If you need 1080p/4K video or just want to extract MP3 audio, pytube handles that too.

Warning: Downloading videos may violate YouTube’s Terms of Service and copyright law if you don’t have permission from the rights holder. Use this script only for videos you own or that are explicitly licensed for download. youtube playlist free downloader python script

Let’s start with a minimal script that downloads an entire YouTube playlist as the best available quality (audio + video).

Create a file named playlist_downloader.py: Run: pip install yt-dlp tqdm

import yt_dlp

def download_playlist(playlist_url, output_path="./downloads"): """ Downloads an entire YouTube playlist to the specified output path. """ ydl_opts = 'outtmpl': f'output_path/%(playlist_title)s/%(playlist_index)s - %(title)s.%(ext)s', 'ignoreerrors': True, # Skip videos that fail 'quiet': False, # Show progress 'no_warnings': False,

with yt_dlp.YoutubeDL(ydl_opts) as ydl:
    try:
        ydl.download([playlist_url])
        print(f"\n✅ Playlist successfully downloaded to output_path")
    except Exception as e:
        print(f"❌ Error: e")

if name == "main": url = input("Enter YouTube Playlist URL: ").strip() download_playlist(url) If you need 1080p/4K video or just want

Run it:

python playlist_downloader.py

This script will create a folder named after the playlist and save each video as 1 - First Video.mp4, 2 - Second Video.mp4, etc.

import tkinter as tk
from tkinter import messagebox
from pytube import Playlist
class YouTubePlaylistDownloader:
    def __init__(self):
        self.window = tk.Tk()
        self.window.title("YouTube Playlist Downloader")
self.playlist_url_label = tk.Label(self.window, text="Enter the YouTube playlist URL:")
        self.playlist_url_label.pack()
self.playlist_url_entry = tk.Entry(self.window, width=50)
        self.playlist_url_entry.pack()
self.download_button = tk.Button(self.window, text="Download", command=self.download_playlist)
        self.download_button.pack()
def download_playlist(self):
        playlist_url = self.playlist_url_entry.get()
        playlist = Playlist(playlist_url)
        for video_url in playlist.video_urls:
            video = pytube.YouTube(video_url)
            video.streams.get_highest_resolution().download()
        messagebox.showinfo("Success", "Playlist downloaded successfully!")
def run(self):
        self.window.mainloop()
if __name__ == "__main__":
    downloader = YouTubePlaylistDownloader()
    downloader.run()