ID3V2一共有四个版本,ID3V2.1/2.2/2.3/2.4,目前流行的播放软件一般只支持第三版即ID3V2.3,
由于ID3V1记录在文件的末尾处,ID3V2就只能记录在文件的首部了,也是因为这个原因,
对ID3V2的操作比ID3V1要慢,而且ID3V2的结构比ID3V1的结构复杂的多,但是ID3V2可以记录更多的信息,长度可变
ID3V2.3由一个标签头和若干个标签帧或者一个扩展标签头组成,至少要有一个标签帧,每一个标签帧记录一种信息,例如作曲、标题等
标签头格式:
char Header[3]; /*必须为“ID3”否则认为标签不存在*/
char Ver; /*版本号ID3V2.3 就记录3*/
char Revision; /*副版本号此版本记录为0*/
/* 标志字节一般为0,仅使用了 前3个bit 定义如下(111000000B)
第8位:表示是否使用Unsynchronisation
第7位:表示是否有扩展头部,一般没有,所以一般也不设置
第6位:表示是否为测试标签,99.99 % 的标签都不是测试标签,不设置
*/
unsigned char Flag;
/*标签帧大小(不包括头的大小),这个大小比较怪,每字节仅底7位有效,4个底7位拼起来
标签帧大小共四个字节,每个字节只使用低7位,最高位不使用恒为0,计算时将最高位去掉,得 到28bit的数据,计算公式如下:
Size = (Size[0] & 0x7F) * 0x200000 + (Size[1] & 0x7F) * 0x4000 + (Size[2] & 0x7F) * 0x80 + (Size[3] & 0x7F)
*/
char Size[4];
实际找的MP3测试中没有发现扩展头的情况,ID3的官方网站上不去, 不知道扩展头在标签头的后面,还是在标签帧的后面。
标签帧的格式:
/*标识帧,说明其内容,例如作者/标题等 TIT2=标题 TPE1=作者 TALB=专集*/
char ID[4];
/*帧内容的大小,不包括帧头,不得小于1 */
unsigned char Size[4];
/*标志帧,只定义了6 位 使用每个字节的高三位,其他位均为0(11100000B 11100000B)
16 -- 标签保护标志,设置时认为此帧作废
15 -- 文件保护标志,设置时认为此帧作废
14 -- 只读标志,设置时认为此帧不能修改
8 -- 压缩标志,设置时一个字节存放两个BCD 码表示数字
7-- 加密标志
6-- 组标志,设置时说明此帧和其他的某帧是一组
*/
unsigned char Flags[2];
标签帧的大小的计算方式:
int getContentSize() {
int size = 0,b=0;
b = (int)this->Size[0]; size = b ;
b = (int)this->Size[1]; size = (size << 8) + b;
b = (int)this->Size[2]; size = (size << 8) + b;
b = (int)this->Size[3]; size = (size << 8) + b;
return size;
}
标签帧的种类
FrameID | Class Name | 2 | 3 | 4 | |
Audio Encryption | AENC | AudioEncryptionFrame | P | P | P |
Attached Picture | APIC | AttachedPictureFrame | P | P | P |
Audio seek point index | ASPI | P | |||
Comment | COMM | TextWithLanguageFrame | P | P | P |
Commercial Frame | COMR | CommercialFrame | P | P | |
Encryption Method Registraion | ENCR | DataWithSymbolFrame | P | P | |
Equalisation (2) | EQU2 | P | |||
Equalization | EQUA | Equalisation | P | P | |
Event Timing Code | ETCO | EventTimingCodeFrame | P | P | P |
General Encapsulated Object | GEOB | GeneralFileFrame | P | P | P |
Group Identification Registration | GRID | DataWithSymbolFrame | P | P | |
Involved People List | IPLS | TextFrame | P | P | |
Linked Information | LINK | LinkFrame | P | P | P |
Music CD Identifier | MCDI | BinaryFrame | P | P | P |
Mpeg Location Lookup Table | MLLT | P | P | P | |
Ownership Frame | OWNE | OwnershipFrame | P | P | |
Paly Counter | PCNT | PlayCounterFrame | P | P | P |
Popularimeter | POPM | PopularimeterFrame | P | P | P |
Position Synchronisation Frame | POSS | PositionSynchronisedFrame | P | P | |
Private Frame | PRIV | PrivateFrame | P | P | |
Recommended Buffer Size | RBUF | RecomendedBufferSizeFrame | P | P | P |
Relative volume adjustment (2) | RVA2 | P | |||
Relative Volume Adjustment | RVAD | RelativeVolumeFrame | P | P | |
Reverb | RVRB | ReverbFrame | P | P | P |
Seek frame | SEEK | P | |||
Signature frame | SIGN | P | |||
Synchronized Lyric/Text | SYLT | SynchronisedText | P | P | P |
Synced Tempo Codes | SYTC | SynchronisedTempoFrame | P | P | P |
Album | TALB | TextFrame | P | P | P |
BPM ( Beats Per Minute ) | TBPM | TextFrame | P | P | P |
Composer | TCOM | TextFrame | P | P | P |
Content Type | TCON | TextFrame | P | P | P |
Copyright Message | TCOP | TextFrame | P | P | P |
Date | TDAT | TextFrame | P | P | |
Encoding time | TDEN | TextFrame | P | ||
Playlist Delay | TDLY | TextFrame | P | P | P |
Original release time | TDOR | TextFrame | P | ||
Recording time | TDRC | TextFrame | P | ||
Release time | TDRL | TextFrame | P | ||
Tagging time | TDTG | TextFrame | P | ||
Encoded By | TENC | TextFrame | P | P | P |
Lyricist/ Text Writer | TEXT | TextFrame | P | P | P |
File Type | TFLT | TextFrame | P | P | P |
Time | TIME | TextFrame | P | P | |
Involved people list | TIPL | TextFrame | P | ||
Content Group Desc | TIT1 | TextFrame | P | P | P |
Title/Songname/Content Desc | TIT2 | TextFrame | P | P | P |
Subtitle/Description | TIT3 | TextFrame | P | P | P |
Initial Key | TKEY | TextFrame | P | P | P |
Language | TLAN | TextFrame | P | P | P |
Length | TLEN | TextFrame | P | P | P |
Musician credits list | TMCL | TextFrame | P | ||
Media Type | TMED | TextFrame | P | P | P |
Mood | TMOO | TextFrame | P | ||
Orginal Album | TOAL | TextFrame | P | P | P |
Original FileName | TOFN | TextFrame | P | P | P |
Original Lyricist | TOLY | TextFrame | P | P | P |
Original Artist | TOPE | TextFrame | P | P | P |
Orginal Release Year | TORY | TextFrame | P | P | |
File Owner/License | TOWN | TextFrame | P | P | |
Lead Artist | TPE1 | TextFrame | P | P | P |
Band Artist | TPE2 | TextFrame | P | P | P |
Conductor | TPE3 | TextFrame | P | P | P |
Interpreted, Remixed | TPE4 | TextFrame | P | P | P |
Part of a set | TPOS | TextFrame | P | P | P |
Produced notice | TPRO | TextFrame | P | ||
Publisher | TPUB | TextFrame | P | P | P |
Track Number | TRCK | TextFrame | P | P | P |
Recording Dates | TRDA | TextFrame | P | P | |
Internet Radio Station Name | TRSN | TextFrame | P | P | |
Internet Radio Station Owner | TRSO | TextFrame | P | P | |
Size | TSIZ | TextFrame | P | P | |
Album sort order | TSOA | TextFrame | P | ||
Performer sort order | TSOP | TextFrame | P | ||
Title sort order | TSOT | TextFrame | P | ||
ISRC | TSRC | TextFrame | P | P | P |
Software/Hardware | TSSE | TextFrame | P | P | P |
Set subtitle | TSST | TextFrame | P | ||
User Text Frame | TXXX1 | UserTextFrame | P | P | P |
Year | TYER | TextFrame | P | P | |
Unique File Identifier | UFID | PrivateFrame | P | P | P |
Term Of Use | USER | TermOfUseFrame | P | P | |
Unsynchronized Lyric | USLT | TextWithLanguageFrame | P | P | P |
Commercial Information | WCOM | TextFrame | P | P | P |
Copyright info | WCOP | TextFrame | P | P | P |
Official Audio File web | WOAF | TextFrame | P | P | P |
Official Artist web | WOAR | TextFrame | P | P | P |
Official audio source web | WOAS | TextFrame | P | P | P |
Official Radio Station Web | WORS | TextFrame | P | P | |
Payment | WPAY | TextFrame | P | P | |
Publisher web | WPUB | TextFrame | P | P | P |
User Define Web | WXXX1 | UserTextFrame | P | P | P |
其中比较重要:
TextFrame
PopularimeterFrame
UserTextFrame
TermOfUseFrame
OwnershipFrame
LinkFrame
TextWithLanguageFrame
AttachedPictureFrame 图片,其它的文件类标签帧不感兴趣,直接忽略
大部分都是文本信息,处理上面的几种基本可以了,其它的不处理,直接根据帧大小跳过。
每种类型的处理方法:
AsII码读取字符串:一直读取到0结束,或者到标签帧的结尾。
按编码读取字符串:根据编码不同读取到一个0结束(utf16是两个00结束,注意大端排列和小端排列),或者到标签帧的结尾。
/* 内容
1/文本 如果是W开头的ID,则默认编码AsII,没有前面的这一个字节
1byte 表示编码 0x00 = ISO-8859-1 01 = utf-16LE 02=utf-16BE 03=utf-8 后面的按照编码处理
2、PopularimeterFrame POPM
先用AsII码读取字符串,0 结束,然后读取一个rating,之后是8字节conter
3、UserTextFrame TXXX
1byte表示编码,
然后读取剩下的字串,按编码处理 描述
按编码处理 内容 如果W开头则ASII编码
4、TermOfUseFrame USER
1byte表示编码
3byte的 language 然后读取剩下的字串,按编码处理
5、OwnershipFrame OWNE
1byte表示编码
按AsII读取字符串 price 必须不小于4 位,前3位整数,后面的是小数
8byte 按ASii读取是Date 0-4 年 5-6 月 7-8 日期
剩下的按编码读取字符串 售卖者
6、LINK LinkFrame
4byte 标识
ASII读取URL
ASII读取剩余的数据
7、TextWithLanguageFrame USLT COMM
1byte表示编码
3byte的 language
按编码读取描述
按编码读取内容
8、AttachedPictureFrame APIC 图片
1byte 表示编码
按编码ASII读取 mimiteye
1byte pictureType 图像类型
按编码读取, 描述
读取剩余长度, 数据。
*/
关于编码的处理方式:
文本内容要根据不同的编码来进行读取。UTF16是2字节的结束符为两个byte的0
如果字符串在标签帧的最后,则后面没有0结束符