4

I have a bunch of stereo MP3s I'd like to convert to mono. What is the best way to do this? I would prefer something that would let be batch process them. I want to keep the quality as close to the original as possible. My files are also in different bitrates, so I don't want to make all files 320kpbs when some are only 128.

Also, is there any quick way to see which files are stereo out of my entire library?

5 Answers 5

5

Converting from stereo to mono will mean re-encoding, so keeping the same bit rate would be meaningless. In fact, converting a 128 kbit/s MP3 -> a new 128 kbit/s MP3 will net you godawfully terrible quality, even if the second one is mono (and therefore requires a lower bit rate for the same subjective quality).

Generally, I would use a Variable Bit Rate (VBR) setting for MP3, which targets a specific quality and lets the encoder set whatever bit rate is required (completely silent audio needs a lower bit rate than whalesong, which needs a lower bit rate than dubstep). From the command-line, ffmpeg can convert audio to mono with the option -ac 1, like so:

ffmpeg -i input.mp3 -c:a libmp3lame -q:a 2 -ac 1 output.mp3

See this page for a guide to using -q:a. Note that the table on that page is aimed at stereo audio; the actual bit rates you'll see will be somewhat lower. Normally, I recommend 3-4, but since you're encoding from MP3s rather than an original CD, you should aim a bit higher.

This can, of course, be automated very easily. On Linux/OSX/other UNIX-like, to convert a directory of MP3s:

for f in *.mp3; do ffmpeg -i "$f" -c:a libmp3lame -q:a 2 -ac 1 mono-"$f"; done

To do so recursively:

find . -type f -name "*.mp3" -exec ffmpeg -i '{}' -c:a libmp3lame -q:a 2 -ac 1 mono-'{}' \;

If you have GNU Parallel and a multi-core machine, you may find this useful:

find . -type f -name "*.mp3" | parallel ffmpeg -i {} -c:a libmp3lame -q:a 2 -ac 1 mono-{}
1
  • I'm getting a bunch of "No such file or directory" errors. Jun 16, 2017 at 11:06
3

Well there are several ways, but let me guide you to ones that actually work. You can use Audacity, a free available software for that.

Kindly see this eHow's article on how to convert the MP3 to mono.

5
  • But can I process an entire folder of MP3s like this automatically?
    – Wil
    Aug 21, 2011 at 7:54
  • 1
    Yes, I also suggest to Cowoon Jet Audio easy interface and fast.
    – aibk01
    Aug 21, 2011 at 7:56
  • 1
    For Audacity read this: manual.audacityteam.org/man/Batch_Processing
    – aibk01
    Aug 21, 2011 at 7:57
  • 4
    It would be nice to include the essential parts of the answer here, and provide the link only for future reference. Could you outline the steps to perform to convert the MP3 to mono?
    – slhck
    Aug 21, 2011 at 8:55
  • Yeah, I think Audacity is what I'd check into first. Sep 13, 2013 at 20:22
1

Lame can convert to files to mono using the -m switch, the advantage being preservation of meta tags (I'm not sure if ffmpeg can do that too).

Here is a somewhat complicated example that determines the bitrate of an mp3 before transcoding it with one of the variable bitrate quality options.

cat s2mono.sh
#!/bin/bash

mp3file=$@

mp3size () {
    du -sk "$1" | awk '{print $1 * 8 }'
}
mp3length () {
    id3info "$1" | \
        awk '/=== TLEN/ { if ($NF > 0) { len=int( $NF/1000) }} END {print len}'
}
mp3rate () {
    echo $(( `mp3size "$1"` / `mp3length "$1"` ))
}

bitrate=`mp3rate "$mp3file"`
if [ $bitrate -gt 155 ]; then VBR='-V4'; fi
if [ $bitrate -gt 190 ]; then VBR='-V2'; fi
if [ $bitrate -gt 249 ]; then VBR='-V0'; fi

echo downsampling $mp3file
lame --silent $VBR -m m --mp3input "$mp3file" \
      "$(basename "$mp3file" .mp3 )-mono.mp3"

I ran this on a folder where the total size of all mp3s was 80 MB in stereo format. The resulting mono mp3s consumed only 32 MB.

 find . -iname \*mp3  -print0 |xargs -0 -L1 sh s2mono.sh
 (...)

 du -skc *-mono.mp3| tail -n1
 32376   total

 find . -iname \*mp3  |grep -ve '-mono'  |\
     while read f; do du -sk "$f" ;done  |\
     awk '{ tot+=$1} END{print tot}'
 80112

As for the last part of your question, file will do:

 find /R/audio/muzica/_ripped/wav  -exec file {} \+   |grep Monaural
1
  • FFmpeg does, indeed, preserve metadata, and it actually uses the LAME library for dealing with MP3s (albeit while using its own syntax rather than the LAME one).
    – evilsoup
    Sep 13, 2013 at 18:21
1

Building on this answer, you can get a more portable solution (no extra dependencies, no problems with ID3v1 vs ID3v2 tags) just using file and sed. I also filled in a bit more of the bitrate settings.

In this script, you must specify the input and output files on the command line.

#!/bin/bash
#
# Usage: (this script) stereo-input.mp3 mono-output.mp3
#
# concept via https://superuser.com/a/566023/253931
#

# gnu/linux
bitrate=`file "$1" | sed 's/.*, \(.*\)kbps.*/\1/'`

# osx
# bitrate=`afinfo "$1" | grep "bits per second" | sed 's/.*: \(.*\)000 bits per second.*/\1/'`

BR='-V9'
if [ $bitrate -gt  75 ]; then BR='-V8'; fi
if [ $bitrate -gt  90 ]; then BR='-V7'; fi
if [ $bitrate -gt 105 ]; then BR='-V6'; fi
if [ $bitrate -gt 120 ]; then BR='-V5'; fi
if [ $bitrate -gt 145 ]; then BR='-V4'; fi
if [ $bitrate -gt 170 ]; then BR='-V3'; fi
if [ $bitrate -gt 180 ]; then BR='-V2'; fi
if [ $bitrate -gt 215 ]; then BR='-V1'; fi
if [ $bitrate -gt 230 ]; then BR='-V0'; fi
if [ $bitrate -gt 280 ]; then BR='-b320'; fi

echo "mono-izing file with detected bitrate '$bitrate': $1"
lame --silent $BR -m m --mp3input "$1" "$2"
0

This is the easist method i found

for i in .mp3; do ffmpeg -i "$i" -ac 1 "${i%.} - mono.mp3"; done

The same method can be used to also convert from other audio formats to mp3 as well as converting to mono

for i in .m4b; do ffmpeg -i "$i" -ac 1 "${i%.} - mono.mp3"; done

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .