Convert a directory of FLAC files to MP3 files.

Home   »   Convert a directory of FLAC files to MP3 files.

#!/usr/bin/env bash
# convert-FLAC-to-MP3.sh
# Convert a directory of FLAC files to MP3 files.
# Copyright 2021 by Donald R Anderson
# https://donaldranderson.com
set -euo pipefail
IFS=$'\n\t'
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
###################

BITRATE=320k
RECURSE='no'
OVERWRITE='no'

# Usage
print_usage(){
cat << EOF

    Convert a directory of FLAC files to MP3 files.

    $(basename "${BASH_SOURCE[0]}") [opts]  []

Where:
      The directory contains the FLAC files. 
     The directory where the MP3 files will be written.
                       Defaults to  if not specified. 

Opts:
    -h Print help.
    -r Recurse directory tree.
    -w Overwrite the MP3 if it exists.

EOF
exit "$1"
}

# Convert file
convert_file(){ #args: in-file-path, out-file-path
    ffmpeg -y -i "$1" -ab ${BITRATE} -map_metadata 0 -id3v2_version 3 "$2"  >/dev/null 2>&1
}

# Do directory
do_directory(){ #args: out-dir-path
    local flac
    local newfile
    for flac in ./*.flac; do
        if [ -f "$flac" ]; then
            newfile="$1/$(basename "$flac" .flac).mp3"
            if [ "$OVERWRITE" == 'yes' ] || [ ! -f "$newfile" ]; then
                echo "$newfile"
                convert_file "$flac" "$newfile"
            else
                echo "MP3 exists, skipping: $newfile"
            fi
        fi
    done
}

# Recurse
recurse(){ #args: in-dir-path out-dir-path
    local dir 
    pushd "$1" > /dev/null
    do_directory "$2"
    for dir in "$1"/*; do
        if [ -d "$dir" ]; then
            dirname="$(basename "$dir")"
            mkdir -p "$2/$dirname"
            recurse "$1/$dirname" "$2/$dirname"
        fi
    done
    popd > /dev/null
}

# Get the options
while getopts "::wrh" opt; do
    case ${opt} in
        r) RECURSE='yes';;
        w) OVERWRITE='yes';;
        h) print_usage 0;;
        *) echo "Invalid opt: $opt"
           exit 1;;
    esac
done
shift $((OPTIND -1))

# Arg count?
if [ $# -lt 1 ]; then
    echo "Too few arguments!"
    print_usage 1 
fi

IN_DIR=$1
OUT_DIR=$1
shift

# Optional output directory
if [ $# -gt 0 ]; then
    OUT_DIR=$1
fi

# Input directory?
if [ ! -d "$IN_DIR" ]; then
    echo "The input-directory does not exist: $IN_DIR"
    print_usage 1 
fi

# Output directory?
if [ ! -d "$OUT_DIR" ]; then
    echo "The output-directory does not exist: $OUT_DIR"
    print_usage 1 
fi

if [ "$RECURSE" == 'no' ]; then
    cd "$IN_DIR"
    do_directory "$OUT_DIR"
else
    recurse "$IN_DIR" "$OUT_DIR"
fi

Leave a Reply

Your email address will not be published. Required fields are marked *