Lame - How to re-encode all 320kbps mp3 to 192kbps mp3

9,678

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...

Share:
9,678

Related videos on Youtube

Moif Murphy
Author by

Moif Murphy

Updated on September 18, 2022

Comments

  • Moif Murphy
    Moif Murphy over 1 year

    As per title. I have lots of MP3s in 320kbps format that I need to convert to 192kbps. Currently I'm using lame --mp3input -b 192 which creates a file of the same name but with an extra .mp3 extension. So I end up with foo.mp3.mp3.

    I need to be able to enter a directory, scan the sub directories for any 320kbps and convert to 192kbps and overwrite if any are found. Is Lame even the best tool for this?

    Thanks

  • AdigaJo
    AdigaJo over 9 years
    edited twice, fixing the command and adding bitrate
  • Moif Murphy
    Moif Murphy over 9 years
    Spectacular answer. I've cobbled something together using lame but I'll be giving this ago. Will report back.
  • Moif Murphy
    Moif Murphy over 9 years
    I'm getting this error: Unrecognized option 'select_streams' Failed to set value 'a:0' for option 'select_streams'
  • lepe
    lepe almost 8 years
    with avconv, replace it to: avconv -i {} -b:a 192k {.}.temp.mp3 && mv {.}.temp.mp3 {}