hoowl

Physicist, Emacser, Digitales Spielkind

How to keep a lossless digital music library with lossy mirror in a few lines of bash
Published on Jun 13, 2020.

I have been building (and rebuilding) my digital music library for around 22 years now. Starting with encoding runs of my few CDs into mp3 which took close to an hour per track on my computer back when – and giving pretty abhorrent quality nevertheless – I moved over the years to a collection which is now several hundreds of albums large. Storage nowadays is much less of a concern, however, and encoding into different formats is blazing fast, so I opt for the lossless FLAC format whenever transferring new CDs to the computer or downloading new albums. For mobile devices, I transcode the files into a mp3 mirror of my library by just running a handy little bash script.

My music library is stored in ~/Music in two folders mp3z and flacs for mp3 and FLAC formats, respectively. My mp3 collection also contains several albums that I could not get in FLAC format (or downloaded before I had an interest in lossless storage). But everything in my FLAC folder can also be found as mp3. This is ensured when I run the following script:

1: #!/usr/bin/env bash
2: 
3: cd $HOME/Music/flacs
4: find . -type f -name '*.flac' -exec bash -c 'if [ ! -e "../mp3z/${0/%flac/mp3}" ]; then mkdir -p "../mp3z/`dirname "$0"`" && ffmpeg -i "$0" -y -codec:a libmp3lame -c:v copy -qscale:a 2 "../mp3z/${0/%flac/mp3}"; else echo SKIPPING: "$0"; fi' {} \;
5: sacad_r . 1000 cover.jpg
6: find . -type f -name 'cover.jpg' -exec bash -c 'if [ ! -e "../mp3z/${0}" ]; then cp "$0" "../mp3z/${0}"; fi' {} \;

It looks for FLAC files without corresponding mp3 and reencodes them using ffmpeg. The meta information contained in the tag is copied 1:1 as well. Note to self: Line 4 is quite long and can probably be refactorized into a function. After re-encoding the file, the cover art is retrieved using sacad_r in line 5 and copied into the folder of the mp3 album.

As final step, the music is automatically spread to my various devices using syncthing. Which means that besides changing CDs and running abcde -o flac && eject I don’t have to do much :)

Tags: scripts