How to resample MP3 audio files on Linux using LAME
If you're like me, you're not willing to shell out several hundred dollars to buy an 80GB iPOD to carry and store your music collection. In my case, I chose the 4GB Sansa e260 as my music player. Having ripped my music at high bitrates for improved quality, I soon became dissatisfied with the capacity of my player. At that point, I decided to do some experimenting with LAME's different encoding options in order to determine what settings gave me the minimum file size while providing acceptable sound quality. For me, LAME's variable bit rate preset 5 provides a good compromise between sound quality and file size.
After determining my optimal file quality, I basically had two choices:
- Rip all of my CD's using these new settings, or
- Figure out a way to re-encode my existing files to the new bitrate.
Well, it turns out that LAME provides an easy option to resample mp3's without having to convert back to .wav first.
I'm using Ubuntu Linux, so these instructions should work for most Debian based Linux Distro's. The first step is to make sure that you have the required packages installed on your system. The packages you'll need for this process are lame and python-mutagen (which contains mid3v2). You can add them using one of the available graphical package managers, or from the terminal using apt-get.
The LAME program doesn't provide a graphical interface, so we'll have to work in the terminal. Here's the basic command to resample a song.
This command does a great job of resampling and likely shrinking your mp3 file, but there are two drawbacks:
- Due to a bug (or missing feature) in the LAME code, the id3 tags are not copied into the resampled file. This means that it will show up in your player as Unknown Song by Unknown Artist.
- It's a pain to type this command hundreds of times to resample all of your music.
Because of the two problems above, I decided to write a script to automate the process. I actually ended up writing two scripts. The first script, mp3shrink, acts as the main program. It reads all of the mp3 files in a directory and feeds them to the second script, cptag, for resampling and copying the id3 tags.
I suggest placing the scripts in your private bin directory(~/bin). If you don't have one, just create it with:
mkdir bin
So, here's the mp3shrink script. Copy the text and paste it into a text editor and save it as /home/myID/bin/mp3shrink.
#!/bin/bash
#
#mp3shrink - A script to resample all mp3 files in a
# directory. This script calls the cptag script which
# must also be in the user's path. cptag depends upon
# lame and mid3v2 (mid3v2 can be found in the
# python-mutagen package).
#
# It is suggested that both the mp3shink and cptag
# scripts be placed in the user's private bin (~/bin).
######################################################
# List mp3's in current directory.
ls *.mp3 > mp3_list
ls *.MP3 >> mp3_list
# Parse the mp3_list and replace spaces with escaped spaces.
sed -i 's: :\\ :g' mp3_list
# Check if resample directory exists and create it if it doesn't.
if
test -e ./resample
then
echo "resample directory/file already exists - delete it? (Y/n)"
read reply
if
[ "$reply" != "n" ]
then
rm -r resample
mkdir resample
else
exit
fi
else
mkdir resample
fi
# Resample each mp3 and write tags using the cptag script
cat mp3_list |while read song
do
echo "$song"
cptag "$song"
done
#clean up
if
test -e mp3_list
then
rm mp3_list
fi
if
test -e tag2.txt
then
rm tag2.txt
fi
exitOK, here's cptag. Paste the following text and save as /home/myID/bin/cptag.
#!/bin/bash # #cptag - A script to resample mp3 files with LAME and # copy id3v2 tags from the old file to the new one. # ##################### # Read id3 tags and write to file mid3v2 -l "$1" > tag2.txt # Resample music file lame -V5 --vbr-new --resample 44.1 "$1" "resample/$1" # Set value of variable 'title' if grep TIT2= tag2.txt > /dev/null #Test if title tag exists then title=`grep TIT2= tag2.txt | sed "s:TIT2=::"` echo $title else echo "Title tag does not exist." fi # Set value of variable 'album' if grep TALB= tag2.txt > /dev/null #Test if album tag exists then album=`grep TALB= tag2.txt | sed "s:TALB=::"` echo $album else echo "Album tag does not exist." fi # Set value of variable 'artist' if grep TPE1= tag2.txt > /dev/null #Test if artist tag exists then artist=`grep TPE1= tag2.txt | sed "s:TPE1=::"` echo $artist else echo "Artist tag does not exist." fi # Set value of variable 'track' if grep TRCK= tag2.txt > /dev/null # Test if track tag exists then track=`grep TRCK= tag2.txt | sed "s:TRCK=::"` echo $track else echo "Track tag does not exist." fi # Set value of variable 'genre' if grep TCON= tag2.txt > /dev/null # Test if genre tag exists then genre=`grep TCON= tag2.txt | sed "s:TCON=::"` echo $genre else echo "Genre tag does not exist." fi # Write tags to file mid3v2 -t "$title" -A "$album" -a "$artist" -T "$track" -g "$genre" "resample/$1" exit
Now, you'll need to make sure that the files are executable.
chmod u+x mp3shrink
chmod u+x cptag
You're now set to resample your music!
Just cd to the directory with your music files and type:
The script will place your resampled mp3's in a sub-directory called resample.





Thank you!!!
THE script I was looking for! But too bad the id3 tag is not written at least id3info does not show them ...
Thanks for the useful script. There were two parts that didn't work immediately for me:
1. the chmod call didn't set the files to executable, so I used the Properties GUI to switch executable on
2. the mp3shrink script needed cptag to be changed to ~/bin/cptag for it to work.
But excellent nevertheless!
Hi,
your script is great! Only a minor flaw i saw is with uncommon characters, such as Norwegian ones:
with titles like this:
TIT2=Inn I Evighetens Mørke (Part 1)
grep returns a message like :
Binary file matches
which clutters all tags in the track.
I have worked around it by adding the "--binary-files=text" to all grep commands in cptag, i.e.:
# Set value of variable 'title'
if
grep --binary-files=text TIT2= tag2.txt > /dev/null #Test if title tag exists
then
title=`grep --binary-files=text TIT2= tag2.txt | sed "s:TIT2=::"`
echo $title
else
echo "Title tag does not exist."
fi
Hope it helps.
Thanks for the tip. My scripts usually get to the point where they work for me and then I'm done.
It looks like grep gets confused by the special characters and thinks the file is a binary file. So your modification forces grep to interpret the file as a text file. Good job figuring that out.
Thanks for sharing your solution. Hopefully it will help someone else out there.