In both my previous and recent projects, I have been working with tags (metadata) of music files. One of the reason being I am rather particular about having a nicely organised library with all tag data aligned to the same format. Until recently while I was seeking for a solution to read and write tags of (potentially) all music formats1I only have MP3, FLAC, AIFF and M4A in my library, so that’s kinda all for me., and I encountered FFmpeg, the Swiss Army Knife of media processing.
FFmpeg has always been my go-to solution for processing media programmatically or in batch, and I have recently found the way to write into the tags of music files using it. The way of doing so might be a little verbose as everything have to fit into the command line interface with other components.
Read tags
To read tags from a music file, we actually need to use ffprobe
instead of ffmpeg
. ffprobe
in this case can produce an output in JSON which is more program-friendly.
The option -show_format
adds the section "format"
to the output, which has the metadata of the file format as long as the tags. Omitting this option will result in an output with no useful data.
Besides JSON, ffprobe
also produce output in CSV, flat key-value pairs, INI, and XML syntax. You can choose whichever format that fits your need better. See ffprobe
documentations for more options.
Note that both ffmpeg
and ffprobe
prints version number, compile info of the program itself and metadata of the file to stderr
. Make sure to get rid of it if your program consumes both stdout
and stderr
together by default.
Write tags
It is trickier to write tags than just reading them. In the logic of FFmpeg, everything is considered as a stream, some file comes as an input stream, some filters are applied, and then one output is produced. This is the same case for writing tags too. It could make the entire procedure a little more complex, since usually when you just want to make changes to tag data, you want to just overwrite the original file. But with the way FFmpeg is designed, it won’t allow you to do so. The best you can go around with this is to let FFmpeg to make a copy of the file, and delete the old one afterwards.
Options used in this command are as follows:
-
-i aiff.aiff
: path to the of input file. -
-map 0
: map both audio and video of the 0th input file to the output file, i.e. to keep the media content unchanged. -
-y
: overwrite if the destination file exists. Note that you cannot write to your input file even with this option enabled, or you may corrupt the file entirely. -
-codec copy
: to keep the codec of the file unchanged, so as to prevent unnecessary re-encoding. -
-write_id3v2 1
: quite self-explanatory, only use this option if you want to write the tags as ID3v2. In cases like AIFF, FFmpeg cannot detect the correct tag type to use, so forcing ID3v2 could be sometimes useful. -
-metadata "tag-name=tag value"
: this is where you write/overwrite tags. -
aiffout.aiff
: path to the output file.
In order to provide a uniform interface for writing metadata, FFmpeg has some custom aliases for common tag names that are different from what is actually written to the file. Examples like title
, album
, artist
, and genre
should be honored in most tag types. But some aliases might not always be mapped to the tag you would expect. Sort key tags of Vorbis Comments in FLAC is not mapped as those in ID3, and are considered as custom tags by FFmpeg. It is always better to check with ffprobe
using an already properly tagged file to see if aliases are used. MultimediaWiki has provided a list of common aliases and the tags they mapped to in actual files.
To write a custom tag, just use the key name of your choice directly. FFmpeg can figure out the proper way to add them to your file, like using TXXX
in ID3.
As mentioned previously, this command also produces a lot of debug info to stderr
. In fact, all these output are by default printed to stderr
, so you will only get a return code 0, and nothing from stdout
.
Read cover art
In FFmpeg, a music file with a cover art embedded is considered as a 2 input streams — 1 audio stream and 1 single-frame video stream (as a picture). So, to extract the cover art out, what we need to do is similar to stripping off the audio track of a video.
Options used in this command are as follows:
-
-i mp3.mp3
: path to the of input file. -
-an
: drop the audio stream. -
-vcodec copy
: to keep the codec of the video stream. (That should mean the image format I guess) -
cover.png
: path to the output file.
So, nothing fancy here. It seems like the format the output image would always follow the extension in the output path specified no matter what you have in the file, even when -vcodec copy
is enabled. I’m not really sure if that option is really needed or not. But what is important here is to have a proper extension in the output path.
Write cover art
Similar to reading, writing cover art is the reverse process — combining an audio and a static picture into one file. The static picture will be automatically considered as a cover art.
Options used in this command are as follows:
-
-i mp3.mp3
: path to the of input audio file. -
-i cover.png
: path to the cover art. -
-map 0
: map streams of the 0th (first) input to the output. -
-map 1:0
: map first stream (image data) of the 1th21th is the way of saying the #1 element in a zero-indexed list, it’s intended here. (second) input (i.e. the picture) to the output. -
-codec copy
: to keep the codec of streams, and prevent unnecessary encoding. -
mp3out.mp3
: path to the output file.
Again, these output are for stderr
only, nothing is printed to stdout
.
You can manipulate metadata and the cover art in the same command by just adding -metadata key=value
options. Note that if you have -map 0:0
instead of -map 0
for the audio file, you may lose your existing tag data. Only add the extra :0
if that is what you want to do.
FFmpeg can get rid of the hassle if you are in a hassle looking for an all-in-one solution for music tag reading/writing. It might be a little too heavy if you are using it only for this purpose, but it shouldn’t be much of a problem if you already have it installed in your system for some other things.
Leave a Reply