When you play a music file in your favourite music player, or in your portable media player the track name, album, artist, lyrics gets displayed. You can search the songs with artists, album names. Even some of the tracks come with album art too, but there is no image file anywhere. The question generally arises, where does these information come from? The answer is straight forward; this metadata about the audio track is stored inside the audio file itself. The different audio files need different codecs. Different audio format files also have different such metadata systems. For example The Vorbis comments, APE tag, ID3 tags etc.

The most common and popular audio media (although not the best) is the mp3 . Mp3 audio format stores this metadata inside the music file, either at the beginning or at the end or at both locations. The music metadata system used with mp3 is called an ID3 Tag.
We will rip off the ID3 tag and check out what’s inside it in this article. We will discuss about ID3v1.x and ID3v2.x tags.

Article Index


In the beginning mp3 music files did not have any feature to carry text data with the audio file, what it could do is to make use of a couple of unused bits on the header of the compressed audio blocks, as ‘copyright’ and ‘private’ bits. Which was not very useful. A man named Eric Kemp came forward and developed a fixed sized tagging system and placed it at the end of the audio file, where some text information could be stored without conflict. This was the first ID3 tag the ID3v1 tag, at that time known as “IDentify an mp3” . After this Michael Mutschler made a minor modification to this and introduced one new field, this version was the ID3v1.1 . Now we straight dig into the tags.

ID3v1 tag

ID3v1 tags supported text only data and also with a very limited number of fields and field sizes. This contains a fixed 128-byte sized tag and was placed at the last of the media file. The tag contained 6 fixed length fields. Which are described in the below table:

ID3v1.x Tag structure
byte 0 to 2 byte 3 to 32 byte 33 to 62 byte 63 to 92 byte 93 to 96 byte 97 to 126 byte 127
Always the string “TAG” (3 bytes) Track Name (30 bytes) Artist (30 bytes) Album (30 bytes) Year (4 bytes) Comment (28+2bytes)

ID3v1.1 Update:
byte 97 to 124: Comment (28bytes)
byte 125 = 0
byte 126 = Track No.

Genre (1 byte)

The stored information takes up 125 bytes of the 128 bytes. The first three bytes of the are always “TAG” (without the quotes). The genre of the track is represented by 1 byte. The value of this byte is looked up in a table of genres, which is fixed and it is determined. For example 52 is Electronic genre, 32 is classical. ID3v1 defines only the first 79 genre types. Genre 80 to 128 is defined by Winamp. (ID3v2.3 8.Appendix )

The next improvement was done by Michael Mutschler, which was nothing but simply splitting the comment field into two fields. The 30 bytes of the comment field in ID3v1 was split into one 28byte new comment field and the remaining 2 bytes were reserved for Album track. Which describes which the track number. The first byte of the Album track is always zero, and the next byte describes the track number.

Although this tagging scheme is simple and easy to make a coder-decoder, but very limited. The Track name , Album name are limited to 30 chars, not all albums and tracks are below 30 chars. The comment field is too short to store something useful. Another problem is that, because the ID3 tag is located at the end of the media file, it is the last data to reach at the user’s end in case of streaming. So the streaming media player would be able to show the track details after the track has ended. There was also no scope for adding more fields, except extending the tag length.

I have posted a small ID3v1 tag parsing library in this post : An ID3v1 Tag Parsing Library . With this you can read write and rip the ID3v1 tags from an mp3 file.

ID3v1 Extended

An unofficial extension of ID3v1.x was the ID3 Extended tag. This was to overcome the field length and it introduced 4 new fields. The extended tag has 60bytes reserved space for track name, artist and album, each of these field contains the next 60 characters of the ID3v1.x tags. So if the name of a track has 53 characters, then the first 30 characters will go into the standard ID3v1.x tag section, and the next 23 characters will go into the extended tag’s title field. The new fields introduced are, speed, free-text genre, start-time and end-time. The speed in represented by 1 byte and could have values 0=unset, 1=slow, 2=medium, 3=fast, 4=hardcore. From this a smart play-list according to a certain mood could be created. The free-text genre allows to store a customized genre upto 30 characters, instead of the fixed table values in ID3v1.x. The start and the end time takes 6bytes each and has a mmm:ss format, which is used to make fade-in and fade-outs in media players. The extended tag has a total size of 227 bytes. This 227 bytes is placed just before the ID3v1.x tag. The extended tag has a header “TAG+“.
So first we check if the file has an ID3v1.x tag, if yes then we check if it has an extended tag, then we read the values from both the tags, and concatenate the strings as needed.

ID3v2.x Tag Structure

On 1998 ID3v2 came to the rescue. Although it may seem a version upgrade to the ID3v1 tag, but it actually is totally different internally. This tag does not have fixed length fields anymore. The information are stored in self describing dynamic length blocks of data called frames. The ID3v2 tag contains the frames within it, thus acts as a container of the frames. This is similar like say you have a cover file, and you have written on it how many papers are there in it, and each paper has written on it how many lines of text is written on that paper. The cover file could be thought as the tag, a container, and the files can be thought as frames, which are self described by the header, and contains data. This eliminates the field length restriction, as now each tag can store any amount of data in a frame. Although the limitation is that the tag could be at max 256MB long, and each frame cannot be more than 16MB. Now a 16MB long frame could hold pdf books, and in reality this could be done. ID3v2.x lets the programmer to define personal frames also. The tag, is placed at the beginning of the file, so the streaming problem was solved, as now the streaming media players received the track information first.

Below we discuss the internals of ID3v2.x tags. The ID3v2.x description will follow the ID3v2.3 version mainly; but also we will talk about ID3v2.4 also. Read the id3v2.4.0-changes documents at the ID3 tag official site (see the Links and References section at the end of this article) for the changes.

Tag Header

The tag, placed at the beginning of the media file, begins with the ID3 tag identifier – the string “ID3” (3 bytes), followed by 2 bytes representing the version number and the revision number. The version number is very important to know for decoding the tag frames, since different tag versions (v2.0, v2.3, v2.4) have different specs, and newer versions are not backward-compatible. The next byte contains a set of flags, which has different interpretations in different versions of the tag. The next 4 bytes, the size byte, store the length of the tag. This header describes the whole tag, the ‘container’, telling about its length, including all the frames and padding (explained later) within it, type and properties.

ID3v2.x Header (10 bytes)
ID3 tag identifier Version Revision Flags Size
3 bytes String “ID3” represents ID3v2 tag 1 byte 1 byte 1 byte 4 bytes synchronization-safe integer

The size bytes describe the span of the tag in the file, and the value is used to stop scanning for frames, but it is not stored in normal bit sequence – involving a tricky part with the size calculation. The size is described by 4 bytes. Each byte’s most significant bit (MSB – that is, the 7th bit) is set to zero and is ignored. The remaining 28 bits represent the actual value. To decode the actual value, convert the 4 byte value to the binary number system, then rewrite the number, removing the 7th bit from each byte, acquiring a 28-bit number defining the length of the tag. The reverse is done when encoding: write a 28-bit number, and insert a 0 in the MSB of each byte. This is not too difficult, but needs a lot of bit-shifting and pasting. The 256 MB limitation on tag size comes from this 28-bit limit (228). An integer encoded in this way is known as a synchronization safe integer. Read section Synchronization Safe Integers and Unsynchronization Scheme to know more

An extended header could also exist to describe additional header information. An extended header is not critical to decode the tag information. The extended header follows the header, and is 6 to 10bytes long. To indicate that the tag has an extended header the 6th bit of the ID3 header flag byte is set, which means that an extended header is following the header. (ID3v2.3 Sec 3.2)


After retrieving the whole tag, we look inside it for the ‘chunks of data’ (the frames) and decode them. There is no strict ordering of the frames in the tag. Again, each frame has a frame header, describing the frame’s type, length, and other properties.

ID3v2.x Frame Header
Frame ID Frame Size Flags Total
ID3v2.2 3 bytes.Example: “TAL”, “TT1”, “COM” 3 bytes big endian N/A 6 bytes
ID3v2.3 4 bytes.Example: “TALB”, “TIT1”, “COMM” 4 bytes big endian 2 bytes 10 bytes
ID3v2.4 4 bytes.Example: “TALB”, “TIT1”, “COMM” 4 bytes synchronization safe integer 2 bytes 10 bytes

Each frame has an identifier, which identifies what data does that frame contain. The identifier is 4bytes in length in ID3v2.3 and ID3v2.4 (3bytes in ID3v2.0). For example the frame identifier containing the Album name is “TALB” for ID3v2.3 and ID3v2.4 (“TAL” for ID3v2.0). The frame identifier is followed by 4bytes in ID3v2.3 (3bytes in ID3v2.0) which determines the size of the frame. These size bytes are stored as normal integers (big-endian) in ID3v2.3 and lesser version, and as synchronization safe integers in ID3v2.4 as described in the section Synchronization Safe Integers and Unsynchronization Scheme and needs to be decoded to get its actual value. ID3v2.3 has two more bytes following the size bytes, containing frame specific flags representing the properties of that frame. Thus the ID3v2.3 frame header is 10bytes long (ID3v2.0 6bytes long). The frame size, described by the ‘size’ bytes, is the size of the frame without the header length. This completes the frame header.

The frame header information describes about the frames and is always 10 bytes long (ID3v2.3). Some frames has some extra bytes to describe more information in addition to the header. These bytes follows the header but is not a part of it, instead these bytes are a part of the frame contents and the frame size is calculated including these special bytes. For example, text frames have one byte just after the header, that represents the text encoding; the actual text follows this byte. (ID3v2.3 Sec 4.2.) Similarly with the “COMM”(comment) frame – the 4 bytes following the header identify the text encoding (1 byte) and text language (3 bytes). Then comes an optional short content description terminated by a NULL byte, after which the actual comment text is stored. (ID3v2.3 Sec 4.11.) The frame size integer in this case will include the 4 bytes, the short description text, if present, and the NULL terminator. This has to be handled by the ID3 reader as per the frame specification.

Other than text tags there are picture tags for storing album arts. The “APIC” frame in ID3v2.3 stores the picture values (‘PIC’ in ID3v2.0). This would solve the mystery picture which is displayed as the album art in the media player, but there was no picture. The tag could hold more than one pictures. The frame size could be at max 16MB so hi-res pictures is not a trouble. There are other types of tags as well , like URL tags, license tags, and a lot more. The frame identifiers and all the details are listed in the ID3 official website’s developers documentations.

Synchronization Safe Integers and Unsynchronization Scheme

But why would anyone store a number is such a manner, and not in a more normal fashion? The quick answer is that this method is used to avoid false synchronization signals. MPEG audio files are divided into small, independent frames containing music data. Each frame has a 32 bits long descriptive header, the upper 11 or 12 bytes of which are always set to ‘1’ (ie. Values starting with 0xFFF or 0xFFE), and this header is called the frame sync. This is used by the decoders to detect an audio frame for playing. Now is an ID3 tag had some part of it with 0xFFE or 0xFFF (the top 11 or 12 bytes set to ‘1’), old media players, which cannot read ID3v2 tags, could wrongly detect the portion of the tag as an audio frame’s frame sync. A number constructed in such a manner, as described above, could never have a combination starting with 0xFF and hence, numbers represented in such a manner would never cause a false sync. Such integers are called synchronization safe integers.

But false synchronization can occur in other data parts of the tag too. For this an unsynchronization scheme is used. A flag in the tag header tells that if unsynchronization is used or not. The unsynchronization scheme replaces all the 0xFFF patterns with 0xFF0F and 0xFFE patterns with 0xFF0E pattern, and thus false signals are avoided. When reading the ID3v2 tag with this first it has to be checked that if the unsynchronization is used by inspecting the flag indicating if the scheme is used, and the reverse process has to be used to get the original data. The parts where this unsynchronization scheme is not used, and can have a 0xFF pattern, are stored in synchronization safe integers, like the tag size byte of the tag, and the frame size bytes in ID3v2.4

It is important to note the difference between the unsynchronization scheme and the synchronization safe integers.

In ID3v2.2 and ID3v2.3 tags the unsynchronization scheme is used at the tag level, that is the whole body of the tag (except the header) is subjected to the unsynchronization scheme. And for that the size byte of the tag header is encoded as synchronization safe integers. So these together avoid any false synchronization signals. In ID3v2.4 the unsynchronization scheme is used at the tag level, that is body of each of the tags are unsynchronized separately, depending on the frame’s unsynchronization flag indicator. So to avoid false synchronization due to the frame’s size bytes they each are coded as synchronization safe integers. Thus in ID3v2.2 and ID3v2.3 the tag header’s size bytes are encoded as synchronization safe integers, and the whole body is subjected to the unsynchronization scheme, and in ID3v2.4 the tag header size byte as well as all the frame’s size bytes are stored as synchronization safe integers and each of the tag body are individually subjected to the unsynchronization scheme.

This bit shifting can be implemented with the below C Language code snippet. The below code snippet converts an input integer in “x” into or from synchronization safe integers.

/* Encoding:*/
/* Convert normal integer into synchronization safe integer */
      x_final = 0x00;
      a = x & 0x7f;
      b = (x >> 7) & 0x7f;
      c = (x >> 14) & 0x7f;
      d = (x >> 21) & 0x7f;

      x_final = x_final | a;
      x_final = x_final | (b << 8);
      x_final = x_final | (c << 16);
      x_final = x_final | (d << 24);

/* Decoding:*/
/* Convert synchronization safe integer into normal integer */
      x_final = 0x00;
      a = x & 0xff;
      b = (x >> 8) & 0xff;
      c = (x >> 16) & 0xff;
      d = (x >> 24) & 0xff;

      x_final = x_final | a;
      x_final = x_final | (b << 7);
      x_final = x_final | (c << 14);
      x_final = x_final | (d << 21);

You can get a full source code here in this post : Synchronization Safe Integer

ID3v2.x Practical Lab

Now let’s hack into the ID3 tags and do something really geeky. The following section describes how to read an ID3 tag manually (and also write it), without using any tag-parsing library. You will need a hex editor like hexdump or Okteta; an MP3 file with an ID3v2 tag; and a synchronization-safe-byte encoder/decoder program, like the one you will find here in this post : Synchronization Safe Integer which will take the bit-shifting load off you.

I have used Okteta to do my dumping – it makes it easy to track the hex values and the text. The following is a hex dump of the first 256 bytes of an MP3 file:

00000000  49 44 33 03 00 00 00 00  01 18 54 49 54 32 00 00  |ID3.......TIT2..|
00000010  00 0c 00 00 00 42 69 6c  6c 69 65 20 4a 65 61 6e  |.....Billie Jean|
00000020  54 41 4c 42 00 00 00 09  00 00 00 54 68 72 69 6c  |TALB.......Thril|
00000030  6c 65 72 54 50 45 31 00  00 00 10 00 00 00 4d 69  |lerTPE1.......Mi|
00000040  63 68 61 65 6c 20 4a 61  63 6b 73 6f 6e 54 59 45  |chael JacksonTYE|
00000050  52 00 00 00 05 00 00 00  32 30 30 35 54 43 4f 4d  |R.......2005TCOM|
00000060  00 00 00 10 00 00 00 4d  69 63 68 61 65 6c 20 4a  |.......Michael J|
00000070  61 63 6b 73 6f 6e 43 4f  4d 4d 00 00 00 19 00 00  |acksonCOMM......|
00000080  00 00 00 00 00 32 35 79  65 61 72 20 73 70 65 63  |.....25year spec|
00000090  69 61 6c 20 61 6c 62 75  6d 00 00 00 00 ff fb 90  |ial album.......|
000000a0  64 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |d...............|
000000b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000000c0  00 49 6e 66 6f 00 00 00  0f 00 00 2b f2 00 47 c2  |.Info......+..G.|
000000d0  63 00 02 05 08 0a 0d 10  12 15 17 1a 1c 1f 21 24  |c.............!$|
000000e0  26 29 2b 2e 30 33 35 38  3a 3d 40 42 45 48 4a 4d  |&)+.0358:=@BEHJM|
000000f0  4f 52 54 57 59 5c 5e 61  63 66 68 6b 6d 70 73 75  |ORTWY\^acfhkmpsu|

A glance is enough to get the major information, but we would look the bytes from the computer’s eye-view. Now switch yourself from human mode to computer mode and scan the above data.

Lets now start scanning from the beginning. If you scan the above data (look at the hex values too), you can verify the following:

  • The first three bytes of the file contain the string “ID3” – that means the file has an ID3v2 tag.
  • The next byte, which represents the tag version number, is 0x03 – that means this tag’s version is ID3v2.3.
  • The next byte, the revision number, is 0x00.

So after reading the first 5 bytes we know that the file has an ID3v2.3.0 . The version number is very important, we find it to be 3 and open the ID3v2.3 specification document and will use it to decode the tag. If the version was 0 then we would use the ID3v2.0 specification which is different from v2.3 specification and decode according to that.

  • Then we continue to the sixth byte, the Flags byte, which has a value of 0x00. Bits 7,6 and 5 represent Unsynchronization, Extended header, and Experimental indicator flags respectively for ID3v2.3. Since this byte is zero, this file’s tag does not need the unsynchronization, the tag has no extended header, and no experimental indicator. (See ID3v2.3 Sec 3.1.)
  • The next 4 bytes are the synchronization-safe integer expressing the size of the file: 0x00 00 01 18. Let’s use the bit-manipulation described earlier to decode the integer. (Later, you could just use the supplied sourcecode provided here : Synchronization Safe Integer) The ignored bit positions are replaced by underscores in our visualization below. The caret signs on the second line of each visualization each represent the end of a 7-bit block.
_0000000 _0000000 _0000001 _0011000
-^------ -^------ -^------ -^------

To fill the ignored gaps, shift the higher bytes onto the empty space of the lower byte which results in below 28bit number.

_ _ _ _0000 00000000 00000000 10011000
-------^--- ---^---- --^----- -^------

Which interprets into 0x98 or 152 in decimal. So these 4 bytes are trying to say that the tag spans 152bytes from the start of the file. If you look at the 10th line with 0x00 00 00 90 address label and advance 8 bytes you would find the tag ending (Highlighted in red). After we figured out the end, we now have the whole tag, and would only consider data inside the 0x98 boundary (inclusive), and would not see anything beyond that address. So we just read those bytes in a buffer and close the file.

Now we are done with reading the 10 byte header and known all about the tag. Now the scanning will proceed reading the frames within the tag.

Reading the next 4 bytes in search of a frame yields “TIT2”. Look that up in the ID3v2.3 frame database and we find that’s the Title/song name/content description. We read the next 4 bytes (the frame size), which is 0x00 00 00 0C which is equivalent to 12 in decimal. The frame size bytes are stored as normal integers in ID3v2.3 tags, so it does not need any bit manipulation. If the tag you are reading is ID3v2.4, then you need to perform the bit-shifting on this value, as ID3v2.4 stores the frame size as synch-safe integer. Note that even a number needs to be decoded from synchronization safe integer, a number with the rightmost byte less than 0x80 practically needs no shifting.

We remember this information, and read the next 2 bytes, containing the frame flags, which are 0x00 00, meaning all the flags are unset. We will ignore these bytes for now, to keep the interpretation simple. (Check specification sheet) The frame header is complete. The frame size says the data is stored in the next 12 bytes after the frame header. Since this is a text frame, the first byte of the stored data will contain the text encoding information, as per ID3v2.3 Sec. 4.2 – the stored value is 0x00, indicating the text after it is encoded in the ISO-8859-1 character set. If it was 0x01, then it would have been Unicode (ID3v2.3 Sec. 3.3). Next, we read the remaining 11 bytes to get the title of the track: “Billie Jean”.

We have just read the Title of the song!! I will brisk on the next tags.

We need to follow the same procedure for the subsequent tags, though I’ll speed up a bit here.
After the Title text, read the next 4 bytes – “TALB”. Look up the ID3v2.3 database – it’s the Album name. The next 4 bytes return the frame size, 9 bytes. For now, we ignore the next 2 bytes (flags), read the 9 bytes (including the text encoding byte) and thus obtain the Album name – “Thriller”. You can similarly apply this procedure to the “TPE1” (lead performer), “TYER” (year) and “TCOM” (composer) frames.

Let’s slow down again for the “COMM” frame, since the 5 extra bytes before the comment might be confusing. Section 4.11 in the ID3v2.3 specification tells us that the “COMM” frame includes three language bytes and one text-encoding byte at the beginning of the data, followed by an optional ‘short content description’, terminated by a NULL. This frame’s size shows as 0x00 00 00 19 – 25 bytes. That includes language (3 bytes), encoding ( 1 byte), NULL terminator (1 byte). So the actual comment string is (25-5) = 20 bytes long: “25year special album”.

Now we’ve reached the 0x98 tag boundary, so let’s stop before we get into the music data itself.
This particular MP3 file did not have any padding in the tag. Open and check other files, you might see a lot of 0x00 bytes before the tag’s end.

To add new frames, first determine what data you want to write. Calculate its length including any frame-specific bytes (like encoding for text frames). If you are writing to ID3v2.4 then encode the byte-size by reversing the bit-shifting, and make it synch-safe. Build up the frame header with the required components for the ID3 specification used in the media file, including the ‘size’ value, flags as needed (or just zero). If the file’s tag has sufficient padding to accommodate your new frame, write the frame header and data into the padded area. If the file doesn’t have enough padding, or has no padding at all, you will need to shift the audio data – possibly by building up a new tag with the new frame plus padding, writing it to a new file, then copying the music data from the old file in after the tag. Keep in mind that when you alter/add frames, you also need to update the tag header’s size value to reflect the change in length of the tag (if any). If you are moving the data into a new file, once done, you can delete (unlink) the original file, and rename the temporary file with the original media file’s name. You can verify the results of your tag manipulation in a media player (e.g. Amarok) or tag-manager (e.g. EasyTag).

Note:It might happen that you change the ID3v2.x tag, but the tag editor shows the same old data. This might be because the ID3v2.x tag is corrupted or not in proper format, and so the tag reader is reading the ID3v1.x tag at the end of the file. Strip out the ID3v1.x tag, or simply zero it out, to avoid it being displayed. Also, don’t forget to refresh the file – force the tag editor to re-read the tags.


We won’t write a ID3v2.x decoder, like we wrote for ID3v1.x . Instead we would check out the taglib API . Heard this name somewhere? Might be when updating amarok, or in a missing dependency message. This is a music tag editing library, which not only supports ID3vX.Y tags but also APE, Xiph, and FLAC tagging formats. And this is available for also Mac, and Windows platform. This is used in different applications which you currently use, like, Amarok, JuK,, Songbird and a lot more. Without talking much, lets get started.

Download taglib from your distribution repository.

yum install taglib taglib-devel taglib-doc

Or, download the source from the official site , and install by executing:

make install #as superuser

Now we are ready to code. I will implement the C Language binding to demonstrate.

/* Program: A minimal example of the taglib library */
#include <stdio.h>
#include <taglib/tag_c.h>

#ifndef FALSE
#define FALSE 0

main (int argc, char *argv[])
  TagLib_File *file;
  TagLib_Tag *tag;
  const TagLib_AudioProperties *audio_properties;

  taglib_set_strings_unicode (FALSE);

  if (argc == 1)
    printf ("Usage: %s <filename.mp3>\n",argv[0]);
    return 0;
  file = taglib_file_new (argv[1]);
  if (file == NULL)
      printf ("Error Opening File \"%s\"\n",argv[1]);
      return 1;

  tag = taglib_file_tag (file);
  audio_properties = taglib_file_audioproperties (file);

  printf ("\n[TAG]");
  printf ("\n\tTitle:   %s", taglib_tag_title (tag));
  printf ("\n\tArtist:  %s", taglib_tag_artist (tag));
  printf ("\n\tAlbum:   %s", taglib_tag_album (tag));
  printf ("\n\tYear:    %d", taglib_tag_year (tag));
  printf ("\n\tComment: %s", taglib_tag_comment (tag));
  printf ("\n\tTrack:   %d", taglib_tag_track (tag));
  printf ("\n\tGenre:   %s", taglib_tag_genre (tag));

  printf ("\n[AUDIO]");
  printf ("\n\tBitrate:      %d kbps",
	  taglib_audioproperties_bitrate (audio_properties));
  printf ("\n\tSample Rate:  %d Hz",
	  taglib_audioproperties_samplerate (audio_properties));
  printf ("\n\tChannels:     %d",
	  taglib_audioproperties_channels (audio_properties));
  printf ("\n\tTrack Length: %d min %d sec",
	  taglib_audioproperties_length (audio_properties) / 60,
	  taglib_audioproperties_length (audio_properties) % 60);
  printf ("\n\n");

  taglib_tag_free_strings ();
  taglib_file_free (file);

  return 0;

The functions are self describing. To get the documentation, check the tag_c.h header file. Which should be located in /usr/local/include/taglib/tag_c.h . It is well commented and easy to understand. That is all about taglib i will tell now.

At Last

After this journey through ID3 tags, the version-specific documentation is your best friend if you wish to start coding your own tag parser. Then there is taglib, which you can use with SQLite to store song metadata and enhance a music player, or make a tag editor. So read the documentation, hack some tags, and enjoy coding!

Links and References

First Publish Information
: This article was first published on Linux For You
(LFY), April 2010 Issue, under Creative Commons Licence.

Author: Arjun Pakrashi


21 thoughts on “What are ID3 Tags all about?

      1. I have a questions.Whats happens if bytes after flag byte are(ı mean 4 bytes) are not 0x00 00 01 18.what happens if they are 00000000,00000111,00011101,00010100.İf first bit erased then xxxx0000000000011100111010010100.So which part should I count?This doesnt make like 0x98.What do you say about this?

  1. It won’t be 0x98. You can just take the ‘x’ s as zeros and find the hex (or decimal) equivalent.

    In your case
    0000 0000 = 0x00, 0000 0111 = 0x07, 0001 1101 =0x1d, 0001 0100 = 0x14
    which makes 0x00 07 1d 14
    And if you follow what i have explained in the synchsafe integer section, or simply follow the ID3v2 standards then you can decode it as:

    _000 0000, _000 0111, _001 1101, _001 0100

    then simply forget the dashes, which is done by shifting each LSB into the next byte’s MSB (the dash)

    ____ 0000 = 0x00, 0000 0001 = 0x01, 1100 1110 = 0xce. 1001 0100 = 0x94

    That is your number is decoded into 0x1ce94 that is in decimal 118420, that is your ID3 tag is of 118420 bytes. Your calculations are right. Basically you ignore the MSB of each byte, that means you calculate the value without it, therefore you can consider the ‘x’ s in your solution as zeros.

    Maybe you would also have a look at the code to encode/decode the syncsafe integers here:

    1. I couldnt understand in the syncsafe but I understand now.Thanx for quick reply. 118420 is very big for tag right?Maybe there is picture in it.İs it possible?

        1. I have another question.I know I asked too much but .I will be appreciated if you aswer this.I have a mp3 file and ı find “APIC” bytes but ı couldn understand bytes after this bytes.İt continue like this:
          what is the meanin of the bytes before (69)(i).I look from the idtag site but I couldn understand.It says first bit after APIC byte is text encoding.this is ok it means ıso8859-1.But after that byte it says MIME byte.Mine is not $00.Mine is 01.Whats does it mean? What should I undertand till (69)(i) bytes?Thx.

    1. Sorry for the delay, I am travelling these days a lot, and the time is totally occupied by my project work. I cannot immediately answer your question without referring to the manual. The best thing you can do to get a good answer is to put up the question in . I this time if I can get through the manual then I will definitely comment here about it.

  2. Thanks very much for writing this detailed explanation, you really helped me to understand and the structure of ID3 tags, I have been struggling how to read and edit these tags. thax a lot.

Leave a Reply to phoxis Cancel reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s