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 C
MP3文件是由帧(frame)构成,帧是MP3文件的最小组成单位。每帧都包含帧头,并可以计算帧的长度。根据帧的性质不同,文件主要分为三个部分,ID3v2标签帧,数据帧和ID3v1标签帧。并非每个MP3文件都有ID3v2,但是数据帧和ID3v1帧是必须的。ID3v2在文件头,以字符串“ID3”为标志,包含了演唱者,作曲,专辑等信息,长度不固定,扩展了ID3V1的信息量。ID3v1在文件结尾,以字符串“TAG”为标记,其长度是固定的128个字节,包含了演唱者、歌名、专辑、年份等信息。
3 @" a7 S) C2 A; O" }
; a+ D- v" q M
I, 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 s
9 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& D
char 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/ T
char 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 T
8 N' k& ?. l$ g; @4 f3 J; n a
char Size[4]; /* 标签大小,除了标签头的10 个字节的标签帧的大小 */
1 ?+ }+ J2 H" O" f- z0 Z
9 ]! ~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) << 21
6 l6 i4 M9 u Z4 x J
| (int)(Size[1] & 0x7F) << 14
5 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 x
0 f% [; F9 J' K1 R4 b2 V- X& V
每个标签帧都有一个10字节的帧头和至少一个字节的不固定长度的内容组成。它们是顺序存放在文件中,由各自特定的标签头来标记帧的开始。其帧的结构如下:
) C$ }2 _/ B8 B' b' @2 s2 y
9 _4 M, A. y, W! r
char 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' C
TIT2:标题
9 H$ {7 u! Q: B( D# C( h
TPE1:作者
; G4 Z* r1 F& g! M" P
TALB:专辑
" k8 y5 W ^! R/ \+ v, d5 j
TRCK: 音轨,格式:N/M,N表示专辑中第几首,M为专辑中歌曲总数
% H) k1 j! N' w2 H' b5 e7 G: D
TYER:年份
, H, |+ d5 t' O) F% b! D
TCON:类型
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) \. O
II, 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- r
char Title[30]; /* 标题 */
T9 }* i6 a. r- K/ N
char 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% b
char 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