Skip to content

Instantly share code, notes, and snippets.

@stvhay
Last active June 23, 2023 20:17
Show Gist options
  • Save stvhay/985f30d1e1a688b741e68a3109214a1c to your computer and use it in GitHub Desktop.
Save stvhay/985f30d1e1a688b741e68a3109214a1c to your computer and use it in GitHub Desktop.
FLAC 2 ALAC
#!/bin/bash
# get cover art using sacad. try only once.
function get_cover_art() {
local artist="$1"
local album="$2"
local dstdir="$3"
local albumdir="${dstdir}/${artist}/${album}"
local artfile="${albumdir}/${artist} - ${album}.png"
local tryfile="${albumdir}/.no-art"
mkdir -p "$albumdir"
if [[ ! -f "$artfile" && ! -f "$tryfile" ]]; then
echo "Downloading art for album: $album"
sacad "$artist" "$album" 600 "$artfile" 2> /dev/null
touch "$tryfile"
fi
}
# check if an existing file has cover art using ffprobe
function has_cover_art() {
local file=$1
local cover_art=$(ffprobe -v error -select_streams v -show_entries stream=codec_name -of default=nw=1:nk=1 "$file")
if [[ $cover_art == 'mjpeg' ]] || [[ $cover_art == 'png' ]]; then
return 0
else
return 1
fi
}
# convert from flac to alac (m4a). Place in album dir. albumart argument is optional.
function flac_alac() {
local flacfile="$1"
local albumdir="$2"
local albumart="$3"
if has_cover_art "$flacfile"; then # keep existing album art
ffmpeg -y \
-i "$flacfile" \
-map 0:a -map 0:v \
-c:v copy -c:a alac -disposition:v:0 attached_pic \
"${albumdir}/$(basename "${flacfile%.flac}.m4a")"
elif [[ $albumart ]]; then
ffmpeg -y \
-i "$flacfile" \
-i "$albumart" \
-map 0:a:0 -map 1 \
-c:v copy -c:a alac -disposition:v:0 attached_pic \
"${albumdir}/$(basename "${flacfile%.flac}.m4a")"
else # just the audio
ffmpeg -y \
-i "$flacfile" \
-map 0:a:0 \
"${albumdir}/$(basename "${flacfile%.flac}.m4a")"
fi
}
# globals
# expected srcdir format is srcdir/artist/album/file
srcdir="$1"
ext="flac"
dstdir="$HOME/Music"
mkdir -p $dstdir
for file in ${srcdir}/**/*.${ext}; do
# validate the file name
if [[ $file =~ .*[[:space:]]-[[:space:]].*[[:space:]]-[[:space:]].*[[:space:]]-[[:space:]].* ]]; then
# File format: artist - album - track - song.${ext}
# (.*/)?(.*) - (.*) - (.*) - (.*)\.${ext}
artist="$(echo $file | sed -E 's|(.*/)?(.*) - (.*) - (.*) - (.*)\.'${ext}'|\2|')"
album="$( echo $file | sed -E 's|(.*/)?(.*) - (.*) - (.*) - (.*)\.'${ext}'|\3|')"
track="$( echo $file | sed -E 's|(.*/)?(.*) - (.*) - (.*) - (.*)\.'${ext}'|\4|')"
song="$( echo $file | sed -E 's|(.*/)?(.*) - (.*) - (.*) - (.*)\.'${ext}'|\5|')"
# create a directory if needed
mkdir -p "${dstdir}/${artist}/${album}"
# fetch album art if missing
get_cover_art "$artist" "$album" "$dstdir"
# convert file
echo "$file"
echo "${dstdir}/${artist}/${album}"
echo "${dstdir}/${artist}/${album}/${artist} - ${album}.png"
if [[ -f "${dstdir}/${artist}/${album}/${artist} - ${album}.png" ]]; then
flac_alac \
"$file" \
"${dstdir}/${artist}/${album}" \
"${dstdir}/${artist}/${album}/${artist} - ${album}.png"
else
flac_alac \
"$file" \
"${dstdir}/${artist}/${album}"
fi
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment