Using the framework
Contents
How to use
TagAPI to manipulate Tags
Step 1.
Include the header file TagAPI.h into your file by using #import "ID3/TagAPI.h"
Step 2.
Create a tag object using TagAPI
*Tag = [[TagAPI alloc] initWithGenreList: GenreDictionary];
- The GenreDictionary is a dictionary that contains the
genreNames. If you leave it blank the framework will use it own
dictionary. The framework will not however update its internal
dictionary if you add or find a new genre name. A sample
dictionary in the form of a XML .plist file is can be found here. Use the following code
chunk to load it.
NSMutableDictionary * GenreDictionary
=
[[MutableDictionary alloc] initWithContentsOfFile:
@"~/GenreDictionary.plist"]];
Step 3.
Attach the tag object to a file by passing it a file path [Tag examineFile:@"path name"];
Step 4. Grab
a tag contents by using either the high level calls for common
attributes
or use the generalised calls to directly access more exotic frames in
V2
tags.
a) High level calls
NSString *
Title = [Tag getTitle]; //
gets the song title from the V2 tag if present or V1 if the V2 is not
present
Similarly for the
other common attributes use methods
-(NSString
*)getArtist;
-(NSString *)getAlbum;
-(int)getYear;
-(int)getTrack;
-(int)getTotalNumberTracks;
-(int)getDisk;
-(int)getTotalNumberDisks;
-(NSArray *)getGenreNames;
-(NSString *)getComments;
-(NSMutableArray *)getImage;
-(NSString *)getComposer;
-(NSArray *) getGenreName;
//returns an array
of genre descriptive stings typically there will be only one
string. It can be empty if no genres were defined.
-(NSString
*)getEncodedBy;
If you want to the framework to
explicitly search a particular tag (v1, v2) when using any of the get
methods, then you can use the -selectTag method.
-(void)selectTag:(int)parse
Where parse can be set to 0, 1, 2.
0 - lets the Framework automatically select the tag to return the
result from.
1 - forces the Framework to always parse the v1 tag.
2 - forces the Framework to always parse the v2 tag.
If you use this method it is up to you to check that there is a tag of
the appropriate version present. If not then you will get
meaningless results. (Null strings or empty arrays.)
For v2 tags you can use the following function to extract
images from the tag (eg album covers).
-
(NSMutableArray
*)getImage;
The method extracts all images present in the v2 tag and stores the
result in an
array containing dictionary objects. The dictionary objects
contain the image, the descriptive
text and other information. The dictionary structure is as below.
{ "Image" , NSBitmapImageRep *
"Picture Type", NSString *
// the standard descriptive string, see spec
"Mime Type", NSString * // as the name suggests
"Description", NSString * // an optionally populated
free text description
}
b) Generalised methods for
accessing v2.x tag content (Advanced
Access to v2 tag content)
Background on ID3
frames
ID3 version 2 tags are composed of an
envelope (the tag) and a number of information frames within this
envelope. Each information frame holds a single atom of
information (eg title, name, tracks, ...). The ID3 v2 standards
define a number of different frame types. Some frames contain
simple text, others contain structured binary information. Some
frame can appear multiple times in a tag others are limited to one
instance (typically text frame).
v2.0-v2.2 Tags use three letter upper case frame IDs to identify each
frames (see v2.2 standard for frame types). v2.3 and v2.4
standards use four letter upper case frame IDs (see v2.3 and v2.4
standard for frame types). v2.0-v2.2 frame IDs are not compatible
with v2.3 and v2.4 frame IDs, v2.3 and v2.4 are mostly
compatible. In most cases a mapping can be made between v2.0-2.2,
v2.3 and v2.4 frame IDs. Similarly the contents in equivalent
frames for v2.0-2.2, v2.3 and v2.4 is generally compatible between each
version (ie title frame types are all compatible text frames).
Some exceptions exist.
Using the generalised access method
(Recommended method to obtain tag information not
available though the simple high level methods described above)
The generalised method
- (NSArray *)
getContentForFrameID:(NSString *)ID provides simple keyed
access to the contents of any class of frame you wish. It allows
you to use the frame ID types from any tag version to access the frame
ID in other version tags. This allows you to program with using
the frame IDs for one version with out having to switch frame IDs to
match the current tag version. (ie The method is able to convert any
version frame ID, be it v2.0-2.2, v2.3 or v2.4 to the correct frame ID
for the current tag if a mapping exists. )
The method returns an array that contains the contents of each frame
with in the tag of the selected ID type. The array will contain
NSData object if the frame types is a binary frame or NSString object
if it is a text type.
To extract the song title from a tag you can write:
- (NSArray *) getContentForFrameID:@"TT2"; // TT2 is the
v2.0-v2.2 frame ID for the frame containing the song title.
The method will automatically map the frame ID to TIT2 if the tag is a
v2.3 or V2.4 tag type. Similarly if TIT2 had been used and the
tag was a v2.0-2.2 tag then the ID would have been mapped back
TT2. If no mapping existed (the tag version does not support that
frame type) the the array is returned empty.
The resultant array would contain a
single string object containing the song title, assuming that the frame
exists in the tag.
Note
It is recommended that you use the high
level simple access method described in a), where possible as they
support content parsing and automatic v1 tag handling.
Step 5. Get
general mpeg meta information
(length of song in seconds, bitrate, ...) using the following methods.
-
(int) getDuration; // gets length of song in seconds
- (int) getBitRate;
// get bitrate
- (NSMutableString *)
getEncoding; // get a string detailing how the file
was encoded (format may change)
- (int)
getFrequency; // get sample rate
-(NSString *)getDurationString;
-(int)getBitRate;
-(NSString *) getVersionString;
-(NSString *) getLayerString;
-(NSString *) getBitRateString;
-(NSString *) getFrequencyString;
-(NSString *) getChannelString;
Step 6.
Change a tags contents by using either the high level calls for
common
frames or use the generalised calls to directly access more exotic
frames.
The high level calls change the contents of the tag stored in
memory. You need to tell the Framework to update the file in
order
for the changes to be made in the actual file, see step 7.
a) bool result = [Tag setTitle: (NSString *) title ]; // Sets
the song title
from the both V1 and V2 tags
Similarly for the
other common attributes use methods
-(BOOL)setTitle:(NSString
*)Title;
-(BOOL)setArtist:(NSString *)Artist;
-(BOOL)setAlbum:(NSString *)Album;
-(BOOL)setYear:(int)Year;
-(BOOL)setTrack:(int)Track
totalTracks:(int)Total;
-(BOOL)setDisk:(int)Disk
totalDisks:(int)Total;
-(BOOL)setGenreName:(NSArray
*)GenreName; //
The
array contains string names
-(BOOL)setComments:(NSString
*)Comment;
-(BOOL)setImages:(NSMutableArray
*)Images;
-(BOOL)setEncodedBy:(NSString *)Text;
-(BOOL)setComposer:(NSString *)Text;
b) Generalised methods for
setting v2.x tag content (Advanced
method to set v2 tag content)
Background on ID3
frames (repeat of text in step 4 b) )
ID3 version 2 tags are composed of an
envelope (the tag) and a number of information frames within this
envelope. Each information frame holds a single atom of
information
(eg title, name, tracks, ...). The ID3 v2 standards define a
number of
different frame types. Some frames contain simple text, others
contain
structured binary information. Some frame can appear multiple
times in
a tag others are limited to one instance (typically text frame).
v2.0-v2.2 Tags use three letter upper
case frame IDs to identify each
frames (see v2.2 standard for frame types). v2.3 and v2.4
standards
use four letter upper case frame IDs (see v2.3 and v2.4 standard for
frame types). v2.0-v2.2 frame IDs are not compatible with v2.3
and
v2.4 frame IDs, v2.3 and v2.4 are mostly compatible. In most
cases a
mapping can be made between v2.0-2.2, v2.3 and v2.4 frame IDs.
Similarly the contents in equivalent frames for v2.0-2.2, v2.3 and v2.4
is generally compatible between each version (ie title frame types are
all compatible text frames). Some exceptions exist.
Using
the generalised content setting method
(Recommended method to set tag information not available though the
simple high level methods described above)
The generalised method -(BOOL)setContent:(NSArray *)Content
forFrame:(NSString *)IDAlias
provides simple keyed access to the contents of any class of frame you
wish. It allows you to use the frame ID types from any tag
version to
access the frame ID in other version tags. This allows you to
program
with using the frame IDs for one version with out having to switch
frame IDs to match the current tag version. (ie The method is able to
convert any version frame ID, be it v2.0-2.2, v2.3 or v2.4 to the
correct frame ID for the current tag if a mapping exists. )
The method returns an array that
contains the contents of each frame
with in the tag of the selected ID type. The array will contain
NSData
object if the frame types is a binary frame or NSString object if it is
a text type.
To extract the song title from a tag
you can write:
-(BOOL)setContent:[NSArray
arrayWithObject:@"Cool song title"] forFrame:@"TT2"; // TT2
is the v2.0-v2.2 frame ID for the frame containing the song title.
The method will automatically map the
frame ID to TIT2 if the tag is a
v2.3 or V2.4 tag type. Similarly if TIT2 had been used and the
tag was
a v2.0-2.2 tag then the ID would have been mapped back TT2. If no
mapping existed (the tag version does not support that frame type) the
method returns NO.
<>Note
- It is recommended that you use the
high level simple setting methods described in a), where possible, as
they
support content parsing and automatic v1 tag handling.
Note
- the Framework will create new tag object in memory if no tag is
found in the file, ie create new tag object. These tags will be
written back to file only when you call the updateFile method. (see
below)
Step 7. You
need to tell the Framework to write
the updated tags back to the file. You
need to use - (int) updateFile;
to
write the tag to the file. The method return 0 if it succeeds, 1
if it fails to update a V1 tag, 2 if it fails to update a v2 tag and 3
if it fails to update both tags. The high level API will re-pad
the tag
if needed and will write both a V1 and V2 tag to ensure maximum
compatibility (see section on changing default if you want to change
what tags are written).
Step 8. Open
tags from another file. Once you have a TagAPI object allocated you can
simply use the - (bool)
examineFile:(NSString *)Path; method to open a new file for
processing (i.e.
start at step three again).
Getting other
information about the Tag
The High level API also provides an interface to get other information
about a files tags. Uses the following calls to get the
information once you have initialized the Tag object with a file.
-(BOOL)
foundTag; // returns yes if a tag (v1 or v2) was found
-(bool)
v1TagPresent; // returns yes if v1 tag is present
-(bool) v2TagPresent; // returns yes
if v2 tag is present
-(NSArray *) getFrameList; //
get an array of containing the names of all the frames in the current
v2 tag
-(long int) getFileSize;
-(int) getPaddingLength; // only applicable to v2 tags
-(int) getTagLength; // only
applicable to v2 tags
-(NSString*) getPath;
-(NSData *) getHash; // gets a simple md5 hash of the first
3*2048 bytes of the MP3 data (ie the tag is not included) this can be
used for simple fingerprinting for better database storage.
-(NSArray *)getGenreList; // gets a list of the Genres
-(NSMutableArray *)getFrame:(NSString *)Title;
Setting the
Framework's default behavior
The data.plist used by the Framework now includes a Dictionary under
the key "preferences" that
specifies the default behavior of the Framework. The "preference" dictionary contains a
number of keys that typically contain Boolean objects that can be set
to modified the default behavior of the Framework. If you want to
change these values you can use the property list editor to edit the
data.plist file. The keys are:
"Default V2 tag -
Major number "
Specifies the major version number of
the default V2 tag type that the Framework will create when a tag is
not available. Default value is 3 (ie a v2.3.x tag). No not
set this value greater than 4. Version 3 tags are widely
supported hence the default value is 3. I some cases with old
players you may want to set this value to 2 or 0.
"Default V2 tag -
Minor number"
Specifies the minor version number of
the default V2 tag type that the
Framework will create when a tag is not available. Default value
is 0
(ie a v2.x.0 tag). Unless you are using funny frames I do not
recommend changing this values as most (read all) player will not
recognise the tag.
"Drop V1"
Tells the Framework to drop the V1 tag
if a v2 tag is present or if the Framework has been set to writing a V2
tag to file. The V1 tag will not be dropped if the v2 tag was not
successfully written or if "Write V1
Always" key is set to YES. The default value is NO ie the
v1 tag is not dropped by default.
"Parse V1"
Tells the Framework to always parse the
V1 tag. The default value is NO (fastest behavior). The
framework will automatically check for and load the V1 tag if you use
the v1TagPresent or if you try to change the tag and "Write V1
always" is set.
"Parse V1 only if
V2 does not exist"
Tells the Framework to look for a v1
tag if no v2 tag was found. This key has no effect if "Parse V1" is set to YES.
Default value is yes.
"V1 auto - fallback"
Tells the Framework to automatically
check the v1 tag (if present) for any information that it could not
find in the v2 tag. Given the limited nature of the v1 tag the
framework can
only check for title, artist, album, comment, track, genre and
year. Default value is yes.
"Write V1 Always"
Tells the Framework to always write
a V1 tag. This value overrides the behavior of "Drop V1". The default value
is Yes (improve compatibility as some old player can not read v2 tags).
"Write V2 Always"
Tells the Framework to always write a
V2 tag. The default value is Yes.
"iTunes v2.4
compatability mode"
Tells the Framework to write broken
v2.4 frames if the Framework detects a broken iTunes v2.4 frames when
reading in the tag.