这是一篇没有营养的文章。只是用来练习的。但是还有改善的地方,如ID3V2的解析,多国语言的支持等。
1 #!/usr/bin/python 2 #-*-<coding:UTF-8>-*- 3 4 """ 5 This file is mainly designed for mp3 ID3V_1/2 Decoder. 6 """ 7 8 import os 9 import sys 10 11 GENRE = { 12 0:"Blues", 13 1:"ClassicRock", 14 2:"Country", 15 3:"Dance", 16 4:"Disco", 17 5:"Funk", 18 6:"Grunge", 19 7:"Hip-Hop", 20 8:"Jazz", 21 9:"Metal", 22 10:"NewAge", 23 11:"Oldies", 24 12:"Other", 25 13:"Pop", 26 14:"R&B", 27 15:"Rap", 28 16:"Reggae", 29 17:"Rock", 30 18:"Techno", 31 19:"Industrial", 32 20:"Alternative", 33 21:"Ska", 34 22:"DeathMetal", 35 23:"Pranks", 36 24:"Soundtrack", 37 25:"Euro-Techno", 38 26:"Ambient", 39 27:"Trip-Hop", 40 28:"Vocal", 41 29:"Jazz+Funk", 42 30:"Fusion", 43 31:"Trance", 44 32:"Classical", 45 33:"Instrumental", 46 34:"Acid", 47 35:"House", 48 36:"Game", 49 37:"SoundClip", 50 38:"Gospel", 51 39:"Noise", 52 40:"AlternRock", 53 41:"Bass", 54 42:"Soul", 55 43:"Punk", 56 44:"Space", 57 45:"Meditative", 58 46:"InstrumentalPop", 59 47:"InstrumentalRock", 60 48:"Ethnic", 61 49:"Gothic", 62 50:"Darkwave", 63 51:"Techno-Industrial", 64 52:"Electronic", 65 53:"Pop-Folk", 66 54:"Eurodance", 67 55:"Dream", 68 56:"SouthernRock", 69 57:"Comedy", 70 58:"Cult", 71 59:"Gangsta", 72 60:"Top40", 73 61:"ChristianRap", 74 62:"Pop/Funk", 75 63:"Jungle", 76 64:"NativeAmerican", 77 65:"Cabaret", 78 66:"NewWave", 79 67:"Psychadelic", 80 68:"Rave", 81 69:"Showtunes", 82 70:"Trailer", 83 71:"Lo-Fi", 84 72:"Tribal", 85 73:"AcidPunk", 86 74:"AcidJazz", 87 75:"Polka", 88 76:"Retro", 89 77:"Musical", 90 78:"Rock&Roll", 91 79:"HardRock", 92 80:"Folk", 93 81:"Folk-Rock", 94 82:"NationalFolk", 95 83:"Swing", 96 84:"FastFusion", 97 85:"Bebob", 98 86:"Latin", 99 87:"Revival", 100 88:"Celtic", 101 89:"Bluegrass", 102 90:"Avantgarde", 103 91:"GothicRock", 104 92:"ProgessiveRock", 105 93:"PsychedelicRock", 106 94:"SymphonicRock", 107 95:"SlowRock", 108 96:"BigBand", 109 97:"Chorus", 110 98:"EasyListening", 111 99:"Acoustic", 112 100:"Humour", 113 101:"Speech", 114 102:"Chanson", 115 103:"Opera", 116 104:"ChamberMusic", 117 105:"Sonata", 118 106:"Symphony", 119 107:"BootyBass", 120 108:"Primus", 121 109:"PornGroove", 122 110:"Satire", 123 111:"SlowJam", 124 112:"Club", 125 113:"Tango", 126 114:"Samba", 127 115:"Folklore", 128 116:"Ballad", 129 117:"PowerBallad", 130 118:"RhythmicSoul", 131 119:"Freestyle", 132 120:"Duet", 133 121:"PunkRock", 134 122:"DrumSolo", 135 123:"Acapella", 136 124:"Euro-House", 137 125:"DanceHall", 138 126:"Goa", 139 127:"Drum&Bass", 140 128:"Club-House", 141 129:"Hardcore", 142 130:"Terror", 143 131:"Indie", 144 132:"BritPop", 145 133:"Negerpunk", 146 134:"PolskPunk", 147 135:"Beat", 148 136:"ChristianGangstaRap", 149 137:"HeavyMetal", 150 138:"BlackMetal", 151 139:"Crossover", 152 140:"ContemporaryChristian", 153 141:"ChristianRock", 154 142:"Merengue", 155 143:"Salsa", 156 144:"TrashMetal", 157 145:"Anime", 158 146:"JPop", 159 147:"Synthpop", 160 255:"None" 161 } 162 163 class ID3Ver1_Decoder(): 164 165 def __init__(self,filename): 166 self.fd = open(filename) 167 168 def __del__(self): 169 self.fd.close() 170 171 def getID3_header(self): 172 length = 3 173 self.fd.seek(-128,os.SEEK_END) 174 header = self.fd.read(length) 175 return header, 176 177 def getID3_title(self): 178 length = 30 179 self.fd.seek(-125,os.SEEK_END) 180 title = self.fd.read(length) 181 return title 182 183 def getID3_artist(self): 184 length = 30 185 self.fd.seek(-95,os.SEEK_END) 186 artist = self.fd.read(length) 187 return artist 188 189 def getID3_album(self): 190 length = 30 191 self.fd.seek(-65,os.SEEK_END) 192 album = self.fd.read(length) 193 return album 194 195 def getID3_year(self): 196 length = 4 197 self.fd.seek(-61,os.SEEK_END) 198 year = self.fd.read(length) 199 return year 200 201 def getID3_comment(self): 202 length = 30 203 self.fd.seek(-31,os.SEEK_END) 204 comment = self.fd.read(length) 205 return comment 206 207 def getID3_genre(self): 208 length = 1 209 self.fd.seek(-1,os.SEEK_END) 210 genre = self.fd.read(length) 211 return GENRE[ord(genre)] 212 213 class ID3Ver2_Decoder(): 214 215 def __init__(self,filename): 216 self.fd = open(filename) 217 218 def getID3Ver2_header(self): 219 length = 3 220 self.fd.seek(0,os.SEEK_SET) 221 header = self.fd.read(length) 222 return header 223 224 def getID3Ver2_version(self): 225 length = 1 226 self.fd.seek(3,os.SEEK_SET) 227 version = self.fd.read(length) 228 return ord(version) 229 230 def getID3Ver2_revision(self): 231 length = 1 232 self.fd.seek(4,os.SEEK_SET) 233 revision = self.fd.read(length) 234 return ord(revision) 235 236 def getID3Ver2_flag(self): 237 length = 1 238 self.fd.seek(5,os.SEEK_SET) 239 flag = self.fd.read(length) 240 return ord(flag) 241 242 def getID3Ver2_size(self): 243 length = 4 244 self.fd.seek(6,os.SEEK_SET) 245 size = self.fd.read(length) 246 #print "size:%d,%d,%d,%d" %(ord(size[0]),ord(size[1]),ord(size[2]),ord(size[3])) 247 totalSize = (ord(size[0])&0x7f)*0x2000000 + (ord(size[1])&0x7f)*0x40000 + \ 248 (ord(size[2])&0x7f)*0x80 + ord(size[3])&0x7f 249 #print totalSize 250 return totalSize 251 252 def getID3Ver2_frame(self): 253 length = 4 254 self.fd.seek(10,os.SEEK_SET) 255 frameID = self.fd.read(length) 256 return frameID 257 258 def getID3Ver2_frameSize(self): 259 length = 4 260 self.fd.seek(14,os.SEEK_SET) 261 frameSize = self.fd.read(length) 262 totalSize = ord(frameSize[0])*0x1000000 + ord(frameSize[1])*0x10000 + \ 263 ord(frameSize[2])*0x100 + ord(frameSize[3]) 264 return totalSize 265 266 def getID3Ver2_frameFlags(self): 267 length = 2 268 self.fd.seek(18,os.SEEK_SET) 269 frameFlags = self.fd.read(length) 270 return frameFlags 271 272 273 if __name__ == "__main__": 274 mp3 = ID3Ver1_Decoder("abc.mp3") 275 header = mp3.getID3_header() 276 title = mp3.getID3_title() 277 artist = mp3.getID3_artist() 278 genre = mp3.getID3_genre() 279 print ">>>ID3Ver_1 info:" 280 print "title:%s\nartist:%s\ngenre:%s\n" %(title,artist,genre) 281 282 mp32 = ID3Ver2_Decoder("abc.mp3") 283 header = mp32.getID3Ver2_header() 284 version = mp32.getID3Ver2_version() 285 revision = mp32.getID3Ver2_revision() 286 size = mp32.getID3Ver2_size() 287 flags = mp32.getID3Ver2_frameFlags() 288 print ">>>ID3Ver_2 info:" 289 print "header:%s\nVersion:%s\nframeFlags:%s" %(header,version,flags)