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/ b
MP3文件是由帧(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: o
char Ver; /* 版本号ID3V2.3 就记录3 */
! ? f( o; ]. s% C& H
2 k3 n$ q- ^1 A3 U) B' t
char Revision; /* 副版本号此版本记录为0 */
& R; ~4 g/ @3 C
6 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* k
0xxxxxxx 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+ V
6 h; c* i# B9 @6 D% w
char FrameID[4]; /*用四个字符标识一个帧,说明其内容 */
& i* d+ K- i6 k& [5 P
& I2 ~8 [$ u6 L; R) @) X, A; _' d
char 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+ c
3 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 H
TYER:年份
3 s' w( P9 c3 G: j( ^) _/ M
TCON:类型
; 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# L
char Header[3]; /* 标签头必须是"TAG"否则认为没有标签 */
- L1 m I5 N; K) r& ?; g1 E$ l% z
char Title[30]; /* 标题 */
6 D3 e- t7 V+ ?+ N$ t
char Artist[30]; /* 作者 */
* n! |1 Y! e* r
char 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 v
char 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