C#读取MP3文件的专辑图片和ID3V2Tag信息(带代码)、

第二次更新,后面的代码有问题,有些专辑图片读取不到。发现是PNG图片的问题。在读取的过程中调试发现,图片帧前10个字节包含了图片的格式,在有些歌曲写着JPEG的格式,数据却是PNG的。先说下思路。
jpeg图片的开头和结尾是连续的两个字节FF,D8和FF,D9(16进制),十进制是255,216和255,217。
png图片的开头为
十进制数
137 80 78 71 13 10 26 10
十六进制数
89 50 4E 47 0D 0A 1A 0A
结束是00 00 00 00 49 45 4E 44 AE 42 60 82
读取图片就找这两种格式的开头和结尾就行了,一般开头都在第14个字节处开始 不超过30
最后把下面的代码改为 if ((255 == bFrame[i] && 216 == bFrame[i + 1])||(137bFrame[i]80bFrame[i + 1]))
测试结果完美读取,反正我电脑里的歌都可以。
后面的代码是前期写的(不包括读取图片),后来在winform里面测试了下读取图片,把读取图片的部分加上了。 需要的人自己进行整理。:

在写有关音乐播放的程序的时候有时需要解析文件的一些基本信息,例如MP3格式的文件中的 艺术家,专辑,歌曲名,比特率,专辑图片等等
MP3文件是由帧构成,帧是 MP3文件的最小组成单位。根据帧性质的不同,文件大体分为四个部分:ID3v2标签帧、数据帧、APEV2标签帧、ID3v1标签帧,而只有数据帧才是必需的。
  数据帧包含了歌曲的压缩数据。标签帧提供了歌曲的演唱者、歌名、专辑、年份等信息。
  ID3v1 在文件结尾,以字符串“TAG”为标识,其长度是固定的 128 个字节。
  ID3v2 在文件头,以字符串“ID3”为标识,长度不固定,扩展了 ID3V1 的信息量。
  APEV2 是最新出现的一种标签,以字符串“APETAGEX”为标识,长度不固定,位置也不固定,可能在文件末尾也可能在文件头,比较常见的是位于文件尾部, 但在 ID3v1 之前。
  值得一提的是 Lyrics3v2,它是千千静听播放器发明的一种独立帧,位于 ID3v1 之前,APEV2 之后(如果有 APEV2 的话),它专用于内嵌 Lrc 类型的歌词文件。

一、ID3V1

表1:ID3V1结构

名称 字节   说明

Tag   3   ID3V1标识符“TAG”的Ascii码
Title  30  歌曲名
Artist  30  歌手名
Album  30  专辑名
Year   4   日期信息
Comment 28  注释信息,有时为30字节
Reserved 1   =0说明有音轨,下一字节就是音轨;≠0表示注释是30个字节
Track  1   音轨(字节型数值),歌曲在专辑里的序号
Genre  1   歌曲风格(字节型数值)

说明:
  ①如果MP3的注释=30字节,那么就要占用 Reserved 和 Track 两个字节,这要看 Reserved 是否=0,如果=0,那么注释有 28 个字节。如果不是,那么注释有 30 个字节。当注释=30 个字节的时候,那就没有 Track 了。
  ②如果 MP3 文件后面虽然有“TAG”三个字母,但字母后面全是0,那就不是一个合法的 ID3V1 信息,应该认为没有 ID3V1 信息。
  ③ID3V1 的各项信息都是顺序存放,没有任何标识将其分开,一般用 0补足规定的长度。比如歌曲名有 20 个字节,则在歌曲名后要补足 10 个 0,否则将造成信息错误。
  ④歌曲风格共 148 种,用编号表示,表2列出了前 30 种的风格与编号对照,详情可上网查询。

表2:30种歌曲风格与编号对照

编号 风格名称  中译义

00 Blues    布鲁斯
01 ClassicRock 古典摇滚
02 Country   乡村
03 Dance    舞曲
04 Disco    迪斯科
05 Funk     伤感爵士
06 Grunge    垃圾摇滚
07 Hip-Hop   饶舌
08 Jazz     爵士
09 Metal    金属
0A NewAge    前卫
0B Oldies    怀旧
0C Other    其他
0D Pop     流行
0E R&B     摇滚布鲁斯
0F Rap     说唱
10 Reggae    雷盖扭摆舞
11 Rock     摇滚
12 Techno    电子流行乐
13 Industrial  工业
14 Alternative 多变
15 Ska     斯卡
16 DeathMetal  重金属
17 Pranks    恶作剧
18 Soundtrack  电影配音
19 Euro-Techno 神游舞曲
1A Ambient   流行
1B Trip-Hop   迷幻舞曲
1C Vocal    非纯音乐
1D Jazz+Funk  爵士摇滚
1E Fusion    合成音乐

二、ID3V2
  ID3V2 与 ID3V1 的作用差不多,也是记录 mp3 的有关信息,但 ID3V2 的结构比 ID3V1 要复杂得多,而且可以伸缩和扩展。ID3V2 到现在一共有 4 个版本,但流行的播放软件一般只支持第 3 版,既ID3V2.3。由于ID3V1记录在 MP3 文件的末尾,ID3V2 就只好记录在 MP3 文件的首部了。
  每个 ID3V2.3 的标签都一个标签头和若干个标签帧或一个扩展标签头组成。歌曲的信息如标题、作者等都存放在不同的标签帧中,扩展标签头和标签帧并不是必要的,但每个标签至少要有一个标签帧。对于 VB 爱好者来说,你可以把 ID3V2 看作是一个对象,而把标签帧看作是 ID3V2 的一个属性,那么,标签帧的标识符就可以看作是属性名了。

1.D3V2标签头
  一首MP3如果有ID3V2.3的话,那么ID3V2.3的标签头占用文件最前面的10个字节,其数据结构如下:

表3:ID3V2.3标签头结构

名称  字节  说明

Header  3 ID3V2.3标识符"ID3"的Ascii码,否则认为没有ID3V2.3
Ver    1  版本号,=03
Revision 1  副版本号,=00
flag   1  标志字节,一般没意义,=00
Size   4  标签内容长度,高位在前,不包括标签头的10个字节

说明:
  ①Size 字段的计算公式如下(从左至右):
size =字节1的值×&H200000+字节2的值×&H4000+字节3的值×&H80+字节4的值
  ②如果所有标签帧的总长度<标签内容长度,则须用0填满。

2.D3V2标签帧
  标签内容由若干个标签帧组成。每个标签帧都由一个10个字节的帧头和至少 1个字节的不固定长度的帧内容组成,它们顺序存放在文件中。
  每个帧都由帧头和帧内容组成,数据结构如下:

表4:标签帧的结构

名称  字节  说明

FrameID 4    帧标识符的Ascii码,常用标识符的意义见表5
Size   4    帧内容及编码方式的合计长度,高位在前
Flags  2    标志,只使用了6位,详见表6,一般均=0
encode  4    帧内容所用的编码方式。许多帧没有此项
帧内容      至少 1 个字节

说明:
  ①Size的计算同上。
  ②标签帧之间没有特殊的分隔符,要得到一个完整的标签帧内容必须先从帧头中得到帧内容长度。
③encode 有 4 个可能值:
0:表示帧内容字符用 ISO-8859-1 编码;
1:表示帧内容字符用 UTF-16LE 编码;
2:表示帧内容字符用 UTF-16BE 编码;
3:表示帧内容字符用 UTF-8 编码(仅ID3V2.4才支持)
  但经常看到的是"eng"这样的字符形式,它表示帧内容所使用的自然语言为英语。也许 D3V2 标签帧进化到现在,encode 已经用“自然语言”取代了“编码方式”。
  ⑤帧内容均为字符串,常以 00 开头。

表5:标签帧标识符的意义

名称  意义

AENC: 音频加密技术
APIC: 附加描述
COMM: 注释,相当于ID3v1的Comment
COMR: 广告
ENCR: 加密方法注册
ETC0: 事件时间编码
GEOB: 常规压缩对象
GRID: 组识别注册
IPLS: 复杂类别列表
MCDI: 音乐CD标识符
MLLT: MPEG位置查找表格
OWNE: 所有权
PRIV: 私有
PCNT: 播放计数
POPM: 普通仪表
POSS: 位置同步
RBUF: 推荐缓冲区大小
RVAD: 音量调节器
RVRB: 混响
SYLT: 同步歌词或文本
SYTC: 同步节拍编码
TALB: 专辑,相当于ID3v1的Album
TBPM: 每分钟节拍数
TCOM: 作曲家
TCON: 流派(风格),见表2
TCOP: 版权
TDAT: 日期
TDLY: 播放列表返录
TENC: 编码
TEXT: 歌词作者
TFLT: 文件类型
TIME: 时间
TIT1: 内容组描述
TIT2: 标题,相当于ID3v1的Title
TIT3: 副标题
TKEY: 最初关键字
TLAN: 语言
TLEN: 长度
TMED: 媒体类型
TOAL: 原唱片集
TOFN: 原文件名
TOLY: 原歌词作者
TOPE: 原艺术家
TORY: 最初发行年份
TOWM: 文件所有者(许可证者)
TPE1: 艺术家相当于ID3v1的Artist
TPE2: 乐队
TPE3: 指挥者
TPE4: 翻译(记录员、修改员)
TPOS: 作品集部分
TPUB: 发行人
TRCK: 音轨(曲号),相当于ID3v1的Track
TRDA: 录制日期
TRSN: Intenet电台名称
TRSO: Intenet电台所有者
TSIZ: 大小 
TSRC: ISRC(国际的标准记录代码)
TSSE: 编码使用的软件(硬件设置)
TYER: 年代,相当于ID3v1的Year
TXXX: 年度
UFID: 唯一的文件标识符
USER: 使用条款
USLT: 歌词
WCOM: 广告信息
WCOP: 版权信息
WOAF: 官方音频文件网页
WOAR: 官方艺术家网页
WOAS: 官方音频原始资料网页
WORS: 官方互联网无线配置首页
WPAY: 付款
WPUB: 出版商官方网页
WXXX: 用户定义的URL链接

说明:
  ①帧内容是数字的,都用 Ascii 字符表示。
  ②有的 TCON(风格、流派)的帧内容是直接用字符串表示的,如“genre”,而有的则是用编号表示的,如“28 31 32 29”就是用字符串“(12)”表示 12 号风格,我们在解析的时候要注意。
  ③TRCK(音轨)的帧内容格式是:N/M。其中,分母表示专辑中共有 M 首歌曲,分子表示专辑中的第 N 首曲。

表6:标签帧中Flags标志的意义

位址 意义

0  标签保护标志,如设置表示此帧作废
1  文件保护标志,如设置表示此帧作废
2  只读标志,如设置表示此帧不能修改
3  压缩标志,如设置表示1个字节存放2个BCD码表示数字
4  加密标志
5  组标志,如设置表示此帧和其它的某帧是一组

如果你想读取mp3里面的专辑图片的话,就要找到APIC标签,然后计算出标签大小。APIC标签的数据部分也比较特殊,首先在数据的前几个字节里面,并没有图片的数据,而是告诉你这里保存的图片数据是什么格式的,大部分都是jpeg的,因为占地小。

在数据部分前几个字节会出现一个特殊标志 image/jpeg 来标明下面的数据是jpeg格式的,如果是其他格式则为image/png image/bmp,jpeg的格式可能会有jpg peg等格式来表示。也就是image/jpg 也表示是jpeg的。

然后开始读取图片数据,在image/jpeg这个标志后面就保存了图片的数据,不过并不是image/jpeg结束后第一个字节就是图片数据,在这里image/jpeg出现的位置和图片的数据开始的位置都是不固定的,就是在它们前后可能都有一些空字节,所以要判断一下。

我们查询jpeg的图片格式可以知道当连着的两个字节是16进制0xFFD8时,就表示图片的数据开始的位置,所以你要从这里开始读,包括0xFFd8也要读进去,也就是FF是第一个字节,D8是第二个字节,然后往下读,直到读到连续两个字节是0xFFD9,这就表示图片数据读完了,记住也要把这两个结束字符读进去。(这里说了个什么意思,我表示不懂,看别人的代码通常在专辑图片信息帧的字节数组中,出现255 和216这两个连续的数字,就代表开始)

public static string[] ReadMp3(string path){int mp3TagID = 0;string[] tags = new string[6];FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);byte[] buffer = new byte[10];// fs.Read(buffer, 0, 128);string mp3ID = "";fs.Seek(0, SeekOrigin.Begin);fs.Read(buffer, 0, 10);int size = (buffer[6] & 0x7F) * 0x200000 + (buffer[7] & 0x7F) * 0x400 + (buffer[8] & 0x7F) * 0x80 + (buffer[9] & 0x7F);//int size = (buffer[6] & 0x7F) * 0X200000 * (buffer[7] & 0x7f) * 0x400 + (buffer[8] & 0x7F) * 0x80 + (buffer[9]);mp3ID = Encoding.Default.GetString(buffer, 0, 3);if (mp3ID.Equals("ID3", StringComparison.OrdinalIgnoreCase)){mp3TagID = 1;//如果有扩展标签头就跨过 10个字节if ((buffer[5] & 0x40) == 0x40){fs.Seek(10, SeekOrigin.Current);size -= 10;}tags = ReadFrame(fs, size);}return tags;}public static string[] ReadFrame(FileStream fs, int size){string[] ID3V2 = new string[6];byte[] buffer = new byte[10];while (size > 0){//fs.Read(buffer, 0, 1);//if (buffer[0] == 0)//{//    size--;//    continue;//}//fs.Seek(-1, SeekOrigin.Current);//size++;//读取标签帧头的10个字节fs.Read(buffer, 0, 10);size -= 10;//得到标签帧IDstring FramID = Encoding.Default.GetString(buffer, 0, 4);//计算标签帧大小,第一个字节代表帧的编码方式int frmSize = 0;frmSize = buffer[4] * 0x1000000 + buffer[5] * 0x10000 + buffer[6] * 0x100 + buffer[7];if (frmSize == 0){//就说明真的没有信息了break;}//bFrame 用来保存帧的信息byte[] bFrame = new byte[frmSize];fs.Read(bFrame, 0, frmSize);size -= frmSize;string str = GetFrameInfoByEcoding(bFrame, bFrame[0], frmSize - 1);if (FramID.CompareTo("TIT2") == 0){ID3V2[0] = "TIT2" + str;}else if (FramID.CompareTo("TPE1") == 0){ID3V2[1] = "TPE1" + str;}else if (FramID.CompareTo("TALB") == 0){ID3V2[2] = "TALB" + str;}else if (FramID.CompareTo("TIME") == 0){ID3V2[3] = "TYER" + str;}else if (FramID.CompareTo("COMM") == 0){ID3V2[4] = "COMM" + str;}else if (FramID.CompareTo("APIC") == 0){MessageBox.Show("有图片信息");int i = 0;while (true){if (255 == bFrame[i] && 216 == bFrame[i + 1]){//在break;}i++;}byte[] imge = new byte[frmSize - i];fs.Seek(-frmSize + i, SeekOrigin.Current);fs.Read(imge, 0,imge.Length);MemoryStream ms = new MemoryStream(imge);Image img = Image.FromStream(ms);FileStream save = new FileStream(@"C:UsersPC-DELLDesktop22.jpeg", FileMode.Create);img.Save(save, System.Drawing.Imaging.ImageFormat.Jpeg);MessageBox.Show("成功");//}}}return ID3V2;}public static string GetFrameInfoByEcoding(byte[] b, byte conde, int length){string str = "";switch (conde){case 0:str = Encoding.GetEncoding("ISO-8859-1").GetString(b, 1, length);break;case 1:str = Encoding.GetEncoding("UTF-16LE").GetString(b, 1, length);break;case 2:str = Encoding.GetEncoding("UTF-16BE").GetString(b, 1, length);break;case 3:str = Encoding.UTF8.GetString(b, 1, length);break;}return str;}

C#读取MP3文件的专辑图片和ID3V2Tag信息(带代码)相关推荐

  1. 用 Windows Media Player 在线匹配歌曲文件的专辑图片,音乐信息等并写入歌曲文件

    如何用 Windows Media Player 在线匹配歌曲文件的专辑图片,音乐信息等并写入歌曲文件 相信大家都遇到过这样一个问题,自己下载的歌曲文件名和歌曲内部的信息(标题.艺术家.唱片集等)杂乱 ...

  2. Html读取本地文件夹下图片并显示的示例代码

    一 目的 在Html上选择本地文件夹,自动读取文件夹及子文件夹下的所有图片并显示在页面. 技术分析: 存在问题 Html中file标签获取到的路径时相对的. Html中Img指定源时需要的是绝对路径. ...

  3. 读取MP3文件内的ID3V2专辑图片并显示

    这里说的ID3V2一般指的2.3版本,MP3文件后128字节是ID3V1信息,ID3V1大小固定所以信息含量较少,由于项目需要,要读取专辑图片并显示,我找到ID3V2的格式说明,也不知准备不准确,但我 ...

  4. C语言读取mp3文件的信息

    MP3文件的ID3V1信息与ID3V2信息结构的分析 --吴俊涛2005/05/05 E-mail:bo_tao@126.com QQ:29248671 主 页:http://wjt276.home4 ...

  5. 读取mp3文件音量_如何规范化或更改MP3文件的音量

    读取mp3文件音量 Have you ever been listening to MP3 music files that were really quiet while others were r ...

  6. java读取mp3文件信息_用JAVA读取MP3文件的标签信息

    突然看到网上有人在用JavaScript来读取MP3中ID3信息.详细请看! 我也在网上搜索了用Flex写的实现同样的功能的.详细请看! 但是我比较熟悉Java.所以也在网上搜索到了用Java实现的读 ...

  7. 读取MP3文件的ID3v1信息

    前段时间,在局域网里面做一个小网站,其中有板块是涉及音乐的在线播放.考虑到以后维护的方便,决定把mp3文件都按专辑分不同的目录存放.然后使用一个程序监控存放mp3的目录,把每个mp3文件的信息都存入数 ...

  8. Silverlight读取Zip文件中的图片与视频

    置顶声明:本文原创版权归 博客园 Ringgo.Yao 所有,如有转载,请按如下方式详细标明原文作者及出处,以示尊重!! 原创作者:Ringgo.Yao 原文出处:Silverlight读取Zip文件 ...

  9. java读取mp3文件

    JMF实际上是Java的一个类包.JMF 2.1.1技术提供了先进的媒体处理能力,从而扩展了Java平台的功能.这些功能包括:媒体捕获.压缩.流转.回放,以及对各种主要媒体形式和编码的支 持,如M-J ...

  10. java中读取mp3文件_java读取mp3文件

    JMF实际上是Java的一个类包.JMF 2.1.1技术提供了先进的媒体处理能力,从而扩展了Java平台的功能.这些功能包括:媒体捕获.压缩.流转.回放,以及对各种主要媒体形式和编码的支 持,如M-J ...

最新文章

  1. BrnShop开源网上商城第二讲:ASP.NET MVC框架
  2. iOS 两种易混淆的存储路径
  3. eclipse报错Project facet Cloud Foundry Standalone Application version 1.0 is not supported.
  4. linux7.0下mysql_CentOS 7.0下使用yum安装MySQL
  5. 高级版本 【多后台】
  6. 系统集成Nacos和Feign
  7. Docker 命令总结
  8. 微信小程序码合成图片
  9. Compass的模块介绍
  10. qiankun加载react子应用报错[import-html-entry] error occurs while executing normal script
  11. 10年后,从新开始...
  12. SQL查询某个时间段购买过商品的所有用户
  13. 怎么炒原油期货外盘?原油期货外盘入门知识有哪些?
  14. 盘点和反思在微信的阴影下艰难求生的移动端IM应用
  15. 500年前的北大寺物证
  16. 汽车芯片的可靠性为其他行业打开了大门
  17. DELPHI bpl使用
  18. HBase 在滴滴出行的应用场景和最佳实践
  19. 网络授时 linux,关于“网络授时域名”全面试运行测试的公告
  20. PIC单片机的AD数据传输和上位机C#串口界面实时显示

热门文章

  1. c 实现走迷宫流程图_C语言实现一个走迷宫小游戏(深度优先算法)
  2. (68)-- 爬取糗百信息
  3. 【长期维护】程序员锻炼法则
  4. ps cs6调油画效果教程
  5. xp证书错误补丁_爱思助手 IPA 签名功能常见问题汇总,安卓软件修复南瓜影视无法播放问题,新增皮皮虾xp版,内置皮皮虾伴侣!...
  6. Kalman滤波器参数分析
  7. excel公式编辑器_EXCEL从文件夹中提取符合条件的记录,其实很简单
  8. 深入理解GatewayWorker框架
  9. 考虫四级词汇思维导图
  10. state_dict详解--存放训练过程中需要学习的权重和偏执系数