Convert .flac to .mp3 with ffmpeg, keeping all metadata

101,316

Solution 1

The following command keeps high quality on .mp3 (320 kbps), and metadata from .flac file are converted to ID3v2 format, which can be included in .mp3 files:

ffmpeg -i input.flac -ab 320k -map_metadata 0 -id3v2_version 3 output.mp3

Solution 2

Perfect answer above. I use it together with find to add all FLAC files in a subtree to iTunes with this command

find . -name "*.flac" -exec ffmpeg -i {} -ab 160k -map_metadata 0 -id3v2_version 3 {}.mp3 \;

To automatically add the resulting files to iTunes, get the iTunes import directory with

find ~/Music/ -name "Automatically Add*"

result e.g.

/Users/sir/Music//iTunes/iTunes Media/Automatically Add to iTunes.localized

Then run e.g.

find . -name "*.mp3" -exec mv {} "/Users/sir/Music//iTunes/iTunes Media/Automatically Add to iTunes.localized/" \;

To automatically add all the converted tracks to iTunes.

Solution 3

If you want to save a little space, try the recommendation of hydrogenaud.io:

Very high quality: HiFi, home, or quiet listening, with best file size -V0 (~245 kbps), -V1 (~225 kbps), -V2 (~190 kbps) or -V3 (~175 kbps) are recommended. These VBR settings will normally produce transparent results. Audible differences between these presets may exist, but are rare.

Source: http://wiki.hydrogenaud.io/index.php?title=LAME

If you want use this option in ffmpeg, you should use the -q:a 0 alias.

Control quality with -qscale:a (or the alias -q: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, and 6 produces an "acceptable" quality. The option -qscale:a is mapped to the -V option in the standalone lame command-line interface tool.

Source: https://trac.ffmpeg.org/wiki/Encode/MP3

If you want ID3v1 metatags too, you should add the -write_id3v1 1 parameter.

So my final command is:

ffmpeg.exe -y -i input.flac -codec:a libmp3lame -q:a 0 -map_metadata 0 -id3v2_version 3 -write_id3v1 1 output.mp3

Solution 4

I was testing the following command to convert infile.flac file to outfile.mp3:

ffmpeg  -i infile.flac  -q:a 0  outfile.mp3

As of Ubuntu 16.04, the above command seems to copy (most of? all of?) the metadata.

-q:a 0 tells ffmpeg to use the highest quality VBR.

However, ffmpeg was transcoding my album art from jpeg to png, which increased the size of the cover art.

Stream mapping:
  Stream #0:1 -> #0:0 (mjpeg (native) -> png (native))
  Stream #0:0 -> #0:1 (flac (native) -> mp3 (libmp3lame))

(I guess the above conversion sort of makes sense given how ffmpeg works.)

After some digging, I found the -c:v copy option, which specifies that the video stream should be copied, rather than transcoded. The full command is:

ffmpeg  -i infile.flac  -c:v copy  -q:a 0  outfile.mp3

The above command results in:

Stream mapping:
  Stream #0:1 -> #0:0 (copy)
  Stream #0:0 -> #0:1 (flac (native) -> mp3 (libmp3lame))

Solution 5

To recursively convert in mp3 all the flac files in nested folders, I used this command:

find '~/Music/' -iname '*.flac' -exec bash -c 'D=$(dirname "{}"); B=$(basename "{}"); mkdir "$D/mp3/"; ffmpeg -i "{}" -ab 320k -map_metadata 0 -id3v2_version 3 -acodec libmp3lame "$D/mp3/${B%.*}.mp3"' \;

It will create a folder named "mp3" inside the one with flac files and, inside the mp3 folder, it will save relative mp3 files with a bitrate of 320kbps, without keeping the old file extension in the name.

Share:
101,316

Related videos on Youtube

Vito Gentile
Author by

Vito Gentile

I’m a researcher in human-computer interaction and adjunct professor of computer science, working at both University of Palermo (Italy) and University of Hertfordshire (UK). At the same time, I’m currently working for Codemotion Magazine and HTML.it as technical writer and content manager. Finally, I currently collaborate with synbrAIn S.r.l. as senior data scientist, working on AI and machine learning solutions in several application domains. Above all else, I’m a passionate developer. I had prior experiences as mobile and web developer (full-stack), working with several technologies and programming languages including Python, JavaScript, C#, Java and PHP. I also love music, technology, and any other new curious facts about computers and programming.

Updated on July 08, 2022

Comments

  • Vito Gentile
    Vito Gentile over 1 year

    How can I convert .flac to .mp3 with ffmpeg, keeping all metadata (that is converting Vorbis comment in .flac files to ID3v2 metadata of .mp3)?

    • llogan
      llogan about 9 years
      Please note that for next time you should ask ffmpeg cli usage questions at Super User. Stack Overflow is only for questions involving programming. Also, FLAC officially supports Vorbis comment only, so I assume you want to convert to ID3v2 instead of "keep".
    • Vito Gentile
      Vito Gentile about 9 years
      Ok, I fixed my question. I asked here because I saw questions like this on StackOverflow (e.g. this or this), and assumed it could be interesting to share my knowledge. Also, I see that there is a ffmpeg tag, so why don't share my solution here? ffmpeg is used in a lot of application by a lot a lot of developers.
    • llogan
      llogan about 9 years
      The ffmpeg tag says, "Questions about interactive use of the FFmpeg command line tool should be asked on Super User.". It's not a big deal, but I just wanted to point it out since there are too many off-topic questions here in my opinion.
  • shockburner
    shockburner over 7 years
    It's worth noting that "ffmpeg" may need to be replaced by "avconv".
  • Dai
    Dai almost 7 years
    FWIW ffmpeg 3.2 automatically copies metadata into ID3v2 from FLAC without needing to specify -map_metadata 0 -id3v2_version 3, though it doesn't copy into ID3v1 tags. I use a separate tool for that.
  • user151496
    user151496 about 6 years
    lyrics still don't get copied though
  • Artyom
    Artyom almost 6 years
    Does it divide flac if there are several parts?
  • Admin
    Admin over 5 years
    @Artyom You should probably have the cue file along with your flac where the split points are marked. If so then you can use shnsplit (console) or flacon (GUI) to split your file and convert the parts to mp3. If you only have a single flac you can either write a cui for it or use ffmpeg's -ss and -t options to cut each song out.
  • Harry Svensson
    Harry Svensson almost 5 years
    "/Users/sir", lmao.
  • user2707001
    user2707001 almost 5 years
    Anecdote : all users in our company have names of stars, abbreviated to 3-5 characters. Mine is "sirius", short sir ;)
  • MonsterMMORPG
    MonsterMMORPG almost 5 years
    Unrecognized option 'name'.
  • MonsterMMORPG
    MonsterMMORPG almost 5 years
    gives error sed: -e expression #1, char 26: unterminated `s' command
  • MonsterMMORPG
    MonsterMMORPG almost 5 years
    Unrecognized option 'name'. Error splitting the argument list: Option not found
  • Dhiraj Gupta
    Dhiraj Gupta almost 5 years
    @MonsterMMORPG you probably missed typing the . after the find command. The . tells find to look in the current folder, and -name tells it to look for matching file names.
  • Chazy Chaz
    Chazy Chaz over 4 years
    Just quote the variable $file like "$file".
  • mivk
    mivk about 4 years
    :r seems to be a zsh modifier, which doesn't work in bash. In Bash you could replace "${file:r}.mp3" with "${file%.flac}.mp3".
  • deadfish
    deadfish almost 4 years
    For loop conversion (.bat script for Windows): for %%f in (*.flac) do ( ffmpeg -i "%%f" -ab 320k -map_metadata 0 -id3v2_version 3 "%%f.mp3" )
  • genuinefafa
    genuinefafa over 3 years
    just a heads up, claiming that 320k is "high quality" is not good practice according to trac.ffmpeg.org/wiki/Encode/MP3#CBREncoding :)
  • Evhz
    Evhz over 3 years
    to show only filename from file, in bash use ${file%.*}
  • Jared Beach
    Jared Beach about 3 years
    powershell to do this for the directory dir *.flac | foreach {ffmpeg -i $_.FullName -ab 320k -map_metadata 0 -id3v2_version 3 $_.FullName.Replace('flac', 'mp3')}
  • aksh1618
    aksh1618 about 3 years
    Exactly what I was looking for, thanks! I adjusted the script a bit for incorporating VBR and other answers, uploaded here: gist
  • gustafbstrom
    gustafbstrom over 1 year
    Big thanks. FYI, your answer credited in an article: quantixed.org/2021/11/20/….
  • Riccardo Volpe
    Riccardo Volpe over 1 year
    Thanks for the reference @gustafbstrom! FFMPEG is so powerful! Cheers :-)
  • gustafbstrom
    gustafbstrom over 1 year
    FYI: I'm not the author, just wanted to give you a heads up :)
  • Kellei
    Kellei over 1 year
    shell version of deadfish's oneliner for f in *.flac; do ffmpeg -i "$f" -ab 320k -map_metadata 0 -id3v2_version 3 "${f%.flac}.mp3"; done or if you want to put it in a separate folder for f in *.flac; do ffmpeg -i "$f" -ab 320k -map_metadata 0 -id3v2_version 3 "mp3/${f%.flac}.mp3"; done