PYPL2MP3 is a Python program that one-shot downloads audio from entire YouTube playlists and saves the tracks in MP3 format with shazam-confirmed ID3 tags and proper cover art. It also allows you to play imported MP3s, search for songs across all imported playlists, manage metadata, and much more.
The program runs from the command line and is designed for a clean and user-friendly experience.
Features Limitations Requirements Installation Configuration Execution Usage Commands Examples Troubleshooting Thanks
- Import YouTube playlist songs in MP3 format
- Automatically shazam songs to set accurate ID3 tags and cover art
- Consistently name MP3 files by artist and song title
- Fix metadata to shazam-unmatched "junk" songs
- Cleanup existing metadata from imported songs
- List songs and playlists with detailed information
- Easily play songs directly from the CLI and open related videos
- Filter and sort songs via fuzzy search (available for all commands)
- Only public playlists can be imported
- Region-restricted videos are excluded from import
- Import of age-restricted videos fails but do not block others
PYPL2MP3 requires:
- Python ≥ 3.7
- UV is required to manage dependencies and run the program in its own virtual env.
ffmpeg
andffprobe
(shipped together) must be installed for audio conversion and tagging.
- A Proof of Origin Token (POT) is needed to access YouTube audio / video streams (details here).
- It is automatically generated via BotGuard from
pytubefix
version8.12
and requiresNode.js
to be installed.
uv sync
PYPL2MP3 works out of the box, storing imported playlists in ~/pypl2mp3
by default. It does not require any database.
PYPL2MP3_DEFAULT_REPOSITORY_PATH
– Folder path for storing imported MP3 playlistsPYPL2MP3_DEFAULT_PLAYLIST_ID
– Favorite YouTube playlist ID for quick access
Example setup (in terminal):
export PYPL2MP3_DEFAULT_REPOSITORY_PATH="/your/custom/path"
export PYPL2MP3_DEFAULT_PLAYLIST_ID="yourFavoritePlaylistID"
To persist settings, add these to your .bashrc
or .zshrc
file.
From the project root, run:
uv run pypl2mp3 <command> [options]
Or use the shell wrapper from any directory:
sh /path/to/pypl2mp3.sh <command> [options]
-
Run a command:
pypl2mp3 <command> [options]
-
List available commands:
pypl2mp3 --help
-
Get help for a specific command:
pypl2mp3 <command> --help
Note: In the command uses described below, the term "INDEX" refers to the rank of an item in a list of songs or playlists resulting from the applied filter criteria; it therefore only has meaning at the time of command execution.
-h, --help
: Show command-specific help-r, --repo <path>
: Set playlist repository (default: see Configuration)-d, --debug
: Enable verbose errors (*) and logging to file/repo/path/pypl2mp3.log
-D, --deep
: Enable deep debug with fully detailed stack trace in log file
(*) Verbose errors display a shortened version of the stack trace:
[ERROR] Failed to import song "LANA DEL REY - COLA (OFFICIAL AUDIO)"
[2] pypl2mp3.libs.song.SongModelException: Failed to stream audio track for YouTube video "UtVUkZ4Rx_I"
[1] pytubefix.exceptions.AgeRestrictedError: UtVUkZ4Rx_I is age restricted, and can't be accessed without logging in.
pypl2mp3 import [options] <playlist>
Arguments (may be optional if a favorite playlist is configured):
-
playlist
: ID, URL or INDEX of a playlist to import (default: see Configuration)Note: Song URLs are also accepted; the playlist ID will be extracted from them.
Options:
-f, --filter <filter>
: Filter songs to import using keywords-m, --match <percent>
: Filter match threshold (0-100, default: 45)-t, --thresh <percent>
: Shazam match threshold (0-100, default: 50)-p, --prompt
: Prompt before importing each new song
This command imports a new YouTube playlist and also syncs previously imported tracks. When syncing, only tracks newly added to the YouTube playlist are eligible for import. It also provides a prompt mode to confirm each song import.
pypl2mp3 playlists
pypl2mp3 songs [options]
Options:
-l, --list <playlist>
: Specify a particular playlist by its ID, URL or INDEX-f, --filter <filter>
: Filter songs using keywords and sort by relevance-m, --match <percent>
: Filter match threshold (0-100, default: 45)-v, --verbose
: Enable verbose output
pypl2mp3 junks [options]
Options:
-l, --list <playlist>
: Specify a particular playlist by its ID, URL or INDEX-f, --filter <filter>
: Filter songs using keywords and sort by relevance-m, --match <percent>
: Filter match threshold (0-100, default: 45)-v, --verbose
: Enable verbose output
pypl2mp3 tag [options]
Options:
-l, --list <playlist>
: Specify a particular playlist by its ID, URL or INDEX-f, --filter <filter>
: Filter songs using keywords and sort by relevance-m, --match <percent>
: Filter match threshold (0-100, default: 45)-t, --thresh <percent>
: Shazam match threshold (0-100, default: 50)-p, --prompt
: Prompt to set ID3 tags and cover art for each song
This command attempts to batch retrieve "junk" song metadata from YouTube and then Shazam and automatically fix MP3 filenames. It also provides an interactive prompt mode to validate or fix the retrieved metadata for each of the selected songs and rename the MP3 files accordingly.
pypl2mp3 untag [options]
Options:
-l, --list <playlist>
: Specify a particular playlist by its ID, URL or INDEX-f, --filter <filter>
: Filter songs using keywords and sort by relevance-m, --match <percent>
: Filter match threshold (0-100, default: 45)-p, --prompt
: Prompt to removes ID3 tags and cover art from each song-v, --verbose
: Enable verbose output
This command batch cleanup metadata for all selected songs and rename them as "junk". It also provides a prompt mode to confirm cleanup song by song.
pypl2mp3 videos [options]
Options:
-l, --list <playlist>
: Specify a particular playlist by its ID, URL or INDEX-f, --filter <filter>
: Filter songs using keywords and sort by relevance-m, --match <percent>
: Filter match threshold (0-100, default: 45)-v, --verbose
: Enable verbose output
This command prompts to open the YouTube video for each of the selected songs.
pypl2mp3 play [options] [filter] [index]
Arguments (optional):
filter
: Filter songs using keywords and sort by relevanceindex
: INDEX of a single song to play (0 for random song)
Options:
-l, --list <playlist>
: Specify a particular playlist by its ID, URL or INDEX-m, --match <percent>
: Filter match threshold (0-100, default: 45)-s, --shuffle
: Play songs in random order-v, --verbose
: Enable verbose output
Player controls:
[ <-- ] Previous song / Play backward
[ --> ] Next song / Play forward
[ SPACE ] Pause song / Play song
[ TAB ] Open song's video in browser
[ ESC ] Quit player
Import / sync a YouTube playlist with accurate Shazam recognition
pypl2mp3 import -t 70 "https://www.youtube.com/playlist?list=PLP6XxNg42qDG3u8ldvEEtWC8q0p0BLJXJ"
Permissively retrieve Jimi Hendrix songs from all imported playlists
pypl2mp3 songs -f "hendrix jim" -m 25
Interactively fix shazam-unmatched "junk" songs in a given playlist
pypl2mp3 fix -l PLP6XxNg42qDG3u8ldvEEtWC8q0p0BLJXJ -p
Play random Dire Straits songs from playlist #2
pypl2mp3 play -l 2 -s "dire straits"
Recent changes to the YouTube API may prevent songs from being uploaded or
tagged. You can try updating pytubefix
to its latest minor version as a
temporary workaround while you wait for a fix (also, feel free to file an
issue):
uv lock --upgrade-package pytubefix
PYPL2MP3 relies primarily on pytubefix
and shazamio
under the hood to provide
its core features. These packages work fine and are well maintained. They
also require a lot of effort to sync with the services they provide access to.
So, if you like PYPL2MP3, please give them a ★ on GitHub.