ID3 Frame Header

ID3 Frame Header

本文关键字:Header Frame ID3      更新时间:2023-10-16

我想尝试在没有库的情况下独自阅读ID3标签,以达到教育目的。我必须为学校做一个关于如何做的演示

首先,我读取ID3标头(前10个字节)。它有效。现在我试着读取第一个帧头,它几乎在我所有的文件中,紧跟在ID3头之后。因此没有扩展的标头。帧头也应该是10个字节,对吧?那我就有问题了。

我检查的所有文件中的帧头结构如下:

+------------+   
-  Frame ID  -   
+------------+   
- Frame Size -   
+------------+   
- Frame Flags-   
+------------+   

在那之后,值应该随之而来,对吧?如果id是TALB(专辑),则应该是专辑名称。该值应该是帧大小值的大小。然而,我的所有文件在相册名称之前都有一个0x03,实际上在所有帧之前,并且帧大小也高出1。示例:

帧ID=TIT2
帧大小=13(0x03为12+1)
标志
值=(0x03字符)3门下降

这个值是什么意思?我读了一点关于文本编码的文章,这个值应该是:

$03 UTF-8〔UTF-8〕编码的Unicode〔Unicode〕。以00美元终止。

但我没有看到任何部分的文本编码值被放置在。

这是我的代码(简化)读取帧头的值:

//Method from a FrameHeader Class, takes 10 bytes as parameter
void setHeader( char* value ){
    int i = 0;
    for(; i < 4; i++ ){
        identifier += value[i];
    }
    for(; i < 8; i++ ){
        size = size << 8 | static_cast<unsigned char>(value[i]);
    }
    for(; i < 10; i++ ){
        flags += value[i];
    }
}
memblock = new char[10];
iStream.read( memblock, 10 );
FrameHeader frameHeader;
frameHeader.setHeader( memblock );
memblock = new char[ frameHeader.getSize() ];
iStream.read( memblock, frameHeader.getSize() );
cout << "Frame Indentifier : " << frameHeader.getIdentifier() << endl;
cout << "Frame Size : " << frameHeader.getSize() << endl;
cout << "Frame value : " << memblock << endl;*/

我希望我的问题是清楚的。我不能上传文件,因为这是一首受版权保护的歌曲,我这样做会触犯法律

我从这个来源得到了所有的信息。

您找到的字节是一个编码字节。来自id3v2.4.0-structure.txt:

允许不同类型文本编码的框架包含一个文本
编码描述字节。可能的编码:

 $00   ISO-8859-1 [ISO-8859-1]. Terminated with $00.
 $01   UTF-16 [UTF-16] encoded Unicode [UNICODE] with BOM. All
       strings in the same frame SHALL have the same byteorder.
       Terminated with $00 00.
 $02   UTF-16BE [UTF-16] encoded Unicode [UNICODE] without BOM.
       Terminated with $00 00.
 $03   UTF-8 [UTF-8] encoded Unicode [UNICODE]. Terminated with $00.

和:

依赖于编码的字符串在帧描述中表示
根据编码为文本字符串,或全文字符串
如果允许换行,则根据编码

的任何空字符串以NULL结尾的$01类型后面可能有Unicode BOM
通过Unicode NULL($FF FE 00 00或$FE FF 00 00)。

除了结构文档外,您还需要参考框架描述文档,该文档将告诉您框架的结构。TIT2是一个文本框。TIT2的框架描述见第4.2节。文本信息帧,它表明应该存在一个文本编码字节:

"文本信息框"的标题,ID:"T000"-"TZZZ",不包括4.2.6中所述的"TXXX"。

 Text encoding                $xx
 Information                  text string(s) according to encoding

从本质上讲,您需要将这两个文档一起引用,因为有些框架有这个字节,有些没有,而有些框架(如果要实现它们)确实需要非常特殊的处理。例如,看看APIC框架,它允许将艺术嵌入标签中。

可能值得指出的是,编写一个完整的、功能完整的ID3V2解码器是一项主要任务(我已经去过那里)。该标准有几个版本,并且每个版本的标准do都存在于野外;更不用说加密、压缩和不同步等选项,以及编码器损坏导致的标签问题。对于像你这样的项目,我只想实现对一些最常见框架的阅读。如果你也在写标签,只要注意逐字逐句地写出你没有实现阅读的任何框架。

除了引用的资源外,维基百科关于ID3的文章可能也很有用。

从您的链接页面:

允许不同类型文本编码的帧包含一个文本编码描述字节。可能的编码:

00美元ISO-8859-1[ISO-8859-1]。以00美元终止。

$01 UTF-16[UTF16]编码的Unicode[UNCODE]与BOM。全部的同一帧中的字符串应具有相同的字节顺序。以00美元终止。

$02 UTF-16BE[UTF-16]编码的Unicode[UNCODE],无BOM。以00美元终止。

$03 UTF-8〔UTF-8〕编码的Unicode〔Unicode〕。以00美元终止。

这意味着,根据编码,文本字符串类型的字符串字段的第一个字节将始终是这些字节中的一个,该字节将选择用于文本的编码。但是你不会发现编码的名字是字面意思。

请注意,有文本字符串类型的aso字段缺少该字节,并假定为ISO-8859-1。

在您的文件中,0x03表示以下文本是UTF-8编码的。