Steven Bleifer

Notes · September 2026

Ripping vinyl.

I wanted my records in the same place as the rest of my music. That turned into a two week project involving a brand new laptop, a fourteen year old one, and a folder name that lies to you.

Apple Lossless Two Macs ~290 MB per album 7 seconds end to end

Why I needed this

My music library is about 95,000 tracks. Roughly a terabyte. It's really three libraries stacked on top of each other. I copied my dad's, I copied my brother's, and I had my own, and I merged all three into one on the old MacBook Pro. A lot of what's in there came off things that don't exist anymore, old iPods and hard drives that died years ago.

It all lives in iTunes. Not Apple Music, not the new Music app. Actual iTunes, the last version before Apple broke it into pieces in 2019.

That sounds like stubbornness but there's a reason. A library this big is basically a database, and the new Music app is built for streaming. iTunes is the last Apple thing that treats a pile of files you own as the main point instead of an afterthought. So the library stays on a machine that can still run it, which means macOS Mojave, which means my old MacBook Pro.

Meanwhile I'd been buying records. I wanted them in the library with everything else, and I didn't want to think about it every time.

Splitting it across two laptops

My first thought was to just do everything on the old machine. It has a real line in, it already has the library, and it's plugged in and running all the time anyway. I actually did it that way for a while and ripped about ninety albums.

It works, but it's slow and irritating. Cleaning up one side of a record takes minutes. The recording software argues with the OS constantly. And the part of the job that needs you sitting there, setting track breaks and typing in track listings, is miserable on a laptop from 2012.

So I split it up. Recording happens on the new laptop now, through a USB audio interface, where everything is fast. The old MacBook Pro just sits there with the lid closed running iTunes and holding the music.

Which left the actual problem. How does a finished album get from one to the other without me babysitting it.

How it actually works

iTunes has a folder called "Automatically Add to iTunes." Anything you put in there gets imported and filed by its tags. That's the whole hook.

It's also the risky part. iTunes watches that folder constantly and it does not wait for you to finish writing a file. If it catches one halfway through, it imports half a song, files it neatly, and you find out months later when you play it.

So nothing gets written into that folder directly. Instead it goes like this:

  • Step 1Record the side, split it into tracks, tag everything.
  • Step 2Export to a staging folder as Apple Lossless, one folder per album.
  • Step 3A script checks every file first. Is it really lossless, does it have an artist, an album, a title, a track number.
  • Step 4Copy it over under a temporary name, so an interrupted transfer can't look finished.
  • Step 5Checksum every file on both machines and compare. Only if they all match does it get its real name.
  • Step 6One move into the watch folder. The whole album shows up at once, or not at all.

That last step is the trick, and it took me a while to understand why it matters. Because the staging folder and the watch folder are on the same disk, moving between them isn't really a copy. It's a rename, and the filesystem does that instantly and all at once. There's no moment where half an album is sitting there for iTunes to grab.

The two laptops are wired directly together instead of going over wifi, which turns out to be worth about four times the speed. An album crosses in three seconds instead of twelve. If I unplug the cable it notices and falls back to wifi on its own.

If you want the actual mechanics, the atomic rename, the checksumming, the MP4 tag parser I had to write, there's a technical write up of how it works.

Things that broke

This is the part I'd actually want to read, so here it is. Four things caught me out.

The folder isn't called what it says it's called. Finder shows it as "Automatically Add to iTunes." On disk it's actually Automatically Add to iTunes.localized, because Finder hides the suffix. Every script using the obvious path just failed until I looked at the raw directory listing.

The normal way to read music tags returned nothing. macOS has a built in tool for this and it gave back empty values for every file I'd just exported. Turns out it reads from the Spotlight index rather than the file itself, and a file written thirty seconds ago hasn't been indexed yet. So the check that was supposed to catch untagged albums was throwing out perfectly good ones. I ended up with a small parser that reads the tags straight out of the file.

One character broke everything. There was a check to refuse filenames with a line break in them, which is an edge case that would mess up the verification step. The way it was written, the thing being searched for came out as an empty string, and every filename contains an empty string. So it matched all of them and refused every single file.

And the first run that worked made fifteen duplicates. Everything did exactly what it was supposed to. Transferred, verified, imported. It was just an album I'd already ripped three weeks earlier. There were guards against the pipeline tripping over its own state and none at all against it tripping over the library. Now it asks iTunes whether it already has the album before it sends anything.

Neither of the two bugs above was visible by reading the code. Both showed up the first time it ran against real music.

Breaking it on purpose

The test I cared about was the ugly one. What happens if the connection dies in the middle of an album.

So I started a 1.4 GB transfer and killed the connection halfway through. It did the right thing. The script stopped and said it failed, nothing reached iTunes, the local copy stayed where it was, and the half finished transfer sat on the other machine under its temporary name where it couldn't be confused for a real album. I ran it again and it picked up where it left off, rechecked every file, and finished.

That's the difference between a script that works and one I actually trust. The first kind works when nothing goes wrong.

The backup thing I found by accident

While setting this up I checked the backups on the machine holding the library, fully expecting to tick a box and move on. Time Machine was on. It was running every hour. The library was included. Fine.

Except the drive only had thirteen days of history on it. A healthy Time Machine keeps daily backups for a month and weekly ones going back further. This one had no weeklies at all. The drive was too small for what it was backing up, so every new backup was quietly deleting an old one to make space, and it had been doing that for months.

Nothing was broken and nothing was lost. But the only copy of a twenty year library had less than two weeks of safety net behind it, and I only found out because I happened to be building something else. A bigger drive is on the way and the old one becomes a second copy that lives unplugged.

The thing I keep coming back to is that I would have said my backups were fine. Time Machine said it was running and I believed it. Those turn out to be two different questions and only one of them is easy to check.

Why bother: the iPods

There's a reason for all of this and it isn't nostalgia. Everything in the library syncs to three iPod Classics, the last iPods Apple made with a hard drive and no internet connection at all, plus a couple of iPod Touches.

So a record I rip goes into the library and then onto a Classic that plays music and does nothing else. Nothing gets recommended to me. Nothing vanishes because a licensing deal expired. An album is where I left it, in the order it was meant to be in, and it stays that way whether or not I keep paying anyone.

That's the actual goal here. I want owning music to be as easy as renting it.

Building it

I built this with Claude Code. What worked was going in stages instead of asking for the whole thing at once: look at what's actually on the machines first, then figure out the transfer, then the folders, then the script.

That order mattered more than I expected. Writing the code was never the slow part. The slow part was all the stuff you can only find by poking at the real machines. The folder with the hidden suffix. The tag tool that returns nothing for a file you just wrote. The backup drive quietly throwing away history. None of that comes up if you just describe the problem, and every one of them would have broken the finished thing.

The bugs were the interesting part. Two of them were in code that read completely fine and did the opposite of what it looked like it did. Both got caught the first time it ran against real music instead of a test file. So the writing is fast and figuring out what to check is where the actual work is.

Making it hands off

It started as a command I had to remember to run. It isn't anymore. Exporting from VinylStudio is now the only thing I do.

Something watches the export folder and notices when files appear. It can't just start immediately though, because the folder changes the moment the first track is written, not the last. So it waits until the folder has stopped changing for a full minute before it does anything. It checks every file's size and modification time, not just how many files there are, because a track that's still being written doesn't create a new file, it just quietly grows.

Then it sends the album, and instead of stopping there, it waits for iTunes to actually import it and tells me. That distinction turned out to matter more than I expected. Handing the files to iTunes takes about seven seconds. iTunes noticing them and importing takes roughly another two minutes. So "it's been sent" and "it's in my library" are quite far apart, and only one of those is the thing I actually care about.

When it's done I get a notification saying which album went in and how long the whole thing took.

There's also a cleanup job that runs once a day. It goes through the folder of albums that have already been sent, asks iTunes whether it really has each one, and only then moves the local copy to the trash. Everything about it is built to keep files rather than delete them. If the old machine is unreachable, or the tags are unreadable, or iTunes only has eleven of twelve tracks, it keeps everything and tries again tomorrow. A skipped cleanup costs me some disk space. A wrong one costs me a recording.

Watching it from the menu bar

Once it was all running by itself I realised I had no idea whether it was actually running by itself. So I built a small app that sits in the menu bar and tells me.

It shows what's waiting to send, whether anything failed to import, whether the two background jobs are actually loaded, and when each of them last ran. It also reaches over to the old MacBook Pro and reports how long it's been up, how long iTunes has been open, disk space, when the last backup finished, and the CPU temperature and fan speeds.

Getting temperatures was the fiddly bit. The normal tool for it needs admin rights, which I didn't want a background app asking for. So there's a small C program on the old machine that reads the sensors directly through IOKit, compiled on the machine itself. It doesn't need any privileges at all. As I write this the old laptop is sitting at 48°C with both fans at about 2000 rpm, which for a fourteen year old machine running full time in a closed lid seems fine.

The icon changes shape depending on whether anything needs attention, so most of the time I never open it. Which is the point.

Where it's at now

Since then the recording side has its own app too: GrooveKeeper, started by Codex and finished by Claude, stages an album for this pipeline from one menu item.

I export an album from VinylStudio and then forget about it. A couple of minutes later a notification on the Mac tells me it's in the library. A week after that the local copy cleans itself up, but only once iTunes has confirmed it really has the album. If anything goes wrong the menu bar icon changes and I go look.

I still have the manual commands, and I still use them when I want to watch it work. But the normal case is now that I don't think about any of it, which was the whole point.