-
-
Save EmmyGraugans/40c1f1e3c91f48a353b4bfd46a1bd5c6 to your computer and use it in GitHub Desktop.
Converts M4A to MP3 respecting the original bitrate (uses ffmpeg)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Takes a directory as parameter and converts everything inside it | |
# from M4A to MP3, respecting the bitrate, and creating a directory | |
# for the converted files. | |
# | |
# MIT Licensed by Gwyneth Llewelyn (2022) | |
# | |
# Based on https://superuser.com/a/1211902/127382 by @jbowman (2017) | |
if [ -d "${1}" ] | |
then | |
echo "Doing conversions from directory \"${1}\"..." | |
else | |
echo "Source directory not found! Please add it as a parameter, e.g.:" | |
echo " ${0} path/to/album/containing/mp3/files" | |
exit 1 | |
fi | |
# Get the album's name from the first parameter | |
ALBUM_PATH="${1}" | |
ALBUM=$(basename "${ALBUM_PATH}") | |
echo "Attempting to process album \"${ALBUM}\" in source directory | |
\"${ALBUM_PATH}\"..." | |
# Create a directory for this run | |
mkdir -p "mp3s" | |
# Check if mkdir succeeded | |
if [[ $? -ne 0 ]] | |
then | |
echo "Could not create directory mp3s/${ALBUM} for output. Exiting..." | |
exit 2 | |
fi | |
# Loop across the filnames in that directory that end in *.m4a, invoke | |
# ffprobe to extract the bitrate, then use ffmpeg to convert it into MP3 | |
# and place the result inside the mp3s/${ALBUM}/ directory: | |
transcode_file() { | |
f=$1 | |
p=${f%/*} | |
ALBUM=${p##*/} | |
[ -d "mp3s/$ALBUM" ] || { | |
echo "=====================================" | |
echo "starting album $ALBUM" | |
echo "=====================================" | |
mkdir "mp3s/$ALBUM" | |
} | |
orgbitrate=$(ffprobe -v quiet -of flat=s=_ -show_entries format=bit_rate "${f}" | sed 's/[^0-9]*//g') | |
[[ orgbitrate > 229376 ]] && bitrate=224k || bitrate=$orgbitrate | |
new_filename=$(basename "${f}" .m4a).mp3 | |
printf "Reading %s\n\tand writing to %s\n\twith bitrate %s... (original: %s)\n" \ | |
"$f" "mp3s/${ALBUM}/${new_filename}" "$bitrate" "$((orgbitrate / 1024))k" | |
ffmpeg -v warning -y -i "${f}" -codec:a libmp3lame -b:a "${bitrate}" -q:a 2 "mp3s/${ALBUM}/${new_filename}" | |
} | |
find ${ALBUM_PATH} -name "*.m4a" | while read m4a | |
do | |
transcode_file "$m4a" < /dev/null | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Use default=nk=1:nw=1 (no key, no wrappers) in place of flat=s=_ in the -of (output format) for ffprobe to get only the value and remove the need for the sed substitution.
ffprobe -v quiet -of default=nk=1:nw=1 -show_entries format=bit_rate "${f}"