Saturday, May 10, 2014

Reading and writing ID3 tags in an MP3 file

One of the things that is fairly easy to make in RealBasic (or Xojo) is of course a small media player. The MoviePlayer component allows you to quickly build a small music player to play MP3 files that fits your own tastes and particular needs. What is a bit harder to do though, is to display the artist and title tags of an MP3 file. And slightly harder still to find a way to display any embedded album art in the ID3 tag. There is a way to get some metadata about a file via quicktime, but this is limited to basic artist and title information.

First thing to read ID3 tags is to know about the various versions of the tags. There is the version 1 (ID3V1) of tagging. That appends a fixed size block of text data to the end of the MP3 file. The more capable and now widespread tag is the ID3 version 2 with its variations 2.2, 2.3 and 2.4 (ID3V2). This is a block with text, image or any binary data of flexible size at the beginning of the file before the MP3 music data. There is quite a bit of documentation on these formats on the web, example source in other languages and of course lots of MP3 files with tags to be looked at with a Hex Editor.

There is source code in RealBasic on the web to read ID3 version 1 tags, but no source for reading the ID3V2 tags. Wanting to be able to read album art and be capable of also reading modern tags with their international characters, I made some classes to do just that for both ID3V1 and ID3V2.

These classes open the MP3 file as a BinaryStream and then parse the file byte-by-byte to see what version tag is present and extract the metadata on title, artist, etc and a Picture for the album art.


The classes are a bit basic in that they only read and keep as properties a limited set of metadata, only the items I was interested in. The classes would on the other hand be not that hard to expand to create a dictionary of all tags in a file and read any and all metadata. Another limitation is that the ID3V2Reader class only returns the first image found in the tag as the album art and ignores any additional images.

The ID3V2Reader does however know about and is robust against tags that were written by an older iTunes version that used base 256 encoded tag sizes instead of the correct base 128 encoded size. (Took a few unexpected results on a few MP3 files to clue on to that one though...) The class should also deal correctly with all the possible text encodings, including UTF16 without a BOM.

Wanting to be able to edit and update tags, also an ID3 tag writing class was made. When writing tags this requires a source file as FolderItem and a destination file (as FolderItem) to write the new file with tags into with the MP3 data from the source file. Note that any metadata of a type not supported by the class is left out and not copied from the source.


As the class structure shows, a few helper encoding and decoding functions are used. Numbers in the tag structure are e.g. encoded so that there will never be a series of 4 zero's, because that is a sync tag for the MP3 decoder (or at least something like that).

As a measure to prevent having to re-write the entire file every time a metadata element is changed, e.g. by adding a single character to the title, a padding area is defined at the end of the tag. This allows for small changes in the size of the tag without having to do a full re-write. The size of this area can be set in the ID3Writer class to a value in bytes.

A zipped archive with the source to all three classes can be downloaded here.

These should work and compile on pretty much any version of RealBasic / Real Studio / Xojo.

3 comments:

  1. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. Euh, yes I do. Will spruce it up a bit and post it as well. (Hmmm, am I right in concluding you got it to work now?)

      Delete