A GUI application for batch-converting audio files between FLAC, ALAC, WAV, AIFF, AAC and MP3 using ffmpeg, preserving the original folder structure.
Formerly "FLAC Converter". Renamed when multi-format output was added.
- Six output formats: FLAC, ALAC (.m4a), WAV, AIFF, AAC (.m4a), MP3
- Drag and drop: drop files or folders straight onto the window
- Multiple folders: on macOS the folder chooser takes several at once (shift-click or cmd-click); elsewhere it asks whether you want to add another after each one
- Background folder scanning: large folders are scanned off the UI thread, with live progress and Esc to cancel
- Folder structure preservation: output mirrors the input hierarchy
- Save in place: optionally write converted files next to their originals
- Skip files already in the target format, marked as Skipped in the list
- Move originals to Trash after conversion is verified (optional, off by default)
- Cover art and tags preserved where the output container supports them
- Cancel mid-run: the Start button becomes In Progress and stops the job when clicked
- De-duplication: adding the same folder twice will not queue anything twice
- Readable failures: destination folders are checked for writability before a run, and every failure reports its reason
| Format | Extension | Encoder | Settings |
|---|---|---|---|
| FLAC | .flac |
flac | -compression_level 8 (lossless, smallest) |
| ALAC | .m4a |
alac | Apple Lossless (lossless, plays natively on Apple devices/iTunes) |
| WAV | .wav |
pcm_s16le | 16-bit PCM |
| AIFF | .aiff |
pcm_s16be | 16-bit PCM |
| AAC | .m4a |
aac | 256 kbps |
| MP3 | .mp3 |
libmp3lame | 320 kbps |
Only formats your ffmpeg build can actually encode appear in the dropdown.
Two things have to be on your computer before Audio Converter will run. Both are one-line installs.
- ffmpeg — this is the program that actually converts the audio. On macOS:
brew install ffmpeg - Python 3.9 or newer, with tkinter — this draws the app's window. Most Macs
already have Python, but the window part is often missing. On macOS:
brew install python-tk
If you don't have Homebrew (the brew command), install it first from
brew.sh.
Everything else the app needs is installed for you in the next step.
Get the project with git clone, not the GitHub "Download ZIP" button. A zip
extracts with a macOS quarantine flag on every file, which blocks the app icon
below from running at all (it can still run from Terminal, but skip the hassle):
git clone https://github.com/raymassie/AudioConverter.git
cd AudioConverterThen:
- Open Terminal in that folder (the
cdabove already did this if you're following along, otherwise typecd, with a space, then drag the folder onto the Terminal window and press Return). - Type
./setup.shand press Return.
setup.sh checks that Python and ffmpeg are present, creates a self-contained
venv folder for the app's own dependencies, and installs them there. It does not
touch anything else on your system. If you see "permission denied", run
chmod +x setup.sh first and try again.
You only ever do this once per machine.
From Terminal, from inside the folder:
./run_app.shThe easy way, once it's set up: double-click Audio Converter.app, which
setup.sh leaves in the same folder. That's the app icon. No Terminal window,
nothing to type. This only works because you cloned rather than downloaded a
zip — see above.
To keep it handy, right-click it and choose Make Alias, then drag the alias to your Dock or your Applications folder. Use an alias, not a copy. The app is a thin launcher that runs the Python file sitting next to it, so a copy moved somewhere else can't find it and will tell you so rather than starting.
Running the Python directly, useful if something is going wrong and you want to see the error messages:
venv/bin/python audio_converter_app.pyUse venv/bin/python rather than plain python3 here. The venv folder is where
setup put the app's dependencies, so plain python3 will usually complain that
tkinterdnd2 is missing.
If the app ever fails to start on the very first launch, it writes what went wrong
to /tmp/audio_converter_setup.log.
- Add files: drag files or folders onto the window, or use Select for a file or folder chooser. On macOS the folder chooser is the native panel and accepts multiple folders at once via shift-click or cmd-click; on other platforms Tk allows only one per dialog, so you are asked whether to add another after each. Folders are scanned recursively in the background; press Esc to cancel a scan that is taking too long.
- Choose an output location: click Destination, or tick Save to same folder as originals.
- Pick a format from the dropdown.
- Start. The button reads In Progress during the run; click it to stop after the current file. It reads Complete when the job finishes.
Select a row and press Delete or Backspace to remove it from the list. Double-click a row to see its full status, source and destination paths, and any error.
Delete original files moves each source file to the Trash, but only after the conversion has been verified: ffmpeg exited cleanly, the output file exists, and it is not zero bytes. Files that were skipped or that failed are never deleted.
On macOS this uses Finder via osascript if send2trash is not installed. On other
platforms send2trash is required; without it the originals are kept and the status
column says so.
The common root of everything you add is calculated, and each file's path relative to that root is recreated under the destination.
Input:
Music/
├── Artist1/
│ ├── Album1/song1.m4a
│ └── Album2/song3.m4a
└── Artist2/Album2/Disc1/song2.m4a
Output:
converted/
├── Artist1/
│ ├── Album1/song1.flac
│ └── Album2/song3.flac
└── Artist2/Album2/Disc1/song2.flac
If any file fails, a dialog lists each one with its reason, and the full list is written
to ~/audio_converter_last_run.log. Double-click a row for that file's error.
Before a run starts, every destination folder is probed with a real test write. Folders
that cannot be written to are named up front and you choose whether to continue. This
catches read-only folders that os.access() reports as writable because of ACLs.
- Skipping is by file extension, not by codec, and ALAC and AAC share an extension.
Both live in
.m4a, and there is no way to tell them apart by filename alone. So an.m4afile -- whichever codec it actually holds -- is treated as already-done and Skipped when either AAC or ALAC is the target. If you specifically need to convert AAC to ALAC (or the reverse), check a converted file's actual codec afterward (Get Info in Finder, orffprobe), since the app cannot verify this for you. - Conversion is serial. One ffmpeg process at a time regardless of core count.
- WAV and AIFF cannot carry cover art. Art is stripped for those targets. Tags are preserved where the container supports them.
- Cancel stops between files in the common case. If ffmpeg is mid-file it is killed and the partial output is removed, but this path is less exercised than the rest.
- Files are converted at a per-file timeout of 15 minutes; anything slower is killed and marked Failed.
- A single folder scan stops at 20,000 audio files. Hidden directories,
node_modules,~/Libraryand system paths such as/Systemand/privateare skipped, and symlinks are not followed. Picking a drive root or your home folder prompts for confirmation first, because scanning either one is rarely what you meant.
ffmpeg not found — brew install ffmpeg, then restart the app.
Drag and drop does nothing — tkinterdnd2 is missing. pip install tkinterdnd2,
or use the Select button. The status bar says which state you are in at launch.
No module named tkinter — your Python was built without Tk. On macOS with Homebrew,
brew install python-tk.
App quits instantly, or crashes with Tcl_Panic / TkpInit — you're on the old
Tcl/Tk 8.5 that ships with macOS's Command Line Tools Python, which is known to crash
on newer macOS versions. Install Python from
python.org/downloads/macos instead (it
bundles a working Tk 8.6), then rebuild the venv against it:
rm -rf venv
/Library/Frameworks/Python.framework/Versions/3.*/bin/python3 -m venv --system-site-packages venv
venv/bin/python -m pip install -r requirements.txtEvery file failed, or "Permission denied" — the destination folder is read-only.
This is common with album folders imported by other software: the folder can be mode
r-xr-xr-x even though the audio files inside it are writable. In Finder, select the
folder, press Cmd-I, and unlock it under Sharing & Permissions. Or from a terminal:
chmod u+w "/path/to/folder". To find every locked folder under a library:
find ~/Music -type d ! -perm -u+w.
Originals were not deleted — the conversion failed verification, the file was skipped, or Trash was unavailable. The status column and status bar say which.
MIT. See LICENSE.