How To: Create/Write ID3 tags using ffmpeg
Update: New article: How To: Dump and Load metadata with ffmpeg
I have received so many requests from my previous article, “ID3 tags on Windows using ffmpeg”, asking how to add, create or write ID3 tags with ffmpeg that I wrote this article in response.
The Basics
The option to write ‘tags’ to a file, known as metadata, is -metadata key="value". Here is a basic example:
ffmpeg32 -i in.mp3 -metadata title="The Title You Want" out.mp3
You repeat the option once for each key/value pair you want to add to your file like this:
ffmpeg32 -i in.mp3 -metadata title="The Title You Want" -metadata artist="Artist Name" -metadata album="Name of the Album" out.mp3
If you want to clear or delete a certain key/value pair, include the key but leave the value blank like this:
ffmpeg32 -i out.mp3 -metadata title="The Title You Want" -metadata artist="" -metadata album="Name of the Album" out2.mp3
The examples shown above are the very basic. While they will work and will produce a file, there are more options that need to be included to achieve the desired results.
Adding, creating, deleting, or clearing ID3 tags in ffmpeg is very simple. The hard part is figuring out what items you want and what the ‘key’ names are. For example, in Windows you can right-click on the audio file, select ‘Properties’, then click on the ‘Details’ tab. There are several Property/Value pair items listed; "Title", "Subtitle", "Comments", "Contributing artists", "Album artist", "Album", etcetera. Similar information is available in iTunes by right-clicking on a name, choose ‘Get Info’, then click on the ‘Info’ tab. The following table may help you decide:
Windows | iTunes (Info tab) | id3v2.3 | ffmpeg key | ffmpeg example |
---|---|---|---|---|
Title | Title | TIT2 | title | -metadata title="Adagio for Strings" |
Subtitle | Description (Video tab) |
TIT3 | TIT3 | -metadata TIT3="Op. 91" |
Rating | n/a | n/a | n/a | n/a |
Comments | Comments | COMM | n/a | not implemented |
Contributing artists | Artist | TPE1 | artist | -metadata artist="Yo Yo Ma/London Symphony" |
Album artist | Album Artist | TPE2 | album_artist | -metadata album_artist="London Symphony" |
Album | Album | TALB | album | -metadata album="String Classics" |
Year | Year | TYER | date | -metadata date="2012" |
# | Track Number | TRCK | track | -metadata track="3/12" (means track number 3 of 12) |
Genre | Genre | TCON | genre | -metadata genre="Classical" |
Publisher | n/a | TPUB | publisher | -metadata publisher="London Publishing" |
Encoded by | n/a | TENC | encoded_by | -metadata encoded_by="Telarc" |
Author URL | n/a | WOAR | n/a | not implemented |
Copyright (Not Editable) |
n/a | TCOP | copyright | -metadata copyright="℗ Telarc" |
Composers | n/a | TCOM | composer | -metadata composer="J.S. Bach" |
Conductors | n/a | TPE3 | performer | -metadata performer="T. S. Miles" |
Group description | Grouping | TIT1 | TIT1 | -metadata TIT1="The Classics" |
Mood | n/a | n/a | n/a | n/a |
Part of set | Disc Number | TPOS | disc | -metadata disc="1/2" (means disc number 1 of 2) |
Initial key | n/a | TKEY | TKEY | -metadata TKEY="G" |
Beats-per-minute | BPM | TBPM | TBPM | -metadata TBPM="120" |
Part of a compilation | Part of a compilation | TCMP | n/a | not implemented |
n/a | n/a | TLAN | language | -metadata language="eng" |
n/a | n/a | TSSE | encoder | -metadata encoder="iTunes v10" |
I suggest you experiment with the different keys to find what works best for you.
A little more advanced
Lets look at some more advanced options you can use to manipulate metadata. For example, if you want to clear or delete all the global metadata in a file. You could use the examples above and include the key and a blank value for each item but that could make your command line very long. Instead you can use -map_metadata -1 instead. Here it is in a command line:
ffmpeg32 -i in.mp3 -map_metadata -1 out.mp3
Setting -map_metadata to -1 (negative one) tells ffmpeg to use a non-existent input thereby clearing or deleting all the global metadata.
You can get the metadatainformation for a media file by including a input file with no output file like this:
ffmpeg32 -i in.mp3
FFmpeg is also able to dump metadata from media files into a simple UTF-8 encoded INI-like text file and then load it back using the metadata muxer/demuxer. Use a command line like the following to create the text file:
ffmpeg32 -i in.mp3 -f ffmetadata metadata.txt
The file format is as follows:
- A file consists of a header and a number of metadata tags divided into sections, each on its own line.
- The header is a ‘;FFMETADATA’ string, followed by a version number (now 1).
- Metadata tags are of the form ‘key=value’.
- Immediately after the header follows global metadata.
- After global metadata there may be sections with per-stream/per-chapter metadata.
- A section starts with the section name in uppercase (i.e. STREAM or CHAPTER) in brackets (‘[’, ‘]’) and ends with a new/next section or end of file.
- At the beginning of a chapter section there may be an optional timebase to be used for start/end values. It must be in the form ‘TIMEBASE=num/den’, where num and den are integers. If the timebase is missing then start/end times are assumed to be in milliseconds. Next a chapter section must contain chapter start and end times in the form ‘START=num’, ‘END=num’, where num is a positive integer.
- Empty lines and lines starting with ‘;’ or ‘#’ are ignored.
- Metadata keys or values containing special characters (‘=’, ‘;’, ‘#’, ‘\’ and a newline) must be escaped with a backslash ‘\’.
- Note that whitespace in metadata (e.g. foo = bar) is considered to be a part of the tag (in the example above key is ‘foo ’, value is ‘ bar’).
A ffmetadata file might look like this:
;FFMETADATA1 title=bike\\shed ;this is a comment artist=FFmpeg troll team [CHAPTER] TIMEBASE=1/1000 START=0 #chapter ends at 0:01:00 END=60000 title=chapter \#1 [STREAM] title=multi\ line
You can edit the ffmetadata text file to include, change, or remove metadata by loading it into your media file.
To load the file and include the metadata in the output file, use -map_metadata like this:
ffmpeg32 -i in.mp3 -i metadata.txt -map_metadata 1 -c:a copy -id3v2_version 3 -write_id3v1 1 out.mp3
The inputs -i in ffmpeg are counted zero-based. What that means is the first input from the command line example above -i in.mp3 is input number zero. The next input -i metadata.txt is input number one. So using -map_metadata 1 we are telling ffmpeg to map the metadata from input one, our text file, to the global metadata of the output file.
Remember the Version
If you are planning on using the media files with metadata on Windows, DO NOT forget to use these options in your command line:
-id3v2_version 3 -write_id3v1 1
As shown in Example 7 above.