A CLI application to download music independently and from your exported Apple Music library.
- To download your entire Apple Music Library and store it locally in one go
- To search and download individual albums and songs from YouTube
- To keep track of your ever growing music collection
- To organize and stream your music library through a self-hosted app like Plex, Navidrome or Jellyfin
- Takes an exported Library.xml from your Apple Music and converts and exports it as a dataframe into Library.csv (
parse
command) - Uses YouTube Music to download songs from the Library.csv (
download
command) - The above two steps can be done automatically by a single
download
command - The metadata for songs and albums are stored in a dedicated sqlite db, see
amusing/models.py
for the complete list of metadata - Can be used to download individual albums and songs outside of your Apple Music library (
album
andsong
commands). All metadata is extracted from MusicBrainz. - Once downloaded, organize your library into a format that is expected by a typical music streaming application like Plex, Navidrome or Jellyfin: Artist/Album/Track (the
organize
command)
I found the beets
library too hard to use so I built this.
I know that beets is much more expansive than Amusing, but if you have or want a simple workflow that allows you to download albums and songs, extract metadata from a reliable source, and organize your music into a reliable format for use by a music streaming application, you'll find no simpler solution than Amusing.
Install it as a PyPI package:
pip install amusing-app
You will also need FFmpeg installed, which is required to embed song metadata (title, artist, album, cover art, ...) in the audio file.
There are three things to know before moving on to the next section:
-
The CLI takes in a
appconfig.yaml
file similar to what's indicated inappconfig.example.yaml
. You can simply rename it.The file looks like this:
root_download_path: "..." db_name: "..."
The file can be placed in two locations:
~/Downloads/Amusing/appconfig.yaml
: default one. If the file is not found anywhere it will be created here.~/.config/amusing/appconfig.yaml
: only if the default one does not exist.
-
A dedicated sqlite database called
db_name
will be created inroot_download_path/db_name.db
to store two tablesSong
andAlbum
as defined inamusing/db/models.py
. All songs downloaded locally will be getting a row in theSong
table and a row for their corresponding album in theAlbum
table. -
The songs are downloaded in
root_download_path/songs
directory. -
That's it. You're done. Let's look at the commands available next.
There are currently 8 commands available, excluding the version
and help
commands.
The first time you run a command (eg. --help
), an Amusing
directory will be created in the ~/Downloads
folder.
For eg., on MacOS, it's in /Users/Username/Downloads
.
$ amusing --help
Usage: amusing [OPTIONS] COMMAND [ARGS]...
CLI to download music independently and from your exported Apple Music library.
╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --version -v │
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ album Search and download the album and add it and any or all of its songs to the db. Creates a new album if not already present. This is the preferred way of adding new songs/albums to │
│ the music library. │
│ download Download the entire DB library. │
│ organize To organize the music library for an applcation like Plex or Jellyfin. Organizes the music at the supplied destination in the form: ArtistName/AlbumName/Track. │
│ parse Parse the entire Apple Music library and make/update the DB as needed. │
│ showsimilar Look up the db and show if similar/exact song(s) are found. │
│ showsimilaralbum Look up the db and show albums similar to the album searched. │
│ showsimilarartist Look up the db and show songs for similar/exact artist searched. │
│ song Search and download an individual song and add it to the db. Creates a new album if not already present. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
You can also use a previously parsed Library.csv
, that already contains mappings with YouTube video IDs and possible URLs to download custom album artworks.
$ amusing parse --help
Usage: amusing parse [OPTIONS] LIBRARY_PATH
Parse the entire Apple Music library and make/update the DB as needed.
╭─ Arguments ───────────────────────────────────────────────────────────────────╮
│ * library_path TEXT The path to the 'Library.xml' or 'Library.csv' │
│ exported from Apple Music. │
│ [default: None] │
│ [required] │
╰───────────────────────────────────────────────────────────────────────────────╯
╭─ Options ─────────────────────────────────────────────────────────────────────╮
│ --help Show this message and exit. │
╰───────────────────────────────────────────────────────────────────────────────╯
# Example
$ amusing parse 'your/path/to/Library.xml'
You can also pass a Library.xml
or a Library.csv
file to parse before downloading the songs.
$ amusing download --help
Usage: amusing download [OPTIONS] [LIBRARY_PATH]
Download the entire DB library.
If passed, parse the library and update the DB before download.
╭─ Arguments ───────────────────────────────────────────────────────────────────╮
│ library_path [LIBRARY_PATH] The path to the 'Library.xml' or │
│ 'Library.csv' exported from Apple Music. │
╰───────────────────────────────────────────────────────────────────────────────╯
╭─ Options ─────────────────────────────────────────────────────────────────────╮
│ --help Show this message and exit. │
╰───────────────────────────────────────────────────────────────────────────────╯
# Example
$ amusing download 'your/path/to/Library.xml'
# is equivalent to running
$ amusing parse 'your/path/to/Library.xml'
$ amusing download
This is the recommended way to download a new album. You can choose to download a song or skip it with this method, and it either edits if an existing album is found, or adds a new album.
$ amusing album --help
Usage: amusing album [OPTIONS]
Search and download the album and add it and any or all of its songs to the db. Creates a new album if not already present. This is the preferred way of adding new songs/albums to the music library.
╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ * --title TEXT Title of the album [default: None] [required] │
│ --artist TEXT Artist of the album (optional) [default: None] │
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
# use it like so:
$ amusing album --title "808s & Heartbreak" --artist "Kanye West"
$ amusing song --help
Usage: amusing song [OPTIONS]
Search and download an individual song and add it to the db. Creates a new album if not already present.
╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ * --title TEXT Title of the song [default: None] [required] │
│ --artist TEXT Artist of the song (optional) [default: None] │
│ --album TEXT Album of the song (optional) [default: None] │
│ --force --no-force Overwrite the song if present. [default: no-force] │
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
$ amusing song --title "Run" --artist "One Republic" --album "Human"
This command helps organize your music library in a new place in the format: Artist/Album/Track
$ amusing organize --help
Usage: amusing organize [OPTIONS] DESTINATION_PATH
To organize the music library for an applcation like Plex or Jellyfin. Organizes the music at the supplied destination in the form: ArtistName/AlbumName/Track.
╭─ Arguments ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ * destination_path TEXT The full destination directory path for organized music, can be the path which an application like Plex is expecting. [default: None] [required] │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
# use it like so:
$ amusing organize ~/Plex/Media/Music/
$ amusing showsimilar "Someday"
Song to look up: someday
┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Song ┃ Artist ┃ Album ┃
┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ Someday │ OneRepublic │ Human (Deluxe) │
│ Someday At Christmas │ Justin Bieber │ Under the Mistletoe (Deluxe Edition) │
└──────────────────────┴───────────────┴──────────────────────────────────────┘
$ amusing showsimilarartist "OneRepublic"
Artist to look up: OneRepublic
┏━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Song ┃ Artist ┃ Album ┃
┡━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ Run │ OneRepublic │ Human (Deluxe) │
│ Someday │ OneRepublic │ Human (Deluxe) │
│ No Vacancy │ OneRepublic │ No Vacancy - Single │
│ RUNAWAY │ OneRepublic │ RUNAWAY - Single │
│ Sunshine │ OneRepublic │ Sunshine - Single │
│ I Ain't Worried │ OneRepublic │ Top Gun: Maverick (Music from the Motion Picture) │
│ West Coast │ OneRepublic │ West Coast - Single │
└─────────────────┴─────────────┴───────────────────────────────────────────────────┘
$ amusing showsimilaralbum "Human"
Album to look up: Human
┏━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓
┃ Album ┃ Number of songs ┃
┡━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩
│ Human (Deluxe) │ 2 │
└────────────────┴─────────────────┘
The resulting Library.csv
file will be automatically updated by Amusing at every DB change.
You can manually modify it to change which YouTube video to download for a specific song. You can also add a new URL to download a specific album artwork or a specific YouTube video.
Here are some great tools you can use to find album artworks:
You just need to run amusing download '/path/to/Library.csv'
and you'll get the updated song/album metadata in your db and the new downloaded song in your collection.
You can then use the organize
command again to sort it out for your Plex application. Running the commnand will make sure to get the updated album(s)/song(s) into your organized music library.
Please open a new Issue to make a bug or an enhancement request known to me.
Also, submit a PR with improvements or new features at your will. :)