2014年6月25日星期三

MP3 ID3文件格式

hecrics
前言
2001年11月的一天,我决定整理一下我的硬盘中乱七八糟的MP3,但使用Winamp+Expleror效率太慢,到网上找了一下只有一个叫MP3/Tag Studio v2.6的工具还不错,可惜是阴文的不说,还只能用30天,而且要插广告。我呸,这么麻烦。一气之下,决定自己写一个从此在网上查阅资料,写下了这辈子的第一个自由软件和这篇文章。大家可以在http://www.csdn.net/cnshare/soft/10/10119.shtm看到这个软件的详细说明和下载链接。
ID3v1
ID3V1比较简单,它是存放在MP3文件的末尾,用16进制的编辑器打开一个MP3文件,查看其末尾的128个顺序存放字节,数据结构定义如下:
char Header[3]; /*标签头必须是"TAG"否则认为没有标签*/
char Title[30]; /*标题*/
char Artist[30]; /*作者*/
char Album[30]; /*专集*/
char Year[4]; /*出品年代*/
char Comment[30]; /*备注*/
char Genre; /*类型*/
ID3V1的各项信息都是顺序存放,没有任何标识将其分开,比如标题信息不足30个字节,则使用'\0'补足,否则将造成信息错误。Genre使用原码表示,对照表如下:
/* Standard genres */
0="Blues";
1="ClassicRock";
2="Country";
3="Dance";
4="Disco";
5="Funk";
6="Grunge";
7="Hip-Hop";
8="Jazz";
9="Metal";
10="NewAge";
11="Oldies";
12="Other";
13="Pop";
14="R&B";
15="Rap";
16="Reggae";
17="Rock";
18="Techno";
19="Industrial";
20="Alternative";
21="Ska";
22="DeathMetal";
23="Pranks";
24="Soundtrack";
25="Euro-Techno";
26="Ambient";
27="Trip-Hop";
28="Vocal";
29="Jazz+Funk";
30="Fusion";
31="Trance";
32="Classical";
33="Instrumental";
34="Acid";
35="House";
36="Game";
37="SoundClip";
38="Gospel";
39="Noise";
40="AlternRock";
41="Bass";
42="Soul";
43="Punk";
44="Space";
45="Meditative";
46="InstrumentalPop";
47="InstrumentalRock";
48="Ethnic";
49="Gothic";
50="Darkwave";
51="Techno-Industrial";
52="Electronic";
53="Pop-Folk";
54="Eurodance";
55="Dream";
56="SouthernRock";
57="Comedy";
58="Cult";
59="Gangsta";
60="Top40";
61="ChristianRap";
62="Pop/Funk";
63="Jungle";
64="NativeAmerican";
65="Cabaret";
66="NewWave";
67="Psychadelic";
68="Rave";
69="Showtunes";
70="Trailer";
71="Lo-Fi";
72="Tribal";
73="AcidPunk";
74="AcidJazz";
75="Polka";
76="Retro";
77="Musical";
78="Rock&Roll";
79="HardRock";
/* Extended genres */
80="Folk";
81="Folk-Rock";
82="NationalFolk";
83="Swing";
84="FastFusion";
85="Bebob";
86="Latin";
87="Revival";
88="Celtic";
89="Bluegrass";
90="Avantgarde";
91="GothicRock";
92="ProgessiveRock";
93="PsychedelicRock";
94="SymphonicRock";
95="SlowRock";
96="BigBand";
97="Chorus";
98="EasyListening";
99="Acoustic";
100="Humour";
101="Speech";
102="Chanson";
103="Opera";
104="ChamberMusic";
105="Sonata";
106="Symphony";
107="BootyBass";
108="Primus";
109="PornGroove";
110="Satire";
111="SlowJam";
112="Club";
113="Tango";
114="Samba";
115="Folklore";
116="Ballad";
117="PowerBallad";
118="RhythmicSoul";
119="Freestyle";
120="Duet";
121="PunkRock";
122="DrumSolo";
123="Acapella";
124="Euro-House";
125="DanceHall";
126="Goa";
127="Drum&Bass";
128="Club-House";
129="Hardcore";
130="Terror";
131="Indie";
132="BritPop";
133="Negerpunk";
134="PolskPunk";
135="Beat";
136="ChristianGangstaRap";
137="HeavyMetal";
138="BlackMetal";
139="Crossover";
140="ContemporaryChristian";
141="ChristianRock";
142="Merengue";
143="Salsa";
144="TrashMetal";
145="Anime";
146="JPop";
147="Synthpop";
ID3V2
ID3V2到现在一共有4个版本,但流行的播放软件一般只支持第3版,既ID3v2.3。由于ID3V1记录在MP3文件的末尾,ID3V2就只好记录在MP3文件的首部了(如果有一天发布ID3V3,真不知道该记录在哪里)。也正是由于这个原因,对ID3V2的操作比ID3V1要慢。而且ID3V2结构比ID3V1的结构要复杂得多,但比前者全面且可以伸缩和扩展。
下面就介绍一下ID3V2.3。
每个ID3V2.3的标签都一个标签头和若干个标签帧或一个扩展标签头组成。关于曲目的信息如标题、作者等都存放在不同的标签帧中,扩展标签头和标签帧并不是必要的,但每个标签至少要有一个标签帧。标签头和标签帧一起顺序存放在MP3文件的首部。
一、标签头
在文件的首部顺序记录10个字节的ID3V2.3的头部。数据结构如下:
char Header[3]; /*必须为"ID3"否则认为标签不存在*/
char Ver; /*版本号ID3V2.3就记录3*/
char Revision; /*副版本号此版本记录为0*/
char Flag; /*存放标志的字节,这个版本只定义了三位,稍后详细解说*/
char Size[4]; /*标签大小,包括标签头的10个字节和所有的标签帧的大小*/
1.标志字节
标志字节一般为0,定义如下:
abc00000
a -- 表示是否使用Unsynchronisation(这个单词不知道是什么意思,字典里也没有找到,一般不设置)
b -- 表示是否有扩展头部,一般没有(至少Winamp没有记录),所以一般也不设置
c -- 表示是否为测试标签(99.99%的标签都不是测试用的啦,所以一般也不设置)
2.标签大小
一共四个字节,但每个字节只用7位,最高位不使用恒为0。所以格式如下
0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx
计算大小时要将0去掉,得到一个28位的二进制数,就是标签大小(不懂为什么要这样做),计算公式如下:
int total_size;
total_size = (Size[0]&0x7F)*0x200000
+(Size[1]&0x7F)*0x400
+(Size[2]&0x7F)*0x80
+(Size[3]&0x7F)
二、标签帧
每个标签帧都有一个10个字节的帧头和至少一个字节的不固定长度的内容组成。它们也是顺序存放在文件中,和标签头和其他的标签帧也没有特殊的字符分隔。得到一个完整的帧的内容只有从帧头中的到内容大小后才能读出,读取时要注意大小,不要将其他帧的内容或帧头读入。
帧头的定义如下:
char FrameID[4]; /*用四个字符标识一个帧,说明其内容,稍后有常用的标识对照表*/
char Size[4]; /*帧内容的大小,不包括帧头,不得小于1*/
char Flags[2]; /*存放标志,只定义了6位,稍后详细解说*/
1.帧标识
用四个字符标识一个帧,说明一个帧的内容含义,常用的对照如下:
TIT2=标题 表示内容为这首歌的标题,下同
TPE1=作者
TALB=专集
TRCK=音轨 格式:N/M 其中N为专集中的第N首,M为专集中共M首,N和M为ASCII码表示的数字
TYER=年代 是用ASCII码表示的数字
TCON=类型 直接用字符串表示
COMM=备注 格式:"eng\0备注内容",其中eng表示备注所使用的自然语言
2.大小
这个可没有标签头的算法那么麻烦,每个字节的8位全用,格式如下
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
算法如下:
int FSize;
FSize = Size[0]*0x100000000
+Size[1]*0x10000
+Size[2]*0x100
+Size[3];
3.标志
只定义了6位,另外的10位为0,但大部分的情况下16位都为0就可以了。格式如下:
abc00000 ijk00000
a -- 标签保护标志,设置时认为此帧作废
b -- 文件保护标志,设置时认为此帧作废
c -- 只读标志,设置时认为此帧不能修改(但我没有找到一个软件理会这个标志)
i -- 压缩标志,设置时一个字节存放两个BCD码表示数字
j -- 加密标志(没有见过哪个MP3文件的标签用了加密)
k -- 组标志,设置时说明此帧和其他的某帧是一组
值得一提的是winamp在保存和读取帧内容的时候会在内容前面加个'\0',并把这个字节计算在帧内容的大小中。
详细的情况可以到www.id3.org查询,对于ID3V1和ID3V2的读写,我用DELPHI写了两个类来实现,可以写信给我索取q.d.zhang@sohu.com
附:帧标识的含义
4. Declared ID3v2 frames
The following frames are declared in this draft.
AENC Audio encryption
APIC Attached picture
COMM Comments
COMR Commercial frame
ENCR Encryption method registration
EQUA Equalization
ETCO Event timing codes
GEOB General encapsulated object
GRID Group identification registration
IPLS Involved people list
LINK Linked information
MCDI Music CD identifier
MLLT MPEG location lookup table
OWNE Ownership frame
PRIV Private frame
PCNT Play counter
POPM Popularimeter
POSS Position synchronisation frame
RBUF Recommended buffer size
RVAD Relative volume adjustment
RVRB Reverb
SYLT Synchronized lyric/text
SYTC Synchronized tempo codes
TALB Album/Movie/Show title
TBPM BPM (beats per minute)
TCOM Composer
TCON Content type
TCOP Copyright message
TDAT Date
TDLY Playlist delay
TENC Encoded by
TEXT Lyricist/Text writer
TFLT File type
TIME Time
TIT1 Content group description
TIT2 Title/songname/content description
TIT3 Subtitle/Description refinement
TKEY Initial key
TLAN Language(s)
TLEN Length
TMED Media type
TOAL Original album/movie/show title
TOFN Original filename
TOLY Original lyricist(s)/text writer(s)
TOPE Original artist(s)/performer(s)
TORY Original release year
TOWN File owner/licensee
TPE1 Lead performer(s)/Soloist(s)
TPE2 Band/orchestra/accompaniment
TPE3 Conductor/performer refinement
TPE4 Interpreted, remixed, or otherwise modified by
TPOS Part of a set
TPUB Publisher
TRCK Track number/Position in set
TRDA Recording dates
TRSN Internet radio station name
TRSO Internet radio station owner
TSIZ Size
TSRC ISRC (international standard recording code)
TSSE Software/Hardware and settings used for encoding
TYER Year
TXXX User defined text information frame
UFID Unique file identifier
USER Terms of use
USLT Unsychronized lyric/text transcription
WCOM Commercial information
WCOP Copyright/Legal information
WOAF Official audio file webpage
WOAR Official artist/performer webpage
WOAS Official audio source webpage
WORS Official internet radio station homepage
WPAY Payment
WPUB Publishers official webpage
WXXX User defined URL link frame


-完-

2014年6月19日星期四

20071102 | 上条恒彦《母亲的照片》(お母さんの写真)

无尽的梦

(跪地口白)

除了自己的灵魂以外

没有什么是属于自己的东西

不要爱现在的自己

而要爱未来的自己


​不要一味追求享乐

不要鼠目寸光

常保目光向前

今年的巢不会住去年的鸟

男人要公正 女人要端正

在其人的幻想中生存

为其人而立下伟大功勋

其人名为

达辛妮亚

(站起开唱)

梦想虽难结果

前路阻碍众多

纵使黯然神伤

吾将奋勇前行

道路崎岖凶险

臂腕疲惫不堪

遥远星辰指引

吾仍继续前行

这是吾之宿命

从此污浊世间

拯救不变真理

任由希望微薄遥远

终将迎来光明遍野

直到陷入永世沉眠

即使伤痕累累

仍将竭尽全力

吾将继续前行

去向星辰彼岸

秋千

遥远山上吹来的风传来信息

山丘上的平原笼罩在夕阳中

不知是谁忘记的银色口琴

在落叶的阴影中渐渐沉默

飘啊飘 摇啊摇

垂下阴影摇摇摆摆

想起了许久以前的梦境

秋千缓缓摇摆

就像静静老去的贤者

眺望季节流转

背着烤乳猪



背着烤乳猪来了

想拿给你吃

料理了猪 升起火烧了

从山那边跑来

流了许多汗 弄脏了

慌慌张张回去了

摘下了不知名的花

带了过来 带了过来

流了许多汗 弄脏了

慌慌张张回去了

椅子

出门买椅子

在城中的店里寻找

只要求坚固

想要橡木的椅子

春天放在透过阳光的树下

坐着看书

夏天穿着短裤

小睡一会儿

想要这样的椅子

想要只属于自己

这世上唯一的椅子

油屋

刚才还在睡觉 这就要工作了

刚以为做完了 这又要开始了

身体好重 心情更重

你说有工作才是好事

婆婆说了(刚才还是少女的婆婆)

漂亮只在年轻时

爷爷说了(刚才还是小哥的爷爷)

剩下的只有人生

沉重而懈怠的人生

爷爷说了(刚才还很年轻的爷爷)

剩下的只有人生

沉重而懈怠的人生

母亲的照片

相册的旧照片中

斜戴着褪色的草帽

微笑着的小女孩

闪着光芒的酒窝 耀眼的笑容

母亲还是小女孩时的照片

一去不复返的遥远夏日

无法传达的憧憬

紫薇花落下阴影 老旧的房屋

倚在门边 抱着不知名的小狗

微笑着的小女孩

摇摆的小辫 温柔的瞳眸

母亲还是小女孩时的照片

一去不复返的遥远夏日

无法传达的憧憬

母亲还是小女孩时的照片

永远闪耀着光辉的遥远夏日

盛夏的振子


​飞驰而去的蓝色地平线

向着扔到风中的麦秆

你呼喊着 在未来等我

心潮澎湃 与潮水无异

在耀眼光芒中 放松全身

心中无法停止

盛夏的振子 直到现在

通向蓝天的灼热坡道

即使放走抓住的蜻蜓

也知道明日一定会再来

脱壳的蝉 草上的热气 温热的水

太阳每日都热烈燃烧

那个夏天一直延续

耀眼的梦想 直到今日

心中无法停止

盛夏的振子 直到现在

中央线

你家那边落下一颗流星

我停下刷牙 冲上了电车

现在的你 弄碎了流星

浮在浴盆里 在等着我

奔驰吧 中央线

穿越黑夜 载着我

寻找着逃走的猫咪

你再也没有回来

现在的你 找到了某处惬意的小镇

在和猫咪一起生活吧

奔驰吧 中央线

穿越黑夜 载着我

奔驰吧 中央线

穿越黑夜 载着我

奔驰吧 中央线

穿越黑夜 载着我

冬日星座

冬日寒风已绝 天空透彻清朗

缓缓落下地面 神奇美妙光芒

万物皆沉眠 皑皑寂静中

闪烁又摇摆 星座空流转

隐隐散发光芒 银河流淌于空

猎户舞动绚烂 牧牛躁动不安

静指无穷处 北斗针芒尖

闪烁又摇摆 星座空流转

牧场的清晨

茫茫一片笼罩遍野

牧场早晨的雾之海

白杨林间淡淡传来

黑色底部那样坚实

钟声响起 铛铛铛

陆续醒过来的田舍

传来人们喧扰之声

处处为浓雾所包围

几群羊儿四处走动

铃声响起 叮铃铃

大古钟


​又大又高的古钟 爷爷的钟

百年来一直运转 自豪的钟

爷爷初生的清晨 买来的钟

现在已经不动了 这个大钟

百年来从不停息 滴滴答答

和爷爷一起走着 滴滴答答

现在已经不动了 这个大钟

无所不知的古钟 爷爷的钟

美丽的新娘来了 仍然在走

无论快乐或悲伤 它都知道

现在已经不动了 这个大钟

百年来从不停息 滴滴答答

和爷爷一起走着 滴滴答答

现在已经不动了 这个大钟

深夜中铃声响了 爷爷的钟

别离的时刻到了 告知大家

上了天堂的爷爷 告别了钟

现在已经不动了 这个大钟

百年来从不停息 滴滴答答

和爷爷一起走着 滴滴答答

现在已经不动了 这个大钟

现在已经不动了 这个大钟

散步

走吧 走吧 我很精神

最喜欢走路 尽情走吧

坡道 隧道 还有草地

独木桥 凹凸不平 沙石路

穿过蜘蛛巢 还有下坡

走吧 走吧 我很精神

最喜欢走路 尽情走吧

蜜蜂 嗡嗡 还有花田

向阳和背阴 有蛇在午睡

蝴蝶在飞舞 还有转弯

走吧 走吧 我很精神

最喜欢走路 尽情走吧

狐狸 狸猫 都出来了

来探险吧 直到树林深处

好多小朋友 真开心啊

好多小朋友 真开心啊

风中之人



何处谁人 仍在等待

云已烧灼 道已蒸干

太阳永远 不会沉寂

而在此刻 早已心死

从无微笑 不知昨日

今日旅程 独自一人

然而何处 你仍等待

而你一定 伫立风中

等待着我

何处谁人 仍在等待

血在流逝 皮开肉绽

疼痛却是 生之印记

几度山峦 勇于跨越

无论何处 难寻故里

谁在哭泣 还有何求

然而何处 你仍等待

而你一定 伫立风中

等待着我


出处:http://www.verovie.net/?p=294


-完-