Automatic CD Ripper - Raspberry Pi, Linux, udev, systemd, Dropbox, Zapier, and more!

August 8, 2017 by Andrew A. Cove

I just pushed the scripts and configuration for my Raspberry Pi automatic CD ripper to GitHub. It’s a project I’ve been thinking about for a long time. I even referenced it in The Great Big Project Hunt.

It took a lot more time and effort than I was expecting, and most of that time and effort was spent on frustrating Google dives. The learning curve of Linux configuration can be steep. Truth be told, I didn’t want to dive deep into Linux to make this work, and I’m disappointed that I had to. Debugging (even just finding feedback from the various systems I touched) was tedious, and there’s no good way to search for solutions. The web is littered with copies of ancient mailing lists; the knowledge spread across forums is of questionable accuracy; and often, the solutions are outdated or for the wrong distro.

Consumer web products like IFTTT make it trivial to do mind-boggling integrations across services. Trying to get an event to trigger a script in Linux was like getting doused by an ice bucket.

On to the project…

I own more than 400 CDs, and I’d like to have them available to me without paying for a premium streaming subscription or the additional cellular data that I’d consume. In addition, a number of the CDs are not available on the streaming services. I think the music industry should give customers the option of buying a permanent license to songs/albums across all media, but until that happens, buying CDs and ripping them seems like the best way to get music with the quality and flexibility I’d like.

Of course, there’s still the headache of actually getting the music onto my phone. There’s still some work to be done there, to automatically add newly ripped audio to my iTunes library (ugh). I will happily accept suggestions of better (non-streaming 😝) options for getting music on my phone. Alexa too.

I bought a Raspberry Pi Zero W which runs headless (it’s never had a monitor or keyboard attached – fully configured over ssh) and a slot loading optical drive (for aesthetic reasons), the LG GP70NS50.

When I insert a disc into the drive, the Pi automatically rips the audio, encodes it to flac (for archiving) and mp3 (for my phone), and then uploads both sets of files to Dropbox. Then it triggers a Zapier webhook, which adds the album to AirTable and sends me an email telling me it’s done.

These are the key components:

  • udev – the Linux device manager. When the disc is inserted, udev triggers a rule that I created, which sets the rest in motion. The rule starts a systemd service.
  • systemd – an init system that also manages system processes. In order for the scripts to run in the background, I wrap them in a systemd service, which is run by the udev rule.
  • abcde – a super powerful command line CD ripping tool. This does most of the heavy lifting.
  • Dropbox – this is where I ended up saving the files. I considered an external hard drive and a NAS, but I’m already paying for Dropbox and have space to burn, and I didn’t want to outlay the money for storage (nor did I want to have to buy the adapters or USB hubs to handle more devices). Not necessarily a permanent choice. I upload the files via the REST API.
  • curl - nothing special, but this was way more efficient for uploading the files than installing a client on the Pi or using the bloated Python script that comes up on Google. It also fires the Zapier webhook.
  • Zapier – instead of hitting a bunch of different services to post-process, I just hit Zapier and it fires off the rest (saving a record in AirTable and sending me an email. But it could probably make my Hue lights flash too)
  • AirTable – not actually touched by any of the scripts, but I <3 it and it’s where I’m storing the list of albums that have been ripped.

Thinking through what took the most work:

  • Permissions. I lost a lot of time trying to debug permissions issues. The scripts run as root when the disc is inserted, but getting the whole thing setup and tested I was logged in as a user. abcde behaves differently when it’s run in a user’s home directory than when it’s run by root (the temp files move around), and I kept getting errors that amounted to not having the appropriate write permissions.
  • For a while, I was seeing the udev scripts start to run and then inexplicably stop. It was maddening. Eventually I found posts online saying that udev strictly kills scripts after a short amount of time, so long running tasks should be run as systemd services.
  • The last bit was mystifying: the udev rules suddenly seemed to stop firing when the disc was inserted. I don’t know what changed, but one night the udev rules were triggering the systemd services and then the next night it stopped. I was so baffled that I waited about a month before trying to fix it. In the end I had to change a udev rule from using SYSTEMD_WANTS to trigger the service to instead running systemctl directly. Not sure how it ever worked before that.

There are still some issues left around error handling (cdparanoia occasionally has read errors that don’t leave much of a log trail), but I’m stoked to have this mostly functional. There are a number of tutorials about how to do this online, but they’re all only accurate to varying degrees so I decided to share my version on GitHub. Code here: https://github.com/aac/raspberrypi-cd-ripper

© 2017 | Follow on Twitter