Lame - How to re-encode all 320kbps mp3 to 192kbps mp3
Solution 1:
lame
is perfectly suited to this task, but I'm going to use ffmpeg
and ffprobe
for this answer, because I know them like the back of my hand and because they can be generalised to more than just MP3s. First of all:
sudo apt-get install ffmpeg
There is no tool that I am aware of that can read media files and then over-write the input straight away: you need to use an intermediate file. For a single file, you could do:
ffmpeg -i file.mp3 -c:a libmp3lame -b:a 192k temp.mp3
mv temp.mp3 file.mp3
You could combine these into a single line:
ffmpeg -i file.mp3 -c:a libmp3lame -b:a 192k temp.mp3 && mv temp.mp3 file.mp3
the &&
there means that the mv
command won't be executed unless ffmpeg
exits with a status of 0 (which means success).
To check that what bit rate a file has, you can use ffprobe
:
ffprobe -show_streams -select_streams a:0 -v quiet file.mp3 | grep -F 'bit_rate=320000'
-show_streams
tells ffprobe
to show information about individual streams; -select_streams
tells it which ones to select, and a:0
means 'the first audio stream (this is important for MP3 files in the case of cover art, which is stored as a video stream). The pipe (|
) takes the standard output of ffprobe
and feeds it to grep
. grep
will only print those lines that match a given pattern -- in this case, lines that contain the string bit_rate=320000
. If you run this on a 320k kbps MP3, you'll get a line like this:
bit_rate=32000
If you run it on anything with a different bit rate, you won't get any output at all; grep will fail to make a match, and will exit with a status of 1. This means that you can chain that command with the ffmpeg command:
ffprobe -show_streams -select_streams a:0 -v quiet file.mp3 | grep -F 'bit_rate=320000' && ffmpeg -i file.mp3 -c:a libmp3lame -b:a 192k temp.mp3 && mv temp.mp3 file.mp3
Or, a bit more readably:
ffprobe -show_streams -select_streams a:0 -v quiet file.mp3 | grep -F 'bit_rate=320000' &&
ffmpeg -i file.mp3 -c:a libmp3lame -b:a 192k temp.mp3 &&
mv temp.mp3 file.mp3
That will only act on 320 kbps MP3s. Try it with a couple of test files.
The next step is to get this working with multiple files. There are two standard ways of doing this: a for
loop, and the find
command. The following will act on every MP3 in a directory:
for f in *.mp3; do
ffprobe -show_streams -select_streams a:0 "$f" | grep -F 'bit_rate=320000' &&
ffmpeg -y -i "$f" -c:a libmp3lame -b:a 192k /tmp/temp.mp3 && mv /tmp/temp.mp3 "$f"
done
This will not go into subdirectories; in order to do so, you have to set the globstar
shell option:
shopt -s globstar
for f in **/*.mp3; do
ffprobe -show_streams -select_streams a:0 "$f" | grep -F 'bit_rate=320000' &&
ffmpeg -y -i "$f" -c:a libmp3lame -b:a 192k /tmp/temp.mp3 && mv /tmp/temp.mp3 "$f"
done
With find
:
find . -name '*.mp3' -exec sh -c 'ffprobe -show_streams -select_streams a:0 "$0" | grep -F "bit_rate=320000" &&
ffmpeg -y -i "$0" -c:a libmp3lame -b:a 192k /tmp/temp.mp3 && mv /tmp/temp.mp3 "$0"' '{}' \;
All of these will run strictly sequentially -- they'll only convert one file at a time. Your processor is almost certainly capable of more than that, though; to speed things up, you could use GNU parallel
:
sudo apt-get install parallel
shopt -s globstar
parallel 'ffprobe -show_streams -select_streams a:0 {} | grep -F "bit_rate=320000" &&
ffmpeg -y -i {} -c:a libmp3lame -b:a 192k {.}.temp.mp3 && mv {.}.temp.mp3 {}' ::: **/*.mp3
Or:
find . -name '*.mp3' | parallel 'ffprobe -show_streams -select_streams a:0 {} | grep -F "bit_rate=320000" &&
ffmpeg -y -i {} -c:a libmp3lame -b:a 192k {.}.temp.mp3 && mv {.}.temp.mp3 {}'
Solution 2:
Lame
is one of the best you can find to do this task
You can use the command lame -b 192 input.mp3 output.mp3
im not good with piping commands but you can use exiftool
to get the bit rate of the mp3 file
exiftool -AudioBitrate File.mp3
but you still need a way to pipe the commands of finding mp3 file, checking the bitrate and converting...