FFMPEG: Convert m4a to mp3 without significant loss
Solution 1:
Use Variable Bit Rate (VBR)
You can use the -q:a
option in ffmpeg
to create a variable bitrate (VBR) MP3 output:
ffmpeg -i input.m4a -c:v copy -c:a libmp3lame -q:a 4 output.mp3
What -q:a
values to use
From FFmpeg Wiki: MP3:
Control quality with
-q:a
(or the alias-qscale:a
). Values are encoder specific, so for libmp3lame the range is 0-9 where a lower value is a higher quality.
- 0-3 will normally produce transparent results
- 4 (default) should be close to perceptual transparency
- 6 usually produces an "acceptable" quality.
The option
-q:a
is mapped to the-V
option in the standalonelame
command-line interface tool.
You'll have to experiment to see what value is acceptable for you. Also see Hydrogen Audio: Recommended LAME Encoder Settings.
Encoding multiple files
In Linux and macOS you can use a Bash "for loop" to encode all files in a directory:
$ mkdir newfiles
$ for f in *.m4a; do ffmpeg -i "$f" -codec:v copy -codec:a libmp3lame -q:a 2 newfiles/"${f%.m4a}.mp3"; done
Solution 2:
Use FFmpeg command line version.
MP3 is officially discontinued (from 2017) and obsolete codec (I call it a dead now). World has already switched to AAC (more efficient & quality codec), and everyone should use this, instead of mp3:
ffmpeg -i filenameee.m4a -acodec copy output.aac
Update: Even though I don't recommend that, unfortunately, some low-quality and obsolete hardware developers still produce appliances which use mp3
and some people still request for that format... Well, here it is:
ffmpeg -i filenameee.m4a -acodec libmp3lame -ab 256k output.mp3
Solution 3:
This worked for me:
ffmpeg -i testing.m4v -b:a 192K -vn testing.mp3
Solution 4:
Using existing answers as a basis I wrote a bash script which should do exactly what the question asks on an Ubuntu machine (tested on 16.04). You'll need to install avprobe
which is in the libav-tools
package. You can install avprobe
with the following command
sudo apt-get install libav-tools
NOTE: It would be wise to make a backup of any folder in which you run this script as well as make your best effort to read and understand what it is doing before running.
I have not tested very rigorously so YMMV.
#!/bin/bash
mkdir "mp3s"
for f in *.m4a;
do
bitrate=$(avprobe "${f}" 2> >(grep bitrate) | sed 's/^.*bitrate://g' | sed 's/[^0-9]*//g')
bitrate="${bitrate}K"
new_filename=$(echo "${f}" | sed 's/.m4a$/.mp3/g')
ffmpeg -y -i "${f}" -acodec libmp3lame -ab "${bitrate}" "mp3s/${new_filename}"
done