UltraID3Lib is a fully object-oriented class library for the reading and editing of both ID3v1 and ID3v2 tags in MP3 files. Reading of MPEG data, such as duration, bitrate, and frequency, is supported as well. UltraID3Lib was written in Visual Basic .NET and is available as a .NET dll.
Tag | A section of an MP3 file containing data about the track. |
Frame | The portion of a ID3v2 Tag which contains a particular element of data (the Field) and its associated metadata. For example, the Comments Frame not only contains the actual comments, but also contains a description of the comments, the language of the comments, and even the text encoding used to store the comments. |
Field | Generically refers to the significant values in either an ID3v1 or an ID3v2 tag. ID3v1 tags only contain Fields, whereas ID3v2 tags contain Frames which contain the Fields and the Frame's metadata. |
ID3 Version 1 | A tag version which allows for a limited amount of fixed-width text fields. |
ID3 Version 2 | A tag version which allows for numerous types of data to be stored in an MP3, including text, numeric, and even binary information such as graphics. |
ID3 | The standard for encoding meta data into mp3 file |
The most important class in UltraID3Lib is the UltraID3 class. This is the class used to read and write tag data. It has the following properties to store data about a track: Artist, Title, Album, Track Number, Year, and Genre. The UltraID3 class also has an ID3v1Tag property and an ID3v23Tag which represents the two ID3 tag versions supported by UltraID3Lib. The ID3v1Tag property and the ID3v23Tag property are themselves classes which also have Artist, Title, Album, Track Number, Year, and Genre properties. The fields for each version can be accessed directly using the ID3v1Tag and the ID3v23Tag properties or they can be accessed using the "generic" properties of the UltraID3 class. The generic properties of the UltraID3 class have different behaviors depending on whether a write or a read is done. In general, preference is given to ID3v23Tag over ID3v1Tag in both reads and writes. See charts below for details.
ID3v1 Tag Exists | ID3v2 Tag Exists | Tag Version From Which Values Are Read | Tag Version To Which Values Are Written |
No | No | N/A | ID3v23Tag |
Yes | No | ID3v1Tag | ID3v1Tag |
No | Yes | ID3v23Tag | ID3v23Tag |
Yes | Yes | ID3v23Tag | ID3v1Tag and ID3v23Tag |
The Read method will open the specified file, search for the ID3 version 1 tag and the ID3 version 2 tag, parse the tags found, and set the appropriate values in the ID3v1Tag and ID3v23Tag class properties. After a read is performed, the UltraID3.ID3v1.FoundFlag and UltraID3.ID3v2.FoundFlag properties can be checked to verify if the corresponding tag was found in the file which was read. The UltraID3.ID3v1.WriteFlag and UltraID3.ID3v2.WriteFlag properties control whether the corresponding tag is written when the Write method is called. When a read is done, the WriteFlag values are defaulted to the corresponding FoundFlag. For example, if a file has an ID3 version 2 tag, both the ID3v23Tag.FoundFlag and the ID3v23Tag.WriteFlag will initially be set to True after a read of the file.
There are seventy-four individual frames specified in the ID3 v2.3 standard. UltraID3Lib has a separate class for each frame with properties specific to the kind of data it stores. When an ID3v23Tag property, such as Artist or Title, is used to get or set a value, the corresponding underlying Frame is actually used. The UltraID3.ID3v23Tag.Frames.GetFrame method is used to retrieve Frames which can only have one instance in a Tag, whereas the UltraID3.ID3v23Tag.Frames.GetFrames method is used to retrieve Frames which can have multiple instances in a Tag.
Frame ID | Frame Description | Frame Class |
AENC | Audio encryption | ID3AudioEncryptionFrame |
APIC | Attached picture | ID3PictureFrame |
COMM | Comments | ID3CommentsFrame |
COMR | Commercial frame | ID3CommercialFrame |
ENCR | Encryption method registration | ID3EncryptionMethodRegistrationFrame |
EQUA | Equalization | ID3EqualizationFrame |
ETCO | Event timing codes | ID3EventTimingCodesFrame |
GEOB | General encapsulated object | ID3GeneralEncapsulatedObjectFrame |
GRID | Group identification registration | ID3GroupIdentificationRegistrationFrame |
IPLS | Involved people list | ID3InvolvedPeopleListFrame |
LINK | Linked information | ID3LinkedInformationFrame |
MCDI | Music CD identifier | ID3CompactDiscIdentifierFrame |
MLLT | MPEG location lookup table | ID3MpegLocationLookupTableFrame |
OWNE | Ownership frame | ID3OwnershipFrame |
PRIV | Private frame | ID3PrivateFrame |
PCNT | Play counter | ID3PlayCounterFrame |
POPM | Popularimeter | ID3PopularimeterFrame |
POSS | Position synchronisation frame | ID3PositionSychronizationFrame |
RBUF | Recommended buffer size | ID3RecommendedBufferSizeFrame |
RVAD | Relative volume adjustment | ID3RelativeVolumnAdjustmentFrame |
RVRB | Reverb | ID3ReverbFrame |
SYLT | Synchronized lyric/text | ID3SynchronizedLyricsFrame |
SYTC | Synchronized tempo codes | ID3SynchronizedTempoCodesFrame |
TALB | Album/Movie/Show title | ID3AlbumFrame |
TBPM | BPM (beats per minute) | ID3BeatsPerMinuteFrame |
TCOM | Composer | ID3ComposersFrame |
TCON | Content type | ID3GenreFrame |
TCOP | Copyright message | ID3CopyrightMessageFrame |
TDAT | Date | ID3RecordingDayMonthFrame |
TDLY | Playlist delay | ID3PlaylistDelayFrame |
TENC | Encoded by | ID3EncodedByFrame |
TEXT | Lyricist/Text writer | ID3LyricistFrame |
TFLT | File type | ID3FileTypeFrame |
TIME | Time | ID3RecordingDurationTimeFrame |
TIT1 | Content group description | ID3ContentGroupDescriptionFrame |
TIT2 | Title/songname/content description | ID3TitleFrame |
TIT3 | Subtitle/Description refinement | ID3SubtitleFrame |
TKEY | Initial key | ID3InitialKeyFrame |
TLAN | Language(s) | ID3LanguagesFrame |
TLEN | Length | ID3RecordingDurationMillisecondsFrame |
TMED | Media type | ID3MediaTypeFrame |
TOAL | Original album/movie/show title | ID3OriginalAlbumFrame |
TOFN | Original filename | ID3OriginalFileNameFrame |
TOLY | Original lyricist(s)/text writer(s) | ID3OriginalLyricistFrame |
TOPE | Original artist(s)/performer(s) | ID3OriginalArtistFrame |
TORY | Original release year | ID3OriginalYearFrame |
TOWN | File owner/licensee | ID3OwnerFrame |
TPE1 | Lead performer(s)/Soloist(s) | ID3ArtistFrame |
TPE2 | Band/orchestra/accompaniment | ID3BandFrame |
TPE3 | Conductor/performer refinement | ID3ConductorFrame |
TPE4 | Interpreted, remixed, or otherwise modified by | ID3InterpretedByFrame |
TPOS | Part of a set | ID3PartOfSetFrame |
TPUB | Publisher | ID3PublisherFrame |
TRCK | Track number/Position in set | ID3TrackNumFrame |
TRDA | Recording dates | ID3RecordingDatesFrame |
TRSN | Internet radio station name | ID3InternetRadioStationNameFrame |
TRSO | Internet radio station owner | ID3InternetRadioStationOwnerFrame |
TSIZ | Size | ID3SizeBytesFrame |
TSRC | ISRC (international standard recording code) | ID3InternationalStandardRecordingCodeFrame |
TSSE | Software/Hardware and settings used for encoding | ID3EncoderSettingsFrame |
TYER | Year | ID3YearFrame |
TXXX | User defined text information frame | ID3UserDefinedTextFrame |
UFID | Unique file identifier | ID3UniqueFileIDFrame |
USER | Terms of use | ID3TermsOfUseFrame |
USLT | Unsychronized lyric/text transcription | ID3UnsynchedLyricsFrame |
WCOM | Commercial information | ID3CommercialInformationWebAddressFrame |
WCOP | Copyright/Legal information | ID3CopyrightInformationWebAddressFrame |
WOAF | Official audio file webpage | ID3OfficialAudioFileWebAddressFrame |
WOAR | Official artist/performer webpage | ID3OfficialArtistWebAddressFrame |
WOAS | Official audio source webpage | ID3OfficialAudioSourceWebAddressFrame |
WORS | Official internet radio station homepage | ID3OfficialInternetRadioStationWebAddressFrame |
WPAY | Payment | ID3PaymentWebAddressFrame |
WPUB | Publishers official webpage | ID3PublisherWebAddressFrame |
Dim TrackFileName As String = "Powderfinger - My
Happiness.mp3" 'Create a new instance of the main UltraID3 class Dim TestUltraID3 As New UltraID3 Try 'Read the track file TestUltraID3.Read(TrackFileName) 'Display a single string representation of the common ID3 fields MsgBox(TestUltraID3.ToString) 'Display the Title, letting UltraID3 determine the appropriate tag source MsgBox(TestUltraID3.Title) 'Check to see if the ID3v1 tag was found If TestUltraID3.ID3v1Tag.FoundFlag Then 'Display the Title property of the ID3v1Tag directly MsgBox(TestUltraID3.ID3v1Tag.Title) End If 'Check to see if the ID3v23 tag was found If TestUltraID3.ID3v23Tag.FoundFlag Then 'Display the Title property of the ID3v23Tag directly MsgBox(TestUltraID3.ID3v23Tag.Title) 'Retrieve the ID3TitleFrame, if any Dim MyID3TitleFrame As ID3TitleFrame = CType(TestUltraID3.ID3v23Tag.Frames.GetFrame(SingleInstanceFrameTypes.Title), ID3TitleFrame) 'Check to see if the ID3TitleFrame exists If Not MyID3TitleFrame Is Nothing Then 'Display the Title property of the ID3TitleFrame MsgBox(MyID3TitleFrame.Title) End If End If 'Retrieve any non-fatal exceptions which might have occurred Dim UltraID3TagExceptions As UltraID3ContextMetaDataException() = TestUltraID3.GetExceptions() If UltraID3TagExceptions.Length > 0 Then Dim IndexUltraID3TagException As UltraID3TagException 'Iterate through each found non-fatal exception For Each UltraID3ContextMetaDataException As UltraID3ContextMetaDataException In UltraID3TagExceptions 'Display the Message of the non-fatal exception MsgBox(IndexUltraID3TagException.Message) Next End If 'Catch any fatal exceptions Catch exc As Exception MsgBox(exc.Message) End Try |
There are three types of Exceptions that can occur during the UltraID3.Read method...
Tag
exceptions
Thrown during a Read
Prevents a Tag from being read
Frame
Errors
Prevents a Frame from being read
Not thrown, but retrieved by the GetExceptions method after a Read
Frame
Warnings
Does not prevent a Frame from being read, but just records a
non-standard format to the Frame
Not thrown, but retrieved by the GetExceptions method after a Read
So, why are there exceptions that have to be retrieved using a function instead of being caught in a Try/Catch block? Well, many of the exceptions that would be returned by the GetExceptions can also be thrown in other situations. In other words, in the context of a Read, an exception may just give a warning that particular Frame field value is out of bounds or is not in the correct format. But if you were to try a an invalid value to Frame field, the same exception would be thrown.
While the primary purpose of UltraID3Lib is to read and write ID3 metadata in MP3's, reading of MPEG data is also supported. Probably the most commonly referenced MPEG metadata values are the duration and the bit rate. However, because MP3 files are constructed from an independent set of audio frames, determining the overall duration and bit rate of a track is not a straight forward matter. There are essentially four ways that one can get the duration and/or bit rate of an MP3 using UltraID3Lib, each one having their own pros and cons.
A) UltraID3.GetMPEGTrackInfo.Duration, UltraID3.GetMPEGTrackInfo.AverageBitRate
This is the most accurate method, but because it has to read each individual audio frame, it is also the most expensive. Each audio frame is read sequentially in order to determine the total duration and average bit rate of the overall track. Because of the sequential nature of the read, if any of the frames are corrupt, the location of the next frame cannot be determined and the function will fail.
B) UltraID3.FirstMPEGFrameInfo.Duration, UltraID3.FirstMPEGFrameInfo.Bitrate
This method is a good estimate of the duration and bit rate of a track, but because it only uses the first audio frame found, the results are not guaranteed 100% accurate. In particular, the duration is calculated using the overall file length and the bit rate recorded in the first MPEG frame found. But the bit rate can change from frame to frame, so the calculated duration and the bit rate can only ever be an estimate, albeit a most likely very good estimate.
C) UltraID3.FirstMPEGFrameInfo.VBRInfo.Duration
Using the Variable Bit Rate header, encoders have the ability to store information about the VBR parameters used to encode the track. If this optional information exists, the VBRInfo.Duration will return the recorded value. Please note, however, that this information is only as good as the encoder which stored the data and applies only to when the file was first encoded. If the file was edited after the initial encoding, this duration will be incorrect unless it was updated by the editing program.
D) UltraID3.Duration.
This method uses the Variable Bit Rate header (if it exists) to calculate the duration. As long as the Frame Count field is accurate, the duration will be accurate as well. If the VBR header doesn't exist or if it doesn't contain a Frame Count field, then the method will return the UltraID3.FirstMPEGFrameInfo.Duration.