Batch Convert Audio with ffmpeg
for f in *.flac; do ffmpeg -v warning -i "$f" -map_metadata 0 -b:a 192k "${f%.flac}.mp3"; done
Inspired by this StackExchange post.
For a more complete script we can use this convert.sh bash script which includes cli options for input folder, output folder and bitrate.
#!/bin/bash
# if $1 is --help then print help message
if [ "$1" == "--help" ]; then
# print some ascii music convert art
echo "-----------------------------------------------"
echo "FLAC to MP3 Converter"
echo "-----------------------------------------------"
echo "This script converts FLAC files to MP3 format using ffmpeg."
echo "It requires ffmpeg to be installed on your system."
echo "-----------------------------------------------"
echo "Usage: $0 <input_folder> <output_folder> [bitrate]"
echo "./convert.sh /path/to/flac_files /path/to/output [bitrate]"
echo "Optional: Specify a bitrate (128, 160, 192, 256, 320) for the output files."
echo "Example: $0 /path/to/flac_files /path/to/output 192"
echo "Supports: Local paths and SMB shares (smb://server/share)"
exit 0
fi
# need folder input param and output folder param
if [ "$#" -lt 2 ]; then
echo "Error: Invalid number of arguments."
echo "Usage: $0 <input_folder> <output_folder>"
exit 1
fi
input_folder="$1"
output_folder="$2"
bitrate="192"
prefix=${4:-""}
# if prefix addd - to the end of it
if [ -n "$prefix" ]; then
prefix="${prefix}-"
fi
if [ -n "$3" ]; then
echo "Input folder: $1 Output folder: $2 Bitrate: $3 Prefix: $prefix"
else
echo "Input folder: $1 Output folder: $2 Bitrate: $bitrate (default) Prefix: $prefix"
fi
# check for user defined bitrate
if [ "$#" -ge 3 ] && [ -n "$3" ]; then
# check if the bitrate is a valid number
if ! [[ "$3" =~ ^[0-9]+$ ]]; then
echo "Error: Bitrate must be a valid number."
exit 1
fi
# check if bitrate is an actual bitrate options being 128, 160, 192, 256, 320
if [ "$3" -ne 128 ] && [ "$3" -ne 160 ] && [ "$3" -ne 192 ] && [ "$3" -ne 256 ] && [ "$3" -ne 320 ]; then
echo "Error: Bitrate must be one of the following: 128, 160, 192, 256, 320."
exit 1
fi
bitrate="$3"
fi
# create output folder if it does not exist
if [ ! -d "$output_folder" ]; then
mkdir -p "$output_folder"
if [ $? -ne 0 ]; then
echo "Error: Could not create output folder: $output_folder"
exit 1
fi
echo "Created output folder: $output_folder"
fi
# ehoc the full path of the input and output folders
echo "Input folder: $(cd "$input_folder" && pwd)"
echo "Output folder: $output_folder"
audio_ext="mp3"
# get the extension of the input files it could be flac or mp3 or m4a
for ext in "flac" "mp3" "m4a" "ogg"; do
shopt -s nullglob
files=("$input_folder"/*."$ext")
if [ ${#files[@]} -eq 0 ]; then
echo "No .$ext files found in $input_folder"
else
echo "Found ${#files[@]} .$ext files in $input_folder"
audio_ext="$ext"
break
fi
shopt -u nullglob
done
for f in "$input_folder"/*."$audio_ext"; do
echo "Processing file: $f"
out_file="${f##*/}"
out_file="${out_file%.*}" # remove extension
out_file="${out_file//./‐}" # replace dots with dashes
out_file="${prefix}${out_file// /-}.mp3" # replace spaces with dashes
ffmpeg -v warning -i "$f" -vn -map_metadata 0 -b:a "$bitrate"k "$output_folder/$out_file"
if [ $? -ne 0 ]; then
echo "Error processing file: $f"
continue
fi
echo "Successfully converted ${output_folder}/$out_file"
done