Some time ago, I built a small website on the local area network, and one of the sections involved the online playback of music. Considering the convenience of future maintenance, we decided to store the mp3 files in different directories according to albums. Then use a program to monitor the directory where mp3s are stored, store the information of each mp3 file in the database, and use the ASP.NET page to present the mp3 file information to the user. Although it is not difficult to use .NET to read the information of mp3 files, it also requires a lot of skills, so the process is organized and shared with everyone.
First, let's take a look at where the mp3 song information is stored. Mp3 files contain a tag called ID3. There are actually two tags, one is called ID3v1 and the other is called ID3v2. For the sake of simplicity, we only introduce ID3v1 here.
The ID3V1 structure is relatively simple and is stored at the end of the MP3 file. You can use a hexadecimal editor (for example: UltraEdit) to open an MP3 file. Pay attention to the 128 bytes at the end. The data structure is defined as follows:
Name Position Length Content
Header 1-3 3 Tag header
Title 4-33 30 Title
Artist 34-63 30 Artist
Album 64-93 30 Album
Year 94-97 4 Production year
Comment 98-127 30 Remarks
Center 128 1 Type
Note: The above tag header must be "TAG", otherwise it means there is no tag.
The information of ID3v1 is stored in order. There is no end mark after each piece of information. If the length of a piece of information is less than the standard length, use " " to add. Genre is an exception. It uses one byte to represent the song genre. The corresponding table is as follows (because there is too much content, only the first 50 items are listed):
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"
After knowing the structure of MP3 song information storage, we can write the corresponding code.
First define an MP3Info class:
1 Public Class Mp3Info
2
3
4
5 Private Const TAGLEN As Integer = 128
6
7
8
9 Private _MP3Tag As String = String.Empty
10
11 Private _Artist As String = String.Empty
12
13 Private _Title As String = String.Empty
14
15 Private _Album As String = String.Empty
16
17 Private _Comment As String = String.Empty
18
19 Private _Year As String = String.Empty
20
21 Private _Genre As String = String.Empty
twenty two
23Private_GenreIDAsByte
twenty four
25
26
27 Private Genres() As String = {"Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", _
28
29 "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", _
30
31 "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", _
32
33 "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid", _
34
35 "House", "Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass", "Soul", "Punk", "Space", _
36
37 "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", _
38
39 "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", _
40
41 "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", "Psychedelic", "Rave", _
42
43 "Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", _
44
45 "Rock & Roll", "Hard Rock", "Folk", "Folk/Rock", "National Folk", "Swing", "Bebob", "Latin", "Revival", _
46
47 "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", _
48
49 "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson", "Opera", _
50
51 "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", _
52
53 "Tango", "Samba", "Folklore"}
54
55
56
57 Public Property MP3Tag() As String
58
59 Get
60
61 Return _MP3Tag
62
63 End Get
64
65 Set(ByVal value As String)
66
67 _MP3Tag = value.Trim
68
69 End Set
70
71 End Property
72
73
74
75 Public Property Title() As String
76
77 Get
78
79 Return _Title
80
81 End Get
82
83 Set(ByVal value As String)
84
85 _Title = value.Trim
86
87 End Set
88
89 End Property
90
91
92
93 Public Property Artist() As String
94
95 Get
96
97 Return _Artist
98
99 End Get
100
101 Set(ByVal value As String)
102
103 _Artist = value.Trim
104
105 End Set
106
107 End Property
108
109
110
111 Public Property Album() As String
112
113 Get
114
115 Return_Album
116
117 End Get
118
119 Set(ByVal value As String)
120
121 _Album = value.Trim
122
123 End Set
124
125 End Property
126
127
128
129 Public Property Comment() As String
130
131 Get
132
133 Return_Comment
134
135 End Get
136
137 Set(ByVal value As String)
138
139 _Comment = value.Trim
140
141 End Set
142
143 End Property
144
145
146
147 Public Property Genre() As String
148
149 Get
150
151 Return_Genre
152
153 End Get
154
155 Set(ByVal value As String)
156
157 _Genre = value.Trim
158
159 End Set
160
161 End Property
162
163
164
165 Public Property GenreID() As Byte
166
167 Get
168
169 Return_GenreID
170
171 End Get
172
173 Set(ByVal value As Byte)
174
175 _GenreID = value
176
177 End Set
178
179 End Property
180
181
182
183 Public Property Year() As String
184
185 Get
186
187 Return _Year
188
189 End Get
190
191 Set(ByVal value As String)
192
193 _Year = value.Trim
194
195 End Set
196
197 End Property
198
199 End Class
200
201
202
203 The above class only contains the data structure corresponding to mp3 song information. We also need to add a specific process for reading mp3 file information:
204
205
206
207 Public Function GetMp3FileInfo(ByVal fname As String) As Boolean
208
209
210
211 'Open the filestream
212
213 Dim msfile As FileStream
214
215 Try
216
217 msfile = New FileStream(fname, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
218
219 If Not (msfile.CanRead) Then
220
221 Throw New IO.IOException("Unable to read file:" + fname)
222
223 End If
224
225 Catch Ex As Exception
226
227 Throw New IO.IOException("An error occurred while reading the file!" + Ex.Message)
228
229 End Try
230
231
232
233 Dim ID3(TAGLEN - 1) As Byte
234
235 Dim BinReader As BinaryReader
236
237 DimStrInfoAsString
238
239
240
241 'Use BinaryReader to read information
242
243 BinReader = New BinaryReader(msfile)
244
245
246
247 msfile.Position = 0
248
249 msfile.Seek(-TAGLEN, SeekOrigin.End)
250
251
252
253 StrInfo = CBytesToString(BinReader.ReadBytes(3))
254
255
256
257 'Determine whether the tag header is TAG
258
259 If StrInfo.ToUpper = "TAG" Then
260
261
262
263 'Read title information
264
265 StrInfo = CBytesToString(BinReader.ReadBytes(30)).Replace(Chr(0), "")
266
267 _Title = StrInfo
268
269
270
271 'Read artist information
272
273 StrInfo = CBytesToString(BinReader.ReadBytes(30)).Replace(Chr(0), "")
274
275 _Artist = StrInfo
276
277
278
279 'Read album information
280
281 StrInfo = CBytesToString(BinReader.ReadBytes(30)).Replace(Chr(0), "")
282
283 _Album = StrInfo
284
285
286
287 'Read publication year information
288
289 StrInfo = CBytesToString(BinReader.ReadBytes(4)).Replace(Chr(0), "")
290
291 _Year = StrInfo
292
293
294
295 'Read remark information
296
297 StrInfo = CBytesToString(BinReader.ReadBytes(30)).Replace(Chr(0), "")
298
299 _Comment = StrInfo
300
301
302
303 'Read song genre information
304
305 _GenreID = BinReader.ReadByte
306
307
308
309 End If
310
311
312
313 BinReader.Close()
314
315 msfile.Close()
316
317
318
319 End Function
320
321
322
323 'Used to convert encoding to prevent Chinese garbled characters
324
325 Private Function CBytesToString(ByVal Bytes() As Byte) As String
326
327 'Note that the encoding needs to be processed here to prevent garbled characters.
328
329 Dim GbCode As Encoding = Encoding.GetEncoding("gb2312")
330
331 If Bytes.Length > 0 Then
332
333 Return GbCode.GetString(Bytes)
334
335 Else
336
337 Return String.Empty
338
339 End If
340
341 End Function
We can use a simple Console program to illustrate how to use the Mp3Info class. Using Visual Studio 2005 Express, create a Console program:
1 Module Module1
2
3
4
5 Sub
6
7
8
9 Dim Mp3 As New Mp3Info("D:MusicTop 40 Singles39 Embrace - Natures Law.mp3")
10
11
12
13 Console.WriteLine("Title : " + Mp3.Title)
14
15 Console.WriteLine("Artist: " + Mp3.Artist)
16
17 Console.WriteLine("Album : " + Mp3.Album)
18
19 Console.Read()
20
21 End Sub
twenty two
twenty three
24 End Module
After running the program, the output is:
Title: Nature's Law
Artist: Embrace
Album: DHZ.INC
Genre: Blues
This article only discusses the ID3v1 of mp3, but in fact many mp3s not only contain ID3v1 information, but also contain ID3v2 information.
But ID3v2 is more complicated than ID3v1. The processing of ID3v2 will have to wait until next time when I have time to write it.