ID3帧头

时间:2014-10-26 17:12:14

标签: c++ id3

我想尝试自己阅读ID3标签而没有用于教育目的的库。我必须为学校做一个如何做的演示。

首先我读了ID3标题(前10个字节)。有用。现在我尝试在ID3标题之后直接读取几乎所有文件中的第一个Frame Header。所以没有扩展头。帧头也应该是10个字节,对吗?那么我有一个问题。

我检查的所有文件中的Frame Header的结构如下:

+------------+   
-  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;*/

我希望我的问题很明确。我无法上传文件,因为这是一首受版权保护的歌曲,我会因法律问题而陷入困境。

我从source获得了所有信息。

2 个答案:

答案 0 :(得分:2)

您找到的字节是编码字节。来自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.

  

依赖于编码的字符串在帧描述中表示   as 根据编码的文本字符串全文字符串
  根据编码
,如果允许换行。任何空字符串   以$ NULL结尾的类型$ 01可能具有遵循
的Unicode BOM   通过Unicode NULL($ FF FE 00 00或$ FE FF 00 00)。

除结构文档外,您还需要引用frame descriptions document,它将告诉您框架的结构。 TIT2是一个文本框架。 TIT2的帧描述在第4.2节下。文本信息框,它显示应该存在文本编码字节:

  

标题为&#39;文字信息框&#39;,ID:&#34; T000&#34; - &#34; TZZZ&#34;,        排除&#34; TXXX&#34;在4.2.6中描述。

 Text encoding                $xx

 Information                  text string(s) according to encoding

基本上,你需要同时参考这两个文档,因为有些框架有这个字节而有些框架没有,有些框架(如果你要实现它们)确实需要非常特殊的处理。例如,看看APIC框架,它允许将艺术嵌入到标签中。

值得指出的是,编写完整且功能齐全的ID3V2解码器是一项重要任务(我已经在那里)。标准有several versions - 标准的每个版本制作的标签都存在于野外;更不用说加密,压缩和unsynchronisation等选项以及tags made by broken encoders的问题。对于像你这样的项目,我只会实现一些最常见的帧的读取。如果您还要编写标签,请务必逐字写出您尚未实施阅读的任何框架。

除引用的资源外,Wikipedia article on ID3也可能有用。

答案 1 :(得分:0)

来自您的链接页面:

  

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

     

$ 00 ISO-8859-1 [ISO-8859-1]。终止于$ 00。

     

$ 01 UTF-16 [UTF-16]编码带有BOM的Unicode [UNICODE]。所有              同一帧中的字符串应具有相同的字节顺序。              终止于$ 00 00。

     

$ 02 UTF-16BE [UTF-16]编码的Unicode [UNICODE]没有BOM。              终止于$ 00 00。

     

$ 03 UTF-8 [UTF-8]编码的Unicode [UNICODE]。终止于$ 00。

这意味着根据编码类型文本字符串的字符串字段的第一个字节将始终是这些字节之一,并且该字节将选择用于文本的编码。但是你不会从字面上找到编码的名称。

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

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