Scripts to keep music tidy.
The main script (bandcamp
) can be used to extract and clean files (allow to review and easily edit some metadata fields) from Bandcamp and Amazon Music downloads.
The files are then stored in a configurable location, in neatly named directories.
It should work with pretty much any ZIP archive that contains MP3 or FLAC files.
See example below.
Some other scripts, here, are dependencies of the bandcamp
one, but can also be used on their own for various purposes.
I don’t do proper releases nor use tags at the moment, but I try to keep master
fairly stable.
Ping me if you think I screwed up somewhere.
-
Download the project and save it where it suits you.
-
Add the
bin/
directory to yourPATH
to be able to run these scripts from anywhere.
~/.bashrc
PATH+=':~/bin/bandcampetc/bin/'
export PATH
Warning
|
Make sure you adapt the |
The bandcamp
script relies on:
- Bash · version ≥ 4.3
-
Because associative arrays and variables declared with
-n
. Should already be OK on most machines. eyeD3
-
Manipulate MP3 metadata. Note that the software’s package is generally called
eyed3
. These guys often break backward compatibility… I adapted my commands firstly to version0.6.18
(Ubuntu 16) and later to0.7.10
(Debian 9). Tell me if you get “unrecognized arguments” errors. metaflac
-
Manipulate FLAC metadata. Bundled with the
flac
package. rsync
-
“A fast, versatile, remote (and local) file-copying tool.”
unzip
-
Decompress ZIP archives.
- ImageMagick
-
To manipulate cover art. (
imagemagick
package.) awk
-
“Pattern scanning and processing language.” GNU’s
gawk
implementation recommended, but the minimal implementationmawk
does the job. geany
-
… as a recommended simple text editor to revise music metadata. You can use any other editor by changing a constant’s value in
config/bandcamp.sh
. ffmpeg
oravconv
-
For FLAC → MP3 conversions.
(Optional, see the config section.) file
-
Installed on most distributions, but missing from some Docker images. The package is also called
file
. curl
· version ≥ 7.67.0-
To send HTTP requests to the MusicBrainz API.
(Optional, for thegetgenre
script.) jq
-
To process the data sent back by the MusicBrainz API. Version
1.6
is recommended, but it may work with older ones.
(Optional, for thegetgenre
script.)
Tip
|
On Ubuntu and Debian machines, this should be enough to get everything: $ sudo apt install eyed3 flac rsync unzip imagemagick gawk geany ffmpeg file jq curl |
The main script, at least from my point of view. When you download music from Bandcamp, Amazon Music, etc., you generally end up with a random ZIP archive full of poorly named files. Furthermore, the music’s metadata is often dirty as well: some labels add random information (sometimes even catalogue numbers!) in the tracks’ titles and so on.
This script can be run from anywhere (it has no importance) without argument.
-
It will look for ZIPs in
~/Downloads/
,~/Téléchargements/
,~/Descargas/
,~/Загрузки/
… You can also give ZIPs directly as arguments to the script. -
For each ZIP that contains MP3 or FLAC files, the files will be extracted.
-
You will be offered the possibility to edit the music’s metadata in a text editor.
-
The files will be tagged and named according to the cleaned version of the metadata.
-
If the album is in FLAC format and if the
CONVERT_TO_MP3
constant has been set to a non-empty value, an MP3 version of the record will be generated alongside the FLAC version. -
The original ZIP will be discarded.
See bandcamp -h
for help.
Try to put capital letters in nice places in song and record titles. This is not perfect, of course, but this script provides a good starting point for metadata cleaning. As time went by, this also became a utility to clean up some common ugly things that have little or even nothing to do with capitalization.
$ capitasong "You will blow up a dog some day, as the other guy said"
You Will Blow Up a Dog Some Day, as the Other Guy Said
$ capitasong "Le chien de ta mère est gros"
Le Chien de Ta Mère Est Gros
Note
|
Many conventions exist. I used stuff from http://aitech.ac.jp/~ckelly/midi/help/caps.html. (That weird link might become dead or point to something unrelated someday. Use with caution.) |
Try to get a musical genre from tags found on MusicBrainz. Can try to target a specific release or (on purpose or as a fallback) an artist itself.
By default, only the best tag is printed out, but -n, --number
can be used to ask for more.
In such cases, the best tags will come first.
$ getgenre -a 'sigur ros' -r kveikur -n 2
Post-rock
Rock
$ getgenre --artist 'negura bunget'
Black metal
$ getgenre -h
Try to fetch cover arts from various sources. An old ugly script of mine. Don’t pay it too much attention. Most album downloads already contain a cover anyway, so this is seldom called. This may break as the used websites change their APIs or page layout, etc.
Warning
|
Since Bandcamp albums always contain a cover art already, I don’t devote time to the I encourage you to manually add a |
I like to add the cover art in the music files’ metadata. This way, even devices such as cars with no Internet access or whatever are able to display cover arts when playing music. The setcover
script embed a cover art in MP3 and FLAC files. See setcover -h
for help.
To prevent art addition (see setcover
) from making my files oversized, I use a low-quality version of it. The create-lq-cover
script simply creates lightweight pictures from a given original version.
Used to be able to display metadata from MP3 and FLAC files using the same command. This uses homemade pattern strings.
$ mmeta '\n%f\n%a, “%t” [%l, %s]\n\t(“%A”, %y, %g)\n\n' ./{salvation,eternal_kingdom/*}/1*
./salvation/1_-_echoes.mp3
Cult of Luna, “Echoes” [59:09, 13.50 MB]
<TAB>(“Salvation”, 2004, Post-Metal)
./eternal_kingdom/flac/10_-_following_betulas.flac
Cult of Luna, “Following Betulas” [Unknown, Unknown]
<TAB>(“Eternal Kingdom”, 2008, Post-metal)
See mmeta -h
for help.
I love this one. It eats a string and gives a version of it devoid of weird characters. I use it to rename all my music files. Since I buy obscure black metal and stuff, I had to update it to roughly transliterate Cyrillic and Icelandic. It still can’t handle Japanese properly, though. Sorry.
$ to_acceptable_name <<< "@Œӂ (%s/) «¼___.flac"
atoez_s_1_4.flac
$ to_acceptable_name <<< '円423 for you.MP3'
423_yens_for_you.mp3
Tip
|
This script also cuts long file names to 255 characters to avoid errors, while trying to keep the file’s extension. |
Use to_acceptable_name
to find a suitable name for a file, and rename that file using that name.
Tip
|
I like to add this as a custom action in my file manager. Typically, in Thunar: give_acceptable_name %F (“Edit” → “Configure custom actions…”) Remember to check that the “Appearance Conditions” are broad enough. |
Various settings can be changed in the config/bandcamp.sh
file.
To get both a FLAC and an MP3 version of your records, check the part of config/bandcamp.sh
that looks like this:
CONVERT_TO_MP3=''
To turn the feature on, change this line to:
CONVERT_TO_MP3=1
Tip
|
To activate conversion for one specific run, you can use the $ bandcamp -c |
To choose the text editor used to edit music metadata, check the part of config/bandcamp.sh
that looks like this:
unset -v EDITOR
#readonly EDITOR=(nano -S)
#readonly EDITOR=(vi)
#readonly EDITOR=(mousepad)
#readonly EDITOR=(leafpad)
#readonly EDITOR=(gedit)
#readonly EDITOR=(code --new-window --wait)
readonly EDITOR=(geany -i)
The commented out lines give you examples for other editors than Geany. Uncomment one of them (while commenting the others), or write your own assignment.
Note
|
I use an indexed array rather than a dumb string to make the script more robust: you can use parameters that contain spaces: |
Tip
|
To make the script run without any interaction, use a no-op or any idle-ish command as an editor: |
Caution
|
The editor must block the execution flow, so that you’re able to edit the metadata, save, and close it before the rest of the script runs.
Some editors, like Visual Studio Code, tend to launch themselves in the background – much like when appending |
I love trying to do unit testing in Bash.
Just run ./run_tests.sh
and a bunch of commands will be executed.
The first failure stops the execution (set -e
) and you should be able to see what failed in the output.
If everything works as intended, the output should end with a message like:
run_tests.sh: All done (22 files).
Tip
|
For development purposes, you can run a subset of the test scripts by passing them as arguments: $ ./run_tests.sh test_scripts/mmeta.sh test_scripts/setcover/gettype.sh |
(Kinda old; may not reflect perfectly the latest version’s logs.)
With one ZIP from https://giftsfromenola.bandcamp.com/album/from-fathoms in ~/Downloads/
:
$ bandcamp
bandcamp: Inspecting “/home/alice/Downloads/Gifts From Enola - From Fathoms.zip”...
Archive: ./Gifts From Enola - From Fathoms.zip
extracting: Gifts From Enola - From Fathoms - 01 Benthos.flac
extracting: Gifts From Enola - From Fathoms - 02 Weightless Frame.flac
extracting: Gifts From Enola - From Fathoms - 03 Weightless Thought.flac
extracting: Gifts From Enola - From Fathoms - 04 Trieste.flac
extracting: Gifts From Enola - From Fathoms - 05 Resurface.flac
extracting: Gifts From Enola - From Fathoms - 06 Melted Wings.flac
extracting: Gifts From Enola - From Fathoms - 07 Thawed Horizon.flac
extracting: Gifts From Enola - From Fathoms - 08 Aves.flac
extracting: cover.jpg
╭────────────────────────────────────────────╌╌┄┄┈┈
│ Type: flac
│ Artist: Gifts from Enola
│ Album: “From Fathoms”
╰────────────────────────────────────────────╌╌┄┄┈┈
[Here, my editor was launched and I set the genre as “Post-rock” before closing it.]
bandcamp: Track 1 of 8...
bandcamp: Track 2 of 8...
bandcamp: Track 3 of 8...
bandcamp: Track 4 of 8...
bandcamp: Track 5 of 8...
bandcamp: Track 6 of 8...
bandcamp: Track 7 of 8...
bandcamp: Track 8 of 8...
bandcamp: Found cover: cover.jpg
HQ → “cover.jpg” (3,5M)
LQ → “./cover_lq.jpg” (resize: 512×512; quality: 85) (112K)
'cover.jpg' -> 'gifts_from_enola/from_fathoms/flac/cover.jpg'
'cover_lq.jpg' -> 'gifts_from_enola/from_fathoms/flac/cover_lq.jpg'
removed 'cover.jpg'
removed 'cover_lq.jpg'
bandcamp: Applying “gifts_from_enola/from_fathoms/flac/cover_lq.jpg” to files...
bandcamp: Renaming files...
“Gifts From Enola - From Fathoms - 01 Benthos.flac” → “1_-_benthos.flac”
“Gifts From Enola - From Fathoms - 02 Weightless Frame.flac” → “2_-_weightless_frame.flac”
“Gifts From Enola - From Fathoms - 03 Weightless Thought.flac” → “3_-_weightless_thought.flac”
“Gifts From Enola - From Fathoms - 04 Trieste.flac” → “4_-_trieste.flac”
“Gifts From Enola - From Fathoms - 05 Resurface.flac” → “5_-_resurface.flac”
“Gifts From Enola - From Fathoms - 06 Melted Wings.flac” → “6_-_melted_wings.flac”
“Gifts From Enola - From Fathoms - 07 Thawed Horizon.flac” → “7_-_thawed_horizon.flac”
“Gifts From Enola - From Fathoms - 08 Aves.flac” → “8_-_aves.flac”
bandcamp: Moving the files to “/home/alice/Music/gifts_from_enola/from_fathoms“...
bandcamp: All done for this ZIP.
removed '/home/alice/Downloads/Gifts From Enola - From Fathoms.zip'
bandcamp: End.
$ tree ~/Music/gifts_from_enola/
/home/alice/Music/gifts_from_enola/
└── from_fathoms
└── flac
├── 1_-_benthos.flac
├── 2_-_weightless_frame.flac
├── 3_-_weightless_thought.flac
├── 4_-_trieste.flac
├── 5_-_resurface.flac
├── 6_-_melted_wings.flac
├── 7_-_thawed_horizon.flac
├── 8_-_aves.flac
├── cover.jpg
└── cover_lq.jpg
2 directories, 10 files
If you want to show your appreciation or make suggestions…
(You can also send me Bandcamp gifts, I guess, hehe.)