Search code examples
bashffmpegmp3bitrate

Batch reduce bitrate and size of mp3 audio files with ffmpeg


I was looking for a way to batch reduce mp3 bitrate on my sizable collection of mp3 files. It was surprising difficult given that this must be a super common thing to want to do.

In fact, there are dozens, maybe hundreds, of posts from people asking how to do it, and dozens of utilities available for varying amounts of money that claim to do just that. Looking around and trying some of the free software, I was surprised that none made the task of batch converting/adjustment easy.

If I wanted to convert a single file, I'm told this is a decent way to do it:

ffmpeg -y -loglevel "error" -i "my_music_file.mp3" -acodec libmp3lame  -ab $BITRATE "my_music_file_new.mp3"

(Though I'd prefer if the file was changed in place and resulted in the same name.)

I need a simple bash script using ffmpeg that will recursively go through my music directory and change the bitrate of my mp3 files.


Solution

  • It took a bit of fiddling to get the right ffmpeg and find options, but this should do it.

    #!/bin/bash
    MUSIC="FULL PATH TO YOUR MUSIC FOLDER"
    BITRATE=160k
    find "${MUSIC}" -name "*.mp3" \
      -execdir echo "{}" \; \
      -exec mv "{}" "{}.mp3" \; \
      -exec ffmpeg -y -loglevel "error" -i "{}.mp3" -acodec libmp3lame  -ab $BITRATE "{}" \; \
      -exec rm "{}.mp3" \;
    

    Because ffmpeg can't output to the same input file without nuking it, the script first renames the file, builds a new one at your chosen bitrate, then removes the old file.

    I'm sure that many people will have suggested improvements here. I certainly welcome ways to make the script more readable.