Attaching a cover image to a handful of MP3s usually means uploading the files to a web service, signing in with a Google account, or sitting through an ad for a "DRM-free converter." The work itself is about four lines of ffmpeg. This is those four lines wrapped in a SwiftUI window.
tunes2tube-mac is a macOS app (13+) that does one thing. A cover image goes in one drop slot, one or more audio files in another, album / artist / year in an optional metadata form, and ⌘↩ writes out .mp3 files with the cover embedded as an ID3v2 APIC frame. The cover image is also copied into the output folder as a standalone album-art file. Output goes to ~/Music/Tunes2Tube/<Album-or-Artist>/ by default. Input that is already an MP3 has its audio stream copied with no re-encode; anything else is encoded with libmp3lame at 320 kbps.
The name is a nod to tunes2tube.com, the web tool this replaces. The original publishes the resulting video to YouTube, which requires a Google OAuth client and a registered GCP project. The project brief drops anything that needs GCP, so the YouTube piece is gone and the app's contract is limited to producing tagged files. For publishing, the README carries the one-line ffmpeg command that turns an MP3 plus cover into a still-image video, uploaded separately.
There is not much to it. The UI is a SwiftUI window with two drop zones and a small metadata form. A @MainActor view model (ProcessingSession) holds the state and drives AudioProcessor, a thin wrapper around Foundation.Process that shells out to ffmpeg. ffmpeg does the real work: read the audio, attach the cover as an APIC frame, write the MP3. The app looks for the binary at /opt/homebrew/bin/ffmpeg, /usr/local/bin/ffmpeg, or via which ffmpeg, and surfaces a clear error when it finds none rather than reporting a successful run.
Audio formats accepted, all producing MP3 out: mp3 wav flac m4a aac aiff ogg opus. Cover formats: .png, .jpg, .webp. A per-file failure does not kill the batch. Each track gets its own result, and the UI reports which ones succeeded.
A Makefile wraps swift build to produce a real .app bundle (Info.plist, ad-hoc codesigned). It is not notarized, because that costs $99/year.
Small project, same habit as the Private Whisper privacy work, which is the longer version of the argument. The recurring pattern is an entirely mechanical task (transcribe audio, embed cover art, convert a file) that has perfectly capable local tooling on macOS, while the easiest discoverable option on Google is a website that wants the files on someone else's disk. There is no good reason an MP3 tagger should leave the machine it runs on, so when the local options are unfriendly or abandoned, the fix is to write the SwiftUI shell.
It is an MVP. The roadmap in the README lists per-track title editing (titles currently come from the filename), a bitrate toggle for re-encoded inputs, an optional video output for the YouTube workflow without the GCP piece, a universal binary release in GitHub Releases, and possibly Sparkle auto-update.