Skip to content

Instantly share code, notes, and snippets.

@kernc
Last active April 30, 2016 11:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kernc/f448b6cc369ebac5e6310c98ff868f07 to your computer and use it in GitHub Desktop.
Save kernc/f448b6cc369ebac5e6310c98ff868f07 to your computer and use it in GitHub Desktop.
Increase the volume -- and impair the quality -- of your audiobooks
#!/bin/bash
set -e
if [ $# != 0 ]; then
echo "Usage: $(basename "$0")
This program accepts no arguments. It takes all the *.mp3 files
in the current directory and makes them louder by first detecting
their mean and max volumes and then amplifying the mean volume by
half of mean or max (whichever is greater). So it clips the samples
that are over the peak possible volume (-0dB) -- i.e. some
information lost.
Works well enough with audio books. So you can enjoy them even while
commuting in heavy traffic.
It optionally creates an m3u playlist."
exit 0
fi
for prog in ffmpeg awk; do
if ! command -v $prog >/dev/null; then
echo "ERROR: missing command '$prog'. Install package '$prog'."
exit 1
fi
done
if [ ! "$(ls ./*.mp3 2>/dev/null)" ]; then
echo "No .mp3 files in current directory. Nothing to do."
exit 2
fi
OUT="$(pwd)/louder"
mkdir -p "$OUT"
ffmpeg="ffmpeg -hide_banner -nostats"
for file in *.mp3; do
echo "Processing file: '$file'"
echo -n ".. detecting mean volume "
read mean_volume max_volume < <(
$ffmpeg -i "$file" -af volumedetect -f null - |&
awk -F'[: ]' '/_volumedetect_.*(mean|max)_volume/{ print $6 }' |
xargs)
echo "(mean: ${mean_volume}dB, max: ${max_volume}dB)"
volume_change=$(awk "BEGIN { print ($mean_volume/2 < $max_volume) ? -($mean_volume/2) : -($max_volume) }")
echo ".. increasing volume by ${volume_change} dB"
$ffmpeg -loglevel error -y -i "$file" -af "volume=${volume_change}dB" -b:a 64k "$OUT/$file"
done
echo "Louder files written to ./$OUT/"
echo
echo "Do you want to create a playlist?"
echo "Type the playlist name to create an m3u playlist, otherwise just pres Return."
echo
read -p "Playlist name []: " playlist
if [ ! "$playlist" ]; then
exit 0
fi
playlist="$(echo "$playlist" | sed -E 's/[^[:alnum:]]/_/g')"
mkdir -p "$OUT/$playlist"
mv "$OUT"/*.mp3 "$OUT/$playlist"
(cd "$OUT";
ls "$playlist"/*.mp3 > "$playlist.m3u" )
echo "Done."
echo
echo "Playlist created as: '$OUT/$playlist.m3u'"
echo "Files are in: '$OUT/$playlist/'"
echo "(You need to copy both.)"
echo
echo "Good day!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment