You now have a free, open-source, and powerful YouTube playlist downloader. But with great power comes great responsibility.
Use your script to create offline archives of knowledge, to help students in areas with poor internet, or to preserve content that might be deleted. That is the ethical sweet spot.
Important: Downloading videos from YouTube may violate YouTube's Terms of Service unless you are downloading your own content or have permission from the copyright holder. Always:
This script is for educational purposes and personal backups of freely available content.
Before we write the script, you need to install the library. Open your terminal or command prompt and run:
pip install pytube
ydl_opts =
'format': 'bestvideo[height<=1080]+bestaudio/best[height<=1080]',
'merge_output_format': 'mp4',
'outtmpl': f'output_path/%(playlist_title)s/%(playlist_index)s - %(title)s.%(ext)s',
First, ensure Python 3.8+ is installed on your system (Windows, macOS, or Linux).
Often, you want only the audio (for music playlists) or need to download high-resolution videos (1080p, 4K) which require merging separate audio and video streams. Here's an enhanced script.
# advanced_playlist_downloader.pyfrom pytube import Playlist, YouTube import os import sys
def download_video(youtube_url, output_path, download_type="video"): """ Downloads a single video based on type. Types: 'video' (highest progressive), 'audio' (highest bitrate audio), 'highres' (1080p+ with merge) """ try: yt = YouTube(youtube_url, on_progress_callback=on_progress) print(f" Title: yt.title")
if download_type == "audio": # Get the highest bitrate audio-only stream stream = yt.streams.get_audio_only() out_file = stream.download(output_path=output_path) # Change extension to .mp3 (or keep .mp4) base, ext = os.path.splitext(out_file) new_file = base + '.mp3' os.rename(out_file, new_file) return True elif download_type == "highres": # For 1080p/4K: download video-only and audio-only, then merge (requires ffmpeg) video_stream = yt.streams.filter(adaptive=True, mime_type="video/mp4", res="1080p").first() audio_stream = yt.streams.get_audio_only() if video_stream and audio_stream: video_file = video_stream.download(output_path=output_path, filename_prefix="video_") audio_file = audio_stream.download(output_path=output_path, filename_prefix="audio_") # Merge logic using ffmpeg (omitted for brevity, but can be implemented) print(" Merge required with ffmpeg.") return True else: print(" High-res streams not available. Falling back to progressive.") return download_video(youtube_url, output_path, "video") else: # Default: best progressive (up to 720p) stream = yt.streams.get_highest_resolution() stream.download(output_path=output_path) return True except Exception as e: print(f" Error: e") return Falsedef on_progress(stream, chunk, bytes_remaining): total_size = stream.filesize bytes_downloaded = total_size - bytes_remaining percentage = (bytes_downloaded / total_size) * 100 print(f"\r Progress: percentage:.2f%", end="")
def main(): print("=== YouTube Playlist Downloader (Advanced) ===") playlist_url = input("Enter playlist URL: ").strip() download_type = input("Download type? (video/audio/highres): ").strip().lower() output_dir = input("Output directory (default: ./downloads): ").strip() or "./downloads"
if not os.path.exists(output_dir): os.makedirs(output_dir) try: pl = Playlist(playlist_url) print(f"\nPlaylist: pl.title (len(pl.video_urls) videos)\n") for idx, url in enumerate(pl.video_urls, 1): print(f"[idx/len(pl.video_urls)] Processing...") success = download_video(url, output_dir, download_type) if not success: print(f" Failed: url") print("-" * 40) print("\n✅ All done!") except Exception as e: print(f"Failed to load playlist: e") sys.exit(1)
if name == "main": main()
python yt_playlist_dl.py "PLAYLIST_URL" --quality 720 --output ./my_videos
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.