mplib manual
Note: This manual is also available as pdf file for print. See the downloads page.
Table of Contents
- Introduction
- Quick Start
- More Advanced Topics
- Handling different tag versions
- Integrating mplib into your project
- Feedback
Introduction
The main thought that was on my mind while writing this library was: handling ID3 tags
should be as easy to do as possible - it's not a big deal!
A few small pages of a manual should be all you need to start over.
Another thought was to build it as being as light-weight as possible.
therefor it may not be the ideal solution for you yet if you're not very familiar with
the ID3 standard and want to do more than just editing a common set of tag infos.
However, I'll give you some introductions in the 'More Advanced Topics' below
how to managed that also. Please consider to give id3lib from <http://www.id3.org
>
a try if you find this lib to be to much limited for your needs.
All functions that do begin with 'mp_' are meant to get used by you. Please consult the
header files (mplib.h
) that come with some more detailed hints for each function, such
as error codes and additional functions I won't mention here.
Quick Start
Ok, so you want to read some tag infos from a file.. Start getting all available tags by
calling
id3_tag_list* mp_get_tag_list_from_file(char* filename)
which will return a list of tags for this file.
A MP3 file can contain more than one tag. Currently mplib supports version 1 tags
at the end of the file and version 2 at the files beginning. It's also posible that tags resists at
other locations spread all over the file (which can be usefull e.g., for web-cast radio
streams) but this is not supported and may not be in the near future. Ok, so there you
are with a list of max. 2 tags (v1 & v2). You may now iterate through the list which looks
as follows:
typedef struct _id3_tag_list
{
id3_tag *tag;
struct _id3_tag_list *next;
struct _id3_tag_list *first;
} id3_tag_list;
The id3_tag structure contains the field 'version' containing the version of that tag (1 or 2)
and which is actually everything you need to know about it. The following functions take
this tag as the first argument.
id3_content* mp_get_content(const id3_tag* tag, int field);
id3_content* mp_get_content_at_pos(const id3_tag* tag, int field, int pos);
Use them to get the content of the specified field. You may specify the field by using the defines MP_ARTIST, MP_TITLE, MP_ALBUM, MP_GENRE, MP_COMMENT, MP_YEAR and MP_TRACK. Not only that there can be more than one tag a file, but there may also be a unknown number of values for the given field. If you use the predefined fields, you should only have to care for the comments that can occur multiple times in an ID3 v2 tag.
The id3_content structure stores informations of that field in a special, binary format. Every time
you invoke mp_get_content you need to parse the content and receive a structure with the
appropriate fields set. Here's a example:
id3_content* content = mp_get_content(tag, MP_ARTIST);
id3_text_content = mp_parse_artist(content);
The id3_text_content struct is suitable for many tag fields and looks as follows:
typedef struct _id3_text_content
{
id3_encoding encoding;
char *text;
} id3_text_content;
It contains the text for that field as a null terminated string. This text field is what you are looking for.
If you also want to do some changes to the tag, you need to reverse what we have done
so far. You need to create a content structure with your informations and add it to the tag.
The following functions will help you building the struct (they all reaturn a pointer to id3_content):
mp_assemble_artist_content(const char* new_text, id3_encoding enc);
mp_assemble_title_content(const char* new_text, id3_encoding enc);
mp_assemble_album_content(const char* new_text, id3_encoding enc);
mp_assemble_year_content(const char* new_text, id3_encoding enc);
mp_assemble_genre_content(const char* new_text, id3_encoding enc);
mp_assemble_comment_content(const char* text_text, const char*, short_descr, id3_encoding enc, const char* language);
And these will set your new content to the specified field and position in the tag:
int mp_set_content(id3_tag* tag, int field, id3_content* content);
int mp_set_content_at_pos(id3_tag* tag, int field, id3_content* content, int pos);
If you need to delete content from your tag, call the functions above with value NULL as the content argument.
After your done with your changes, write the tag to a file with the function:
int mp_write_to_file(const id3_tag_list* list_of_tags_to_write, const char* filename);
As with the contents, you can delete the tags from the file by passing NULL as
the first argument. You may also use
int mp_del_tags_from_file(const char* filename);
int mp_del_tags_by_ver_from_file(int tag_version, const char* filename);
More Advanced Topics
This chapter covers working with ID3 v2 tags that have a much bigger range of
possiblities. You definitly need to get familiar with the standard before doing
anyhing with this library beyong working with the standard fields.
You'll find the standard at <http://www.id3.org
>.
To work with frames that are not supported by default, call
id3_content* mp_get_content_custom(const id3_tag* tag, const char* field);
id3_content* mp_get_content_custom_at_pos(const id3_tag* tag, const char* field, int pos);
int mp_set_custom_content(id3_tag* tag, char* field, id3_content* content);
int mp_set_custom_content_at_pos(id3_tag* tag, char* field, id3_content* content, int pos);
These functions are working with ID3 v2 frames. Here each frame is not identified by
a defined constant but a four length character field, e.g. "ENCR" or "COMM". You need to pass this
field along with the content for the frame. mplib does not provide a assemble
function for your content and this means you have to assemble the data
yourself. Please read the v2 specification and my sources (mplib_paas.c
)to
manage this. I'll add further assemble/parse functions to the lib myself when
it's out of its beta stage...
Handling different tag versions
Handling different versions of ID3 tags can be a nasty task. Most of the MP3 files you'll encounter
will only have a v1 tag, some v2 and others both of them. Last called will likely have
actual identical fields set to different values. mplib will try to cover the issue
of how to handle a tag with his version as best as it can from you; i.e. it will allow you to access
a tag allways in the same way, independently of the version. It also does automatic tag conversion:
if you set a tags field to a value that does conflict with the v1 specification, mp_set_content
will
converted the tag to v2.
Heres a overview of sitiuations when an v1 tag will be converted to v2:
artist > 30 chars
title > 30 chars
album > 30 chars
comment > 30 chars
year > 4 chars
genre not in list
encoding != latin1
comment_shortdescr set
Generally mplib tries to make v1 tags wherever possible. This means if you
create an empty tag with mp_alloc_tag
and set fields to allowed values
you'll get a v1 tag. You may enforce a v2 tag by calling
mp_alloc_tag_with_version
with 2 as the parameter. You also can do
manual tag conversion by calling mp_convert_to_v1/v2
. One thing to
notice is that mp_set_content
will automatical convert v1 tags to v2
if necessary but never v2 to v1.
Integrating mplib into your project
If you do develop any software that makes use of mplib, I encourage you to ship mplib with it instead of referring to it's homepage and let the user install it. There are a number of reasons for this. First of all I think that make the user install mplib as a shared library would be not very wise, cause it is very unlikly that any other program except yours will make use of it. Second, the user should not have to download such a small library, it would be a extra waste of time making your software run.
If you're developing a commercial, serversided application, the things are looking easy here. Put the mplib package on the destination server (or at least a similiar system) and compile. You'll find a static binary in the src/.lib directory. You can also do 'make install' to get it into the systems lib dir.
mplib was build using GNU Autotools. You'll find that most of the free major software
written does make use of this set of tools for a number of strong reasons. Please refer
to the autotools homepage at <http://www.gnu.org/software/autoconf
> for more
informations.
If you allready use autotools add AC_CONFIG_SUBDIRS(mplib) to your configure.in file, which will result in ./configure being invoked in the mplib directory, too. You need also to make libtool available. To make sure it does all the linking add '$(OBJECTS): $(top_builddir)/libtool' to the appropriate make files (mostly Makefile.am in the src dir).
The latest releases became rather fat with the docs and the testsuite. You should delete all unnecessary files before making this package a part of your distribution. You can delete the doc and testsuite dir.
Feedback
I hope this document could give you some hints on how to get started. This doc is as much in beta stage as the rest of this library, I'll work on it, giving examples and stuff when I'm having some time for it. Feel free to let me know about things you missed and what problems you encountered.
Good luck and have some fun with it.
Stefan Podkowinski,