Harness the Combinatoric Power of Command-Line Tools and Utilities

../Tutorials

Convert FLAC to MP3 using the CLI

Bash scripts

Published December 27, 2022 and last verified on March 9, 2024

Warning

❗ This article is more than six months old. Some things may not work as written.

If you’ve downloaded an album from your favorite artist in a lossless format like FLAC but need to produce MP3 files so you can use them in a portable player or upload them to a music service, you can use a little Bash scripting and some CLI tools to convert the files quickly.

In this tutorial you’ll use the flac and lame command-line tools to transcode the files. You’ll write a Bash script to capture the metadata from the FLAC file and add it to the MP3 you create.

What You Need

To complete this tutorial on macOS, you’ll need Homebrew installed, which you can do by following the Install Homebrew tutorial.

Install the tools

You’ll need both the flac and lame command-line tools.

On macOS, you can use Homebrew to install flac with the following command:

brew install flac

To install lame, execute this command:

brew install lame

On Ubuntu, you’ll use the apt package manager to install both. First update your list of sources:

sudo apt update

Then install both flac and lame:

sudo apt install -y lame  flac

With both tools installed, you can write a script to decode the FLAC file and convert it to an MP3.

Create the Script

Create the file ~/bin/flac2mp3 and add the following contents to the file which read through a list of files, extract any metadata from the files, and convert the file to an MP3:

#!/usr/bin/env bash

for f in "$@"
do
    [[ "$f" != *.flac ]] && continue
    album="$(metaflac --show-tag=album "$f" | sed 's/[^=]*=//')"
    artist="$(metaflac --show-tag=artist "$f" | sed 's/[^=]*=//')"
    date="$(metaflac --show-tag=date "$f" | sed 's/[^=]*=//')"
    title="$(metaflac --show-tag=title "$f" | sed 's/[^=]*=//')"
    year="$(metaflac --show-tag=date "$f" | sed 's/[^=]*=//')"
    genre="$(metaflac --show-tag=genre "$f" | sed 's/[^=]*=//')"
    tracknumber="$(metaflac --show-tag=tracknumber "$f" | sed 's/[^=]*=//')"
    flac --decode --stdout "$f" | lame --preset extreme --add-id3v2 --tt "$title" --ta "$artist" --tl "$album" --ty "$year" --tn "$tracknumber" --tg "$genre" - "${f%.flac}.mp3"
done

The script loops over all of the arguments passed in, which should be a list of files. It then extracts the metadata like the title, artist, and track number from existing information in the FLAC file. It then decodes the file and sends the output to lame, using the extracted metadata as inputs. The new file will be saved with the same name, but with the .mp3 extension.

Save the file.

Now make the script executable so you can run it without specifying the interpreter:

chmod +x ~/bin/flac2mp3

You can now try the script out.

Convert the Files

Run the script on a Flac file by passing the file to the script you created:

~/bin/flac2mp3 myfile.flac

This produces an MP3 file with the metadata preserved:

flac 1.3.4
Copyright (C) 2000-2009  Josh Coalson, 2011-2016  Xiph.Org Foundation
flac comes with ABSOLUTELY NO WARRANTY.  This is free software, and you are
welcome to redistribute it under certain conditions.  Type `flac' for details.

myfile.flac: done
LAME 3.100 64bits (http://lame.sf.net)
polyphase lowpass filter disabled
Encoding <stdin> to myfile.mp3
Encoding as 44.1 kHz j-stereo MPEG-1 Layer III VBR(q=0)

The script supports multiple files too, so you can pass them by separating each file with a space:

~/bin/flac2mp3 myfile.flac my_other_file.flac

If you have a whole directory of files to convert, this can be cumbersome. Instead of passing every file in manually, use the find command with its -exec argument to build up the file list:

find . -name "*.flac" -exec bash ~/bin/flac2mp3 {} +

This searches for all the flac files in the current directory and uses the -exec option to run the script. The {} symbols are the placeholder for the filename to use, and the + sign combines the arguments into a single argument rather than running the script once per file. Remember, the script accepts multiple files.