Convert FLAC to MP3

Related articles
Convert any Movie to DVD Video
This article outlines different ways to transcode from FLAC to MP3. FLAC is a lossless audio format, so it is better for archival purposes, but it also takes up more disk space. The idea is to compress the files without creating a perceived loss in fidelity.
Packages
audiotools
AUR
- Transcode between different formats and keep tags with
track2track
, can encode from CDDA with
cdda2track
, has an optional Ncurses GUI.
flac2all
AUR
- Multi-threaded conversion of flac to 70+ other formats retaining all tags and metadata.
whatmp3
AUR
- A small Python script that accepts a list of directories containing FLAC files as arguments and converts them to MP3 with the specified options.
Graphical applications
SoundConverter
— A dedicated audio transcoding utility built for the
GNOME
desktop and relying on GStreamer. It can make use of
GNOME Audio Profiles
and features multithreaded conversions. It can also extract the audio from videos.
https://soundconverter.org/
||
soundconverter
soundKonverter
— A Qt graphical frontend to various audio manipulation programs. Features conversion, ripping and other audio manipulation functionalities.
https://github.com/HessiJames/soundkonverter/wiki
||
soundkonverter
AUR
WinFF
— A GUI for the powerful multimedia converter FFmpeg. Features dedicated profiles for audio transcoding.
https://github.com/WinFF/winff/
||
winff-gtk3
AUR
,
winff-qt6
AUR
Usage
In these two examples, FLAC files in current directory are encoded by the LAME MP3 encoder. Both scripts pass the ID3 tags from the FLAC files to the resulting MP3 files, and encode to MP3 V0. V0 results in a variable bitrate usually between 220-260 kbps. The audio of a V0 file is transparent, meaning one cannot tell the difference between the lossy file and the original source (compact disc/lossless), but yet the file size is significantly reduced. For more information on LAME switches/settings such as V0, visit the
Hydrogenaudio LAME Wiki
.
The original
.flac
files are not modified and the resulting
.mp3
s will be in the same directory. All files with extensions not matching
*.flac
in the working directory (
.nfo
, images,
.sfv
, etc.) are ignored.
For ease of use, add the script to your
PATH
. Open up a terminal,
cd
to the directory of FLAC files that you wish to convert, and invoke
flac2mp3
(or whatever you named the script). You will see the verbose decoding/encoding process in the terminal which may take a few moments. Done! At this point, it is trivial to
mv *.mp3
all your new MP3s wherever you wish.
With FFmpeg
Chances are, your system already has
FFmpeg
installed, which brings in the
flac
and
lame
packages. FFmpeg has all the encoding and decoding facilities built in to do the job.
#!/bin/bash

for a in ./*.flac; do
  < /dev/null ffmpeg -i "$a" -qscale:a 0 "${a[@]/%flac/mp3}"
done
Parallel version
Since LAME is a single-threaded encoder, conversion can be accelerated by encoding multiple files concurrently on multiple cores. To do this,
install
the
parallel
package, and run:
parallel ffmpeg -i {} -qscale:a 0 {.}.mp3 ::: ./*.flac
Parallel with recursion
Fd is a fast, user-friendly alternative to
find
. This one liner avoids the "while read" loop, which may have performance implications according to a response on Stack Exchange.
[1]
Install
fd
first, then run:
fd -t f -e flac -x ffmpeg -i "{}" -qscale:a 0 "{.}.mp3"
Makefile for incremental recursive transcoding
Warning
Makefiles do not handle spaces correctly, see
[2]
for details.
Besides transcoding in parallel with
make -j$(nproc)
, this has the added benefit of not regenerating transcoded files that already exist on subsequent executions:
SOURCE_DIR := flacdir
XCODE_MP3_DIR := mp3dir
# NOTE: see lame -v option for quality meaning
XCODE_MP3_QUALITY := 0

# Find .flac sources and determine corresponding targets
flac_srcs := $(shell find $(SOURCE_DIR) -type f -name '*.flac')
flac_2_mp3_tgts := $(patsubst $(SOURCE_DIR)/%.flac, $(XCODE_MP3_DIR)/%.mp3, \
    $(flac_srcs))

.PHONY: all mp3 flac_2_mp3

all: mp3 

mp3: flac_2_mp3

flac_2_mp3: $(flac_2_mp3_tgts)

$(XCODE_MP3_DIR)/%.mp3: $(SOURCE_DIR)/%.flac
        @echo "converting -> $@"
        @mkdir -p "$(@D)"
        @ffmpeg -v error -i "$<" -codec:a libmp3lame \
            -q:a $(XCODE_MP3_QUALITY) "$(@)"
Without FFmpeg
If for some reason FFmpeg is not installed and you do not want to install it, you still need to have
flac
and
lame
installed. Here, the tagging process is more explicit using the metadata utility that comes with
flac
and passing the information to
lame
. The process duration will slightly increase since FLACs must first be decoded to WAVE and then fed into the MP3 encoder.
#!/bin/bash

for a in ./*.flac; do
  # give output correct extension
  OUTF="${a[@]/%flac/mp3}"

  # get the tags
  ARTIST=$(metaflac "$a" --show-tag=ARTIST | sed s/.*=//g)
  TITLE=$(metaflac "$a" --show-tag=TITLE | sed s/.*=//g)
  ALBUM=$(metaflac "$a" --show-tag=ALBUM | sed s/.*=//g)
  GENRE=$(metaflac "$a" --show-tag=GENRE | sed s/.*=//g)
  TRACKNUMBER=$(metaflac "$a" --show-tag=TRACKNUMBER | sed s/.*=//g)
  DATE=$(metaflac "$a" --show-tag=DATE | sed s/.*=//g)

  # stream flac into the lame encoder
  flac -c -d "$a" | lame -V0 --add-id3v2 --pad-id3v2 --ignore-tag-errors \
    --ta "$ARTIST" --tt "$TITLE" --tl "$ALBUM"  --tg "${GENRE:-12}" \
    --tn "${TRACKNUMBER:-0}" --ty "$DATE" - "$OUTF"
done
Recursively
A useful extension of the above scripts is to let them recurse into all subdirectories of the working directory. To do so, replace the first line (
for .... do
) with:
find -type f -name "*.flac" -print0 | while read -d $'\0' a; do
See also
https://www.xiph.org/flac/
Wikipedia:FLAC
https://lame.sourceforge.net/
https://wiki.hydrogenaudio.org/index.php?title=Flac
- More information on FLAC.
CUE Splitting
to split a single FLAC with cue sheet into multiple audio files