Chip123 科技應用創新平台

標題: MP3文件格式解析2 [打印本頁]

作者: windflowerz    時間: 2007-4-11 05:00 AM
標題: MP3文件格式解析2
2,      MP3文件格式
( M' Z. v7 f, X% \0 Z4 `5 K7 [! D  I6 I
用一个二进制查看器(比如Ultra-Edit)打开一个MP3文件,就能看到一大堆看似杂乱无序的数据。但只要用心了解就会知道,其实,这一切都是有章可循的。9 e* ]$ Y# X3 x4 V0 k9 j( r

9 _; @  ~: c- b" }* X8 M. M/ bMP3文件是由帧(frame)构成,帧是MP3文件的最小组成单位。每帧都包含帧头,并可以计算帧的长度。根据帧的性质不同,文件主要分为三个部分,ID3v2标签帧,数据帧和ID3v1标签帧。并非每个MP3文件都有ID3v2,但是数据帧和ID3v1帧是必须的。ID3v2在文件头,以字符串“ID3”为标志,包含了演唱者,作曲,专辑等信息,长度不固定,扩展了ID3V1的信息量。ID3v1在文件结尾,以字符串“TAG”为标记,其长度是固定的128个字节,包含了演唱者、歌名、专辑、年份等信息。2 ]6 \/ J& Q/ F/ s& ]# K6 |
' A$ T5 s$ }/ ^& L& t- b5 V
I, ID3V2 8 B& X9 W0 n0 U: t3 ^$ }6 G
; _* k1 M( U" P; j. P' a8 X% R: n
ID3V2到现在一共有四个版本,但流行的播放软件一般只支持第三版,既ID3V2.3。每个ID3V2.3 的标签都一个标签头和若干个标签帧或一个扩展标签头组成。关于曲目的信息如标题、作者等都存放在不同的标签帧中,扩展标签头和标签帧并不是必要的,但每个标签至少要有一个标签帧。标签头和标签帧一起顺序存放在MP3 文件的首部。
( \# N) n$ u: Z8 ~( i. f) B0 X
6 r, Z, ~2 H+ Z$ |, O4 T8 e6 a2 G6 Q标签头
9 V% f/ v: b, D0 {( z$ q
' [# U6 g* q0 d长度为10个字节,位于文件首部,其数据结构如下: ' a% z7 V: v+ X' c
3 z- [9 x  d) U2 E. F
char Header[3]; /* 字符串 "ID3" */8 F) o, V' g1 m$ T" \- _0 q. D

* Q- m3 t1 S# A: N5 e: ochar Ver;       /* 版本号ID3V2.3 就记录3 */
! ?  f( o; ]. s% C& H2 k3 n$ q- ^1 A3 U) B' t
char Revision;  /* 副版本号此版本记录为0 */
& R; ~4 g/ @3 C6 r) G; O# w' E
char Flag;     /* 存放标志的字节,这个版本只定义了三位,很少用到,可以忽略 */
  A0 N$ f  Q1 }7 s$ j9 K- Y# z2 E/ v5 h* H
char Size[4];  /* 标签大小,除了标签头的10 个字节的标签帧的大小 */ 5 I7 v$ l, z6 W9 t9 g2 ^

9 X- x3 \: A; M+ N; |. N, t标签大小为四个字节,但每个字节只用低7位,最高位不使用,�为0,其格式如下:
; h9 O) m+ Y* k0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx 0 Z3 n/ z* Y% B" Y
' w. M, J+ y) l$ ]
计算公式如下: # ~  Q2 ~$ D0 B8 @, S6 i$ c; t, T
  u! ?; G  M" z& }1 d- e4 @
ID3V2_frame_size =  (int)(Size[0] & 0x7F) << 21$ S: v+ \+ N. e0 T, X5 r
                  | (int)(Size[1] & 0x7F) << 14
' S, d- m3 l% V9 Q* c- W! H                  | (int)(Size[2] & 0x7F) << 7
! E5 u8 t3 U; ?- {8 k. C                  | (int)(Size[3] & 0x7F) + 10;
3 C9 {; _$ d4 }% j) n& l9 \" z1 O( M+ ?4 ~& e! D
5 @2 A+ G) |+ }" }3 `
标签帧 - z' Z3 L, C& H0 k$ G) r

+ o$ s+ `- m7 h2 g) v每个标签帧都有一个10字节的帧头和至少一个字节的不固定长度的内容组成。它们是顺序存放在文件中,由各自特定的标签头来标记帧的开始。其帧的结构如下:
7 A3 {1 n4 O( H6 i+ V6 h; c* i# B9 @6 D% w
char FrameID[4];   /*用四个字符标识一个帧,说明其内容 */ & i* d+ K- i6 k& [5 P

& I2 ~8 [$ u6 L; R) @) X, A; _' dchar Size[4];      /* 帧内容的大小,不包括帧头,不得小于1 */ 3 F2 B; i1 X. n" w) D. O8 _$ x
5 w5 X- b# M2 l3 x# _
char Flags[2];     /* 存放标志,只定义了6 位,此处不再说明 */
# |4 Z  B7 G. h. d) S' M2 G+ c3 v  I% H2 `& W
常用帧标识: $ G+ v5 c3 }, R4 S( ]/ o

3 j/ |. V$ H; v% B- b1 @TIT2:标题0 I/ L4 h: {0 j( h
TPE1:作者  o3 s% m- Q% I2 H9 A4 W* J; i) f
TALB:专辑& J7 [2 _/ l" I& Q
TRCK: 音轨,格式:N/M,N表示专辑中第几首,M为专辑中歌曲总数
3 H$ T; q1 A$ \3 HTYER:年份
3 s' w( P9 c3 G: j( ^) _/ MTCON:类型; P( S& h; D& j$ Q! q, P( y; u) p
COMM:备注,格式:“eng\0备注内容”,其中eng表示所使用的语言3 S" q) E8 f* v
帧大小为四个字节所表示的整数大小。
9 e& H, v0 L# c, I# j3 g: q+ R* j
1 R+ D1 r0 z. x( a* Q
II, ID3V1 % B) X# H$ A  O, B' T) q- L

) j& }) y# P- e4 l4 X# p' b其数据结构如下: * t6 U! j/ J7 I5 T2 q+ \  D6 d

) L# R4 \; C# Lchar Header[3];    /* 标签头必须是"TAG"否则认为没有标签 */
- L1 m  I5 N; K) r& ?; g1 E$ l% zchar Title[30];    /* 标题 */6 D3 e- t7 V+ ?+ N$ t
char Artist[30];   /* 作者 */
* n! |1 Y! e* rchar Album[30];    /* 专集 */& h7 t8 u1 \" u, E* D
char Year[4];      /* 出品年代 */! P5 E. ^" u6 ^9 U
char Comment[28]; /* 备注 */2 J4 v9 i/ V7 T, p* h  E: z8 P
char reserve;      /* 保留 */5 E) ?: C# L: \& W
char track;;       /* 音轨 */
4 W1 S$ A; O1 \8 D' b4 x2 vchar Genre;        /* 类型 */ 2 O+ d3 E. i5 s3 |! {* g
: V8 A3 V& b( w8 B! R
其实,关于最后31个字节还存在另外一个版本,就是30个字节的Comment和一个字节的Genre. & V- p5 u  i5 Y( f

* k0 Q' Z1 H; M, x' r# F3 f有了上述的这些信息,我们就可以自己写代码,从MP3文件中抓取信息以及修改文件名了。但是,如果真的想写一个播放软件,还是需要读它的数据帧,并进行解码。




歡迎光臨 Chip123 科技應用創新平台 (http://chip123.com/) Powered by Discuz! X3.2