MP3文件的ID3V1信息与ID3V2信息结构的分析

2024-01-29 09:48

本文主要是介绍MP3文件的ID3V1信息与ID3V2信息结构的分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

MP3文件的ID3V1信息与ID3V2信息结构的分析

 

——吴俊涛2005/05/05

E-mail:bo_tao@126.com  QQ:29248671

主 页:http://wjt276.home4u.china.com(有源代码)

 本人是一位编程爱好者,想通过VB。NET编写一个可以读取MP3文件的信息的不程序,可以不知道文件结构,呀我在网上找了好长时间(好几个月)都没有找到VB的。后来看到一个VC的,还附有结构分析,太好了,动手了。

一:“ID3v1”信息的分析

MP3的基本歌曲信息存在了MP3文件的最后128个字节里,其结构是:
Public Structure ID3v1Info

Dim ID3v1TAG As String 'TAG三个字母,ID3V1的标识

Dim Title As String '存储标题信息,30个字节

Dim Artist As String '存储歌手信息,30个字节

Dim Album As String '存储专辑信息,30个字节

Dim Year As String '存储年代信息,4个字节

Dim Comments As String '存储备注信息,28个字节(有时为30字节)

Dim Genre As String '存储音乐风格信息,保留位,1个字节 

Dim Reserved As String '保留位,1个字节(有时没有意思

Dim Track As String '音轨(曲号)保留位,1个字节(有时没有)

End Structure

ID3V1信息存储结构如下(如图1):

图 1 一个MP3文件的ID3v1信息


1-3 TAG

4-33 歌曲名(Take Me To Your Heart )

34-63 歌手名(Michael Learns to Rock)

64-93 专辑名(Take Me to Your Heart)

94-97 年(2004)

98-125 备注 (http://www.uptu.com)

126 保留位,这时为0,则说明有音轨,下一位就是音轨

127 保留位,为音轨(第几首歌)(OC)

128 保留位 (风格)(66)

 

而在Winamp的ID3v1歌曲信息里(如图1),我们看到的是他都包括:
Title(歌曲名)
Artist(歌手名)
Album(专辑名)
Year(年)
Comment(备注)
Genre(歌曲风格)注,见下面有详细的列表
Track#(歌曲在专辑里的顺序,就是我们经常说的“第几首”)

  Title,Artist,Album,Year,Comment我们都是可以在那个128个字节里得到,Genre和Track哪里去了呢? 有的朋友都重视了那128字节信息的前125个信息了,而这两个信息是却放在了最后的126-128字节里。其实,127那处就是Track信息,而128处就是Genre信息。他们的存储方式都不是字符,我们提取他们的时候需要注意,他们都是数字。比如,就如我们看到的这首歌的126处是0x0D,那么很显然,他就是13。也就是第13号歌曲风格,Pop流行( 下面列表)。

这时,你也该猜到了,127和128都是有意义的,自然126处也是有其意义!ID3v1信息的Comment(注释)一共占用28个字节。这个说法并不是完全的正确。准确的说应该是正确了一部分。有的时候注释也可以超过这个数字的。ID3v1要求注释最多可以到30个字节。那么有的读者会问“MP3的ID3v1就是得有130个字节的信息了嘛?”不是,当然不是。ID3v1是固定的128个字节,这个你不用担心。其实ID3v1是这样安排的:如果MP3的注释是大于28个字节的,那么就要借用126-127两个字节。所以ID3v1的注释部分可能是28个字节也可能是30个字节。那么,怎么区分到底是28个字节还是30个字节呢?很简单,126处就是管这个的,我们只要看看126处是不是0x00,如果是0x00那么注释就有28个字节。如果不等于0x00,那么就是说注释是30个字节。同时别忘了,由于第127字节存储了Track信息,那么如果注释是30个字节的时候,这首歌的ID3v1里的那个127处的信息自然就不是Track信息了。Track自然就是没有地方存了,所以127处变的没有Track意义了,它只是Comment的一部分了。在你决定制作读取ID3v1的程序的时候,请特别注意一下。

我们最终知道了126处是ID3v1信息的注释部分到底是28个字节还是30个字节的标志位。127处是音轨信息(Track),而Reserved3则是歌曲风格(Genre)。现在我们重新再写一次结构

原理2:MP3文件有没有ID3v1信息的错误理解
  那就是到底什么能叫做“MP3文件没有ID3v1信息”。检测的方法是先提取指定的MP3文件的最后128字节信息,然后确定这128个字节的前3个字节是“TAG”。很多朋友都会同意这个方法没有问题的。可是,实际上问题并不是那么简单。

  Winamp或者其他的MP3播放相关的软件都有MP3信息的写入和读取的功能,然而这些写入ID3v1的软件都会不自觉的当你一打开这个MP3文件就会给它加上这128个字节的信息。也就是说当我们用这种软件打开MP3文件的时候,这些软件就会自动的在这个MP3文件尾端添加了一个128字节的ID3v1结构,而且还是以“TAG”开头!(如图3)。那么很显然,光靠检测那“TAG”三个字节的信息,还是不能完全确定MP3到底有没有ID3v1信息的。我们还要确定这“TAG”后的125字节是不是正确的信息。一般情况下,这类软件产生的ID3v1结构都是由一堆00,或者一堆空格组成的,所以我们要判断一下是不是ID3v1的信息是一堆00或者一堆空格。如果是,那么MP3文件虽然有这“TAG”三个字母,却仍然不是一个合法的ID3v1信息。MP3文件仍然应该认为没有ID3v1信息。我觉得这个东西有必要特别提醒大家注意。

二:ID3v2信息的提取
MP3文件的“ID3v1信息”。这个信息结构提取起来非常容易,写入到文件也不是什么难事。但是它的信息安排和可扩展性却非常之差(只能128个字节)。就如你所知,MP3文件还有另外的一个信息结构,这个结构具有更好的可扩展性,而且存储的容量也不受限制(也就是总长度不固定)。这个信息就是ID3v2信息(相对ID3v1而言)。由于ID3v1信息存储在了文件的最后128个字节里,那么ID3v2就不得不放弃选择存储在文件的末尾了,于是它被存储在了文件的起始位置。

ID3v2信息的存储和读取远远要比ID3v1信息复杂的多。这是因为ID3v2信息不再固定,而且由于这段信息存储在了文件的首端,所以重新写入的时候也远比ID3v1麻烦的多。

我用尽可能清楚而且简练的话,给大家讲一下ID3v2信息的读取方法。ID3v2到现在一共有4个版本,不过比较流行的MP3播放软件一般只支持第3版,即ID3v2.3。我们要读取的就是ID3v2.3信息。ID3v2信息包括两个部分,一个部分是标头信息,另一个部分是标体信息。其中标头信息占固定的十个字节,

 每个ID3V2的标签部一个标签头和若干个标签帧或一个扩展标签组成关于曲目的信息如标题、作者等都放在在不同的标签帧中,扩展标签头和标签帧关不是必要的,但每个标签至少要有一个标签头和标签帧一直顺序存放在MP3文件首部。

它的结构如下:

(一)、标签头

Private Structure ID3v2Header

  Dim Header() As Byte'ID3v2标识位,应该是“ID3”三个字母为对

  Dim Ver As Byte'版本号ID3V2就记录3

  Dim Revision As Byte’副版本号此版本记录为0

  Dim Flag As Byte‘存放标志的字节,这个版本只定义了三位,稍后详细解说

  Dim Size() As Byte’标签大小,不包括标签头的10个字节(但是有的文章说包括)我是通过核实 才这样说的,看看源代码就知道了

End Structure

这十个字节的信息作用:

1、Header(2),一般为“ID3”,否则没有ID3V2信息

2、Flag 标志字节:标志字节一般为0,字义为abc00000

a-表示是否使用Unsynchronisation

b-表示是否有扩展头部,一般没有(WINAMP也没有)所以一般不设置

 c-表示是否为测试标签(99.9%的标签都不是测试用的,所以一般不设置)

3、Sixe(3) 标签大小:一共四个字节,但每个字节只使用7位,最高位不使用恒为0,所以格式如下:

  0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx

 计算大小时要将0去掉,得到一个28位的二进制数,就是标签的大,计算公式如下

   ①、VC的:ID3size =(Size[0]&0x7F)*0x200000 +(Size[1]&0x7F)*0x400 +(Size[2]&0x7F)*0x80 +(Size[3]&0x7F);

②、VB的:ID3size =Size(0) * (2 ^ 21) + Size(1) * (2 ^ 14) + Size(2) * (2 ^ 7) + Size(3) * (2 ^ 0)

VB的我已在类中声明了一个函数ByteToLong,很方便,直调用就OK了。

通过解析这段标头信息我们可以知道一个MP3文件是不是有ID3v2信息,如果有我们就知道了ID3v2的数据体的总长度。

(二)、标签帧

  接下来我们要解析ID3v2的 标签帧,别担心,虽然复杂,但也没你想象的那么的痛苦。ID3v2的数据体又分为很多相同的数据结构。

  每个标签帧都有一个10个字节的帧头和至少一个字节的不固定长度的内容组成,它们也是顺序存放在文件中,和标签头和其他的标签帧也没有特殊的字符分隔,得到一个完整的帧的内容只有从帧头中的到内容大小 后才能读出,读取时要注意大小,不要将其它的帧的内容或帧头读入。帧的定义如下:

Private Structure ID3v2Frame

  Dim FrameID As String‘用4个字符标识一个帧,说明其内容,常用的标识对照表见附表

  Dim Size() As Byte’4个字节 帧内容的大小,不包括帧头,不得小于1,计算时也用上面的公式计算

  Dim Flags() As Byte’2个字节 存放标志,只定义了6位,稍后详细解说

End Structure 

 1、FrameID 帧标:用四个字符标识一个帧的内容含义,常用的对照如下:

TEXT: 歌词作者 TENC: 编码
WXXX: URL链接(URL) TCOP: 版权(Copyright)
TOPE: 原艺术家 TCOM: 作曲家
TDAT: 日期 TPE3: 指挥者
TPE2: 乐队 TPE1: 艺术家相当于ID3v1的Artist
TPE4: 翻译(记录员、修改员) TYER: 年代相当于ID3v1的Year
USLT: 歌词 TALB: 专辑相当于ID3v1的Album
TIT1: 内容组描述 TIT2: 标题相当于ID3v1的Title
TIT3: 副标题 TCON: 流派(风格)相当于ID3v1的Genre见下表
TBPM: 每分钟节拍数 COMM: 注释相当于ID3v1的Comment
TDLY: 播放列表返录 TRCK: 音轨(曲号)相当于ID3v1的Track
TFLT: 文件类型 TIME: 时间 
TKEY: 最初关键字 TLAN: 语言
TLEN: 长度 TMED: 媒体类型
TOAL: 原唱片集 TOFN: 原文件名
TOLY: 原歌词作者 TORY: 最初发行年份
TOWM: 文件所有者(许可证者) TPOS: 作品集部分
TPUB: 发行人 TRDA: 录制日期
TRSN: Intenet电台名称 TRSO: Intenet电台所有者
TSIZ: 大小   TSRC: ISRC(国际的标准记录代码)
TSSE: 编码使用的软件(硬件设置) UFID: 唯一的文件标识符
AENC: 音频加密技术    

   其中要说明的是这个FrameID,在ID3v1里我们是根据每一个信息所占用的固定的字节数和位置来判断他是哪个信息的。而ID3v2为了提供更好的可扩展性,把这些信息变得“动态”化了,因为长度并不是预先设定好的,而是在size[4]里存储的。这样长度就可以不再固定了。我觉得在我们自己定义文件的时候ID3v2和ID3v1也是值得我们考虑的一个方面。如果结构很小而且存储的量也不大,我们可以采用ID3v1的信息存储方式。如果存储的信息不固定,而且要求有很好的可扩展性,那么ID3v2当然成了首选。实际上,现在很多格式的文件的存储方式都是ID3v2的存储方式非常接近的。

2、Size() 帧内容大小:不再是总标头那样的每个字节只取后7位了,它是按照正常的8位存储的。得到帧内容的大小的格式如下 :

xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx

 计算成整形,公式如下:

   ①、VC的: FSize = Size[0]*0x100000000 + Size[1]*0x10000 + Size[2]*0x100 + Size[3];

②、VB的:ID3size =Size(0) * (2 ^ 21) + Size(1) * (2 ^ 14) + Size(2) * (2 ^ 7) + Size(3) * (2 ^ 0)

VB的我已在类中声明了一个函数ByteToLong,很方便,直调用就OK了。

3、Flags() 标志:只定义了6位,另外10位为0 但大部分的情况下16位都为0就可以了,格式如下:

 a-标签保护标志,设置时认为此帧作废

b-文件保护标志,设置时认为此帧作废

c-只读标志,设置时认为此帧不能修改(目前好像没有看到过)

i-压缩标志,设置时一个字节存放两个BCD码表示数字

j-加密标志(好像不太实用)

k-组标志,设置时说明此帧和其它的某帧是一组。


  详细你可能到www.ID3.org去了解一下。

4、帧内容(数据体)


  标头后面就是数据体了,我们提取数据体的前十个字节,我们知道了这个数据结构存储的FrameID是TIT2,查上面的表,说明这个数据结构存储的是歌曲名信息。大小是00 00 00 17,换成十进制就是23。也就是歌曲名是这个子标头后的23个字节的信息。也就是:“Take Me To Your Heart ”。接下来的一个数据结构的FrameID是TPE1,说明是歌手名,而大小是00 00 00 17,说明这个数据体有23个字节,也就是:“Michael Learns to Rock”。依次类推。这里需要大家知道的是一个汉字占用两个字节。在写入时,要计算字节数,我已编写了一个函数ByteSize,大家可以直接使用了。

  还有特别要提醒大家的是,ID3v2的注释信息(FrameID是COMM)的数据体的前四(但经我测试为前5个字节)个字节,并不是注释内容,而是注释使用的自然语言,这个例子里我们看到是:”eng/0”,我们要跳过这四个字节的信息进行解析。此外ID3v2的歌曲类型Genre(FrameID是TCON)的存储也不太一样的。由于很多MP3播放器的写入方式并不是非常一致,而在Genre写入的也不一致。比如,这首歌的ID3v2的Genre是Classic Rock,其实有的还会写入成:(1),或者1,还有(1)Classic Rock,所以格式五花八门,我们要在解析的时候注意一下。还有,值得一提的是winamp在保存和读取帧内容的时候会在内容前面加个'/0',并把这个字节计算在帧内容的大小中。所以前面提到的歌手名“Michael Learns to Rock”本身应该22个字节,可是却占了23个字节。

源代码已发布,你可以到本站点的主页去下载,如有什么问题,请一定联系我呀,不要客气轼呀

您如有什么问题,可以发E-MAIL给我,我们一起来讨论,主页里有源代码和实例,有兴趣的朋友不访去看看 http://wjt276.home4u.china.com

作者:吴俊涛   时间:2005/05/05    

这篇关于MP3文件的ID3V1信息与ID3V2信息结构的分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/656520

相关文章

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

【北交大信息所AI-Max2】使用方法

BJTU信息所集群AI_MAX2使用方法 使用的前提是预约到相应的算力卡,拥有登录权限的账号密码,一般为导师组共用一个。 有浏览器、ssh工具就可以。 1.新建集群Terminal 浏览器登陆10.126.62.75 (如果是1集群把75改成66) 交互式开发 执行器选Terminal 密码随便设一个(需记住) 工作空间:私有数据、全部文件 加速器选GeForce_RTX_2080_Ti

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

MOLE 2.5 分析分子通道和孔隙

软件介绍 生物大分子通道和孔隙在生物学中发挥着重要作用,例如在分子识别和酶底物特异性方面。 我们介绍了一种名为 MOLE 2.5 的高级软件工具,该工具旨在分析分子通道和孔隙。 与其他可用软件工具的基准测试表明,MOLE 2.5 相比更快、更强大、功能更丰富。作为一项新功能,MOLE 2.5 可以估算已识别通道的物理化学性质。 软件下载 https://pan.quark.cn/s/57

衡石分析平台使用手册-单机安装及启动

单机安装及启动​ 本文讲述如何在单机环境下进行 HENGSHI SENSE 安装的操作过程。 在安装前请确认网络环境,如果是隔离环境,无法连接互联网时,请先按照 离线环境安装依赖的指导进行依赖包的安装,然后按照本文的指导继续操作。如果网络环境可以连接互联网,请直接按照本文的指导进行安装。 准备工作​ 请参考安装环境文档准备安装环境。 配置用户与安装目录。 在操作前请检查您是否有 sud

线性因子模型 - 独立分量分析(ICA)篇

序言 线性因子模型是数据分析与机器学习中的一类重要模型,它们通过引入潜变量( latent variables \text{latent variables} latent variables)来更好地表征数据。其中,独立分量分析( ICA \text{ICA} ICA)作为线性因子模型的一种,以其独特的视角和广泛的应用领域而备受关注。 ICA \text{ICA} ICA旨在将观察到的复杂信号

【软考】希尔排序算法分析

目录 1. c代码2. 运行截图3. 运行解析 1. c代码 #include <stdio.h>#include <stdlib.h> void shellSort(int data[], int n){// 划分的数组,例如8个数则为[4, 2, 1]int *delta;int k;// i控制delta的轮次int i;// 临时变量,换值int temp;in

三相直流无刷电机(BLDC)控制算法实现:BLDC有感启动算法思路分析

一枚从事路径规划算法、运动控制算法、BLDC/FOC电机控制算法、工控、物联网工程师,爱吃土豆。如有需要技术交流或者需要方案帮助、需求:以下为联系方式—V 方案1:通过霍尔传感器IO中断触发换相 1.1 整体执行思路 霍尔传感器U、V、W三相通过IO+EXIT中断的方式进行霍尔传感器数据的读取。将IO口配置为上升沿+下降沿中断触发的方式。当霍尔传感器信号发生发生信号的变化就会触发中断在中断

kubelet组件的启动流程源码分析

概述 摘要: 本文将总结kubelet的作用以及原理,在有一定基础认识的前提下,通过阅读kubelet源码,对kubelet组件的启动流程进行分析。 正文 kubelet的作用 这里对kubelet的作用做一个简单总结。 节点管理 节点的注册 节点状态更新 容器管理(pod生命周期管理) 监听apiserver的容器事件 容器的创建、删除(CRI) 容器的网络的创建与删除