Chip123 科技應用創新平台

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

作者: windflowerz    時間: 2007-4-11 05:00 AM
標題: MP3文件格式解析2
2,      MP3文件格式 / e1 J2 H/ `4 I' z9 _" `
8 R8 h' i: _& n6 e5 c# n; i
用一个二进制查看器(比如Ultra-Edit)打开一个MP3文件,就能看到一大堆看似杂乱无序的数据。但只要用心了解就会知道,其实,这一切都是有章可循的。
# ^: b6 U( \( ?3 K
% A3 X0 j" O7 c; _" T& g5 CMP3文件是由帧(frame)构成,帧是MP3文件的最小组成单位。每帧都包含帧头,并可以计算帧的长度。根据帧的性质不同,文件主要分为三个部分,ID3v2标签帧,数据帧和ID3v1标签帧。并非每个MP3文件都有ID3v2,但是数据帧和ID3v1帧是必须的。ID3v2在文件头,以字符串“ID3”为标志,包含了演唱者,作曲,专辑等信息,长度不固定,扩展了ID3V1的信息量。ID3v1在文件结尾,以字符串“TAG”为标记,其长度是固定的128个字节,包含了演唱者、歌名、专辑、年份等信息。3 @" a7 S) C2 A; O" }

; a+ D- v" q  MI, ID3V2
. F& A, G0 j9 Y0 N# P5 l: B8 }+ n( r, z' D2 O2 B/ W
ID3V2到现在一共有四个版本,但流行的播放软件一般只支持第三版,既ID3V2.3。每个ID3V2.3 的标签都一个标签头和若干个标签帧或一个扩展标签头组成。关于曲目的信息如标题、作者等都存放在不同的标签帧中,扩展标签头和标签帧并不是必要的,但每个标签至少要有一个标签帧。标签头和标签帧一起顺序存放在MP3 文件的首部。
; y# {$ z0 F2 s9 c& h$ K) w. \4 f/ K3 I. H
标签头
% h3 h6 E  f* ~! R8 d/ l: U* n1 V' A6 b2 H5 F2 y- I8 e
长度为10个字节,位于文件首部,其数据结构如下: - k' H# J6 \  w5 c1 P- l1 g$ v

" s6 ]1 }! J# g+ W# g& Dchar Header[3]; /* 字符串 "ID3" */
: D% T- ^* C1 ]7 P+ w: _# L* ?' A' J% n0 z) f3 Y) i
char Ver;       /* 版本号ID3V2.3 就记录3 */ 3 y. x! w& K$ f3 l% i4 `5 Y

! r9 Z3 C  w! J( Q/ Tchar Revision;  /* 副版本号此版本记录为0 */ # X& _- k9 Q# \2 V5 K2 U; N
! i  F$ a2 y" z) F! k1 c
char Flag;     /* 存放标志的字节,这个版本只定义了三位,很少用到,可以忽略 */
/ y/ T% v5 z! B5 o4 T8 N' k& ?. l$ g; @4 f3 J; n  a
char Size[4];  /* 标签大小,除了标签头的10 个字节的标签帧的大小 */
1 ?+ }+ J2 H" O" f- z0 Z9 ]! ~5 Q/ F' w1 w
标签大小为四个字节,但每个字节只用低7位,最高位不使用,�为0,其格式如下:* i1 ~- N7 s+ h  S3 g6 V
0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx   @" v+ p, o: o& u9 y: T# ^

7 K6 s5 p$ C5 x( N; m4 {. c计算公式如下:
# y' @: d) h: x. q1 B, y  s4 X+ z! D# P2 \* p$ E4 L( [  M
ID3V2_frame_size =  (int)(Size[0] & 0x7F) << 216 l6 i4 M9 u  Z4 x  J
                  | (int)(Size[1] & 0x7F) << 145 R9 n4 F% z4 M; @0 k
                  | (int)(Size[2] & 0x7F) << 7" Z# B( X5 Z* y( n5 X0 V: g
                  | (int)(Size[3] & 0x7F) + 10;
9 r0 W: ?+ p4 L9 U+ L
/ W1 e* v, e) m  }0 } 0 ]' b8 F0 ?# W( \- P6 L5 U
标签帧
5 ~! q6 q4 _. j+ C% x: l3 x0 f% [; F9 J' K1 R4 b2 V- X& V
每个标签帧都有一个10字节的帧头和至少一个字节的不固定长度的内容组成。它们是顺序存放在文件中,由各自特定的标签头来标记帧的开始。其帧的结构如下:
) C$ }2 _/ B8 B' b' @2 s2 y
9 _4 M, A. y, W! rchar FrameID[4];   /*用四个字符标识一个帧,说明其内容 */ % X. h4 r. t4 @! q  ]4 q; p
9 i& K9 ?1 h: j! u
char Size[4];      /* 帧内容的大小,不包括帧头,不得小于1 */   q3 M( r, C7 V7 Z! ?3 X9 R
! c) C% B7 Z# O6 F, J
char Flags[2];     /* 存放标志,只定义了6 位,此处不再说明 */
  p1 O. G, a: R
% {$ \9 A% K# |- Q& R5 O& j常用帧标识: / o8 }6 J0 w$ r- o! M1 ~

% V8 ?# J7 k' CTIT2:标题
9 H$ {7 u! Q: B( D# C( hTPE1:作者; G4 Z* r1 F& g! M" P
TALB:专辑
" k8 y5 W  ^! R/ \+ v, d5 jTRCK: 音轨,格式:N/M,N表示专辑中第几首,M为专辑中歌曲总数
% H) k1 j! N' w2 H' b5 e7 G: DTYER:年份
, H, |+ d5 t' O) F% b! DTCON:类型5 O# `! n1 ?# s; o5 r( I1 }
COMM:备注,格式:“eng\0备注内容”,其中eng表示所使用的语言
7 t( |+ z) ?, e: t% B) u( J9 F6 p帧大小为四个字节所表示的整数大小。
0 l- N/ W8 \4 u" e2 _8 }- d. ]4 G; m
* E7 K$ ~" e! M0 W' _
" R( V, t' n5 N8 n) \. OII, ID3V1 % r: n/ m; B' y1 T7 X- k" q
. ]" o) k; a0 e( j0 I; g
其数据结构如下: 3 L# `  ^4 ^: }) E' G5 G* e
& Q5 q+ j4 Q, a/ [) |/ c
char Header[3];    /* 标签头必须是"TAG"否则认为没有标签 */
  e0 D0 Y1 Q) s/ v1 Y4 ^5 f- rchar Title[30];    /* 标题 */
  T9 }* i6 a. r- K/ Nchar Artist[30];   /* 作者 */& Q  v/ {" A* @" p" `! n
char Album[30];    /* 专集 */$ j: x  s6 E  W4 g/ _+ L
char Year[4];      /* 出品年代 */
0 O! g/ o' D2 d4 Q1 r% bchar Comment[28]; /* 备注 */, c& m# Y; K: Y& Y! J: ~
char reserve;      /* 保留 */
" d1 N2 g  a! f. C3 i" _% S, f) @4 [char track;;       /* 音轨 */6 W' C5 S4 o) ]) z
char Genre;        /* 类型 */ ! ]* w+ l' C! Z7 a5 a! w5 ]

/ t# m6 J* T' {其实,关于最后31个字节还存在另外一个版本,就是30个字节的Comment和一个字节的Genre.
$ y0 Y- O+ J$ z% t# Q) J" P
- f3 W. X2 J/ F) m有了上述的这些信息,我们就可以自己写代码,从MP3文件中抓取信息以及修改文件名了。但是,如果真的想写一个播放软件,还是需要读它的数据帧,并进行解码。




歡迎光臨 Chip123 科技應用創新平台 (http://free.vireal.world/chip123_website/innoingbbs/) Powered by Discuz! X3.2