|
Introduction
There are many other articles at The Code Project describing the audio
header and tag information, but none in VB.NET. So it's time to update
my very old article (Reading
and writing MP3 ID3v1 tags
) with nicer code and extend it to read the MPEG header information.
I don't want to go into detail about the structure of MPEG audio headers,
because Konrad Windszus already has a very good article (MPEG
Audio Frame Header) about that. If you're interested in the structure
of the audio header or the ID3 tag format i recommend to visit the
following sites:
Using the code
I wrote two classes to handle the header and tag information, called MP3Info
and ID3v1Tag. The following code will show the structure
to use the classes:
Dim objMP3Info As New _
Monotic.Multimedia.MP3.MP3Info
With ListView1
objMP3Info.Filename = "c:\test.mp3"
.Add("Filesize").SubItems.Add(objMP3Info.Filesize & " Byte")
.Add("SamplingRateFrequency").SubItems.Add _
(objMP3Info.SamplingRateFrequency & " Hz")
.Add("Padding").SubItems.Add(objMP3Info.Padding & " Bytes")
.Add("Private").SubItems.Add(objMP3Info.PrivateBit)
.Add("Copyright").SubItems.Add(objMP3Info.Copyright)
.Add("OriginalBit").SubItems.Add(objMP3Info.OriginalBit)
.Add("Bitrate").SubItems.Add(objMP3Info.Bitrate & " bps")
.Add("FrameSamples").SubItems.Add(objMP3Info.FrameSamples)
.Add("FrameSize").SubItems.Add(objMP3Info.FrameSize & " Byte")
.Add("Length").SubItems.Add(objMP3Info.Length & " s ("
& Int(objMP3Info.Length / 60) & ":" & _
objMP3Info.Length Mod 60 & " m)")
.Add("HeaderPosition").SubItems.Add(objMP3Info.HeaderPosition)
.Add("VBRScale").SubItems.Add(objMP3Info.VBRScale)
Select Case objMP3Info.MPEGVersion
Case MP3.MPEGVersionEnum.MPEG1
.Add("MPEGType").SubItems.Add("MPEG 1")
Case MP3.MPEGVersionEnum.MPEG2
.Add("MPEGType").SubItems.Add("MPEG 2")
Case MP3.MPEGVersionEnum.MPEG25
.Add("MPEGType").SubItems.Add("MPEG 2.5")
End Select
Select Case objMP3Info.Layer
Case MP3.LayerEnum.LayerI
.Add("Layer").SubItems.Add("Layer I")
Case MP3.LayerEnum.LayerII
.Add("Layer").SubItems.Add("Layer II")
Case MP3.LayerEnum.LayerIII
.Add("Layer").SubItems.Add("Layer III")
End Select
Select Case objMP3Info.Protection
Case MP3.ProtectionEnum.None
.Add("Protection").SubItems.Add("None")
Case MP3.ProtectionEnum.CRC
.Add("Protection").SubItems.Add("By CRC")
End Select
Select Case objMP3Info.ChannelMode
Case MP3.ChannelModeEnum.DualChannel
.Add("ChannelMode").SubItems.Add("Dual Channel")
Case MP3.ChannelModeEnum.JointStereo
.Add("ChannelMode").SubItems.Add("Joint Stereo")
Case MP3.ChannelModeEnum.SingleChannel
.Add("ChannelMode").SubItems.Add("Single Channel")
Case MP3.ChannelModeEnum.Stereo
.Add("ChannelMode").SubItems.Add("Stereo")
End Select
Select Case objMP3Info.Emphasis
Case MP3.EmphasisEnum.CCIT
.Add("Emphasis").SubItems.Add("CCIT")
Case MP3.EmphasisEnum.MS5015
.Add("Emphasis").SubItems.Add("50/15 ms")
Case MP3.EmphasisEnum.None
.Add("Emphasis").SubItems.Add("None")
End Select
Select Case objMP3Info.Encoding
Case MP3.EncodingEnum.CBR
.Add("Encoding").SubItems.Add("CBR")
Case MP3.EncodingEnum.VBR
.Add("Encoding").SubItems.Add("VBR")
End Select
If (objMP3Info.ID3v1Tag.TagAvailable) Then
.Add("ID3 Title").SubItems.Add _
(objMP3Info.ID3v1Tag.Title)
[...]
End If
objMP3Info.ID3v1Tag.Title = "Another title"
objMP3Info.ID3v1Tag.Update()
End With
Please have a look at the sample and the class code to see all the
features.
Points of Interest
Unlike other articles, this class will handle CBR and VBR encoded files, so the
playtime is calculated correctly.
The class is well-commented with XML comments made by
AxTools CodeSmart 2005 and NDoc
. I included the generated HTML help file in the download.
I'm working on reading and writing the much more complex ID3v2.x tags at the
moment (80% done, just compressed frames are a little bit tricky). If you are
interested in this, i will update this article in the future.
History
27.02.2004 Release of version 1
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 32 (Total in Forum: 32) (Refresh) | FirstPrevNext |
|
|
 |
|
|
this sample code for the mp3-tags is excellent for reading the tags, but how can i write some informations??
objMP3Info.ID3v1Tag.Title = "Another title" objMP3Info.ID3v1Tag.update()
error: update isnt a member of monotonic.multimedia.mp3.ID3v1Tag...
it doesnt work ;-(
anybody can help me?
|
| Sign In·View Thread·PermaLink | 1.14/5 (4 votes) |
|
|
|
 |
|
|
 |
|
|
 |
|
|
Hi, I'm using this powerfull code and I think that is very well done.
I think that the form to obtain the genre is a little archaic, and i'm gona implement the search whit a XML file that can be editable in the future.. i don't now what you think..
For now I think that the GetGenreString function must end like this:
Public Function GetGenreString(ByVal bytGenre As Byte) As String
Dim strGenres() As String = {"Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", _ "Hip - Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", _ "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro -Techno", "Ambient", _ "Trip -Hop", "Vocal", "Jazz Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", _ "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative", _ "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno -Industrial", "Electronic", _ "Pop -Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap", _ "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", _ "Lo - Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", _ "Folk", "Folk/Rock", "National Folk", "Swing", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", _ "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", _ "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", _ "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", _ "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A Cappella", "Euro - House", _ "Dance Hall", "Goa", "Drum & Bass", "Club - House", "Hardcore", "Terror", "Indie", "BritPop", "Negerpunk", _ "Polsk Punk", "Beat", "Christian Gangsta Rap", "Heavy Metal", "Black Metal", "Crossover", "Contemporary Christian", _ "Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop", "Synthpop"} If bytGenre > 147 Then Return "Unknown" Else Return strGenres(bytGenre) End If End Function
Thanks again for the class man..
Ricsamma
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
ricsamma wrote: I think that the form to obtain the genre is a little archaic, and i'm gona implement the search whit a XML file that can be editable in the future.. i don't now what you think..
Yes, it is, but i think there is no need for an extra xml file, because the genres don't will change.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi, This is a really nifty little class. Thanx a million for it. There was no project or anything in the download though, so I created a project, added a form to it and on the form put a ListBox1 and a "test" button called btn_test. Then I changed the code from this page and added it to the btn_test. Hope this helps others.
John Private Sub btn_Test_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_Test.Click Dim objMP3Info As New Monotic.Multimedia.MP3.MP3Info With ListBox1.Items ' Set the filename property objMP3Info.Filename = "test.mp3"
' Add the header information to a listview .Add("Filesize= " & objMP3Info.Filesize & " Byte") .Add("SamplingRateFrequency= " & objMP3Info.SamplingRateFrequency & " Hz") .Add("Padding= " & objMP3Info.Padding & " Bytes") .Add("Private= " & objMP3Info.PrivateBit) .Add("Copyright=" & objMP3Info.Copyright) .Add("OriginalBit= " & objMP3Info.OriginalBit) .Add("Bitrate= " & objMP3Info.Bitrate & " bps") .Add("FrameSamples= " & objMP3Info.FrameSamples) .Add("FrameSize= " & objMP3Info.FrameSize & " Byte") .Add("Length= " & objMP3Info.Length & " s (" & Int(objMP3Info.Length / 60) & ":" & objMP3Info.Length Mod 60 & " m)") .Add("HeaderPosition= " & objMP3Info.HeaderPosition) .Add("VBRScale= " & objMP3Info.VBRScale)
Select Case objMP3Info.MPEGVersion Case MP3Info.Monotic.Multimedia.MP3.MPEGVersionEnum.MPEG1 .Add("MPEGType= " & "MPEG 1") Case MP3Info.Monotic.Multimedia.MP3.MPEGVersionEnum.MPEG2 .Add("MPEGType= " & "MPEG 2") Case MP3Info.Monotic.Multimedia.MP3.MPEGVersionEnum.MPEG25 .Add("MPEGType= " & "MPEG 2.5") End Select
Select Case objMP3Info.Layer Case MP3Info.Monotic.Multimedia.MP3.LayerEnum.LayerI .Add("Layer= " & "Layer I") Case MP3Info.Monotic.Multimedia.MP3.LayerEnum.LayerII .Add("Layer= " & "Layer II") Case MP3Info.Monotic.Multimedia.MP3.LayerEnum.LayerIII .Add("Layer= " & "Layer III") End Select
Select Case objMP3Info.Protection Case MP3Info.Monotic.Multimedia.MP3.ProtectionEnum.None .Add("Protection= " & "None") Case MP3Info.Monotic.Multimedia.MP3.ProtectionEnum.CRC .Add("Protection= " & "By CRC") End Select
Select Case objMP3Info.ChannelMode Case MP3Info.Monotic.Multimedia.MP3.ChannelModeEnum.DualChannel .Add("ChannelMode= " & "Dual Channel") Case MP3Info.Monotic.Multimedia.MP3.ChannelModeEnum.JointStereo .Add("ChannelMode= " & "Joint Stereo") Case MP3Info.Monotic.Multimedia.MP3.ChannelModeEnum.SingleChannel .Add("ChannelMode= " & "Single Channel") Case MP3Info.Monotic.Multimedia.MP3.ChannelModeEnum.Stereo .Add("ChannelMode= " & "Stereo") End Select
Select Case objMP3Info.Emphasis Case MP3Info.Monotic.Multimedia.MP3.EmphasisEnum.CCIT .Add("Emphasis= " & "CCIT") Case MP3Info.Monotic.Multimedia.MP3.EmphasisEnum.MS5015 .Add("Emphasis= " & "50/15 ms") Case MP3Info.Monotic.Multimedia.MP3.EmphasisEnum.None .Add("Emphasis= " & "None") End Select
Select Case objMP3Info.Encoding Case MP3Info.Monotic.Multimedia.MP3.EncodingEnum.CBR .Add("Encoding= " & "CBR") Case MP3Info.Monotic.Multimedia.MP3.EncodingEnum.VBR .Add("Encoding= " & "VBR") End Select
' Add the ID3v1 tag information to a listview If (objMP3Info.ID3v1Tag.TagAvailable) Then .Add("ID3 Title= " & objMP3Info.ID3v1Tag.Title) '[...]() End If
' Update the tag 'objMP3Info.ID3v1Tag.Title = "Another title" 'objMP3Info.ID3v1Tag.Update()
End With End Sub
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
Hi I need some very basic instruction in how to use this dll in an Excel macro. For instance where do I place the dll to begin with (that is which directory?) I'm using excel 2002. Let's say I want to get the bitrate, size, and encoding(stereo or joint stereo etc) for a single file.
Thanks, Steve
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
You'll need ta compile the DLL with a STRONG NAME and den will need to smack a COM wrapper on it and den register it on your machine using REGSRV23.EXE, a Windows provided executable.
After ya dun all that, the DLL will be available in the VBE as an add-able reference.
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
I got a problem with the Property Bitrate() As Integer. On some MP3 files I have an issue in computing the Bitrate. Stepping with the debugger, I found for those files: Encoding=CBR, MPEGVersion=MPEG25, Layer=Reserved, and then no IF branch inside the block:
If (Me.Encoding = EncodingEnum.CBR) Then ... Else
is executed, resulting in a Bitrate set to 0 and consequently an overflow error while computing the track length (in seconds) as:
Return Math.Round(f_intAudioSize / Me.Bitrate * 8, 0)
I read somewhere that computing the track length may be difficult for VBR files, but this one is CBR. I read also that ID3 tags should expose the "duration" of the track (solving also inaccuracies eventually coming in this computation on VBR files), but ID3v1Tag property of your class doesn't expose such "duration" (maybe a ID3 v2 feature...).
Can you help me, please?
Thank you in advance, AV
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
I had the same problem, but solved it by changing the length property like this:
Public ReadOnly Property Length() As Integer Get If Me.Bitrate = 0 Or Me.Bitrate = -1 Then Return 0 Else Return Math.Round(f_intAudioSize / Me.Bitrate * 8, 0) End If End Get End Property Then I made an errorhandling wehn length = 0.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
|
I use the same code as you provide in this page (above), but objMP3Info.ID3v1Tag.Update() is missing in your dll. Infact I checked ID3v1Tag and it doesn't contain any Update(), how can it works? Please upload the correct version of these downloads (files). This will correct this problem.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
|
Hi Thommy, great class it works very fine. I've written a small mp3Manager wich scans for my mp3 files and stores them, with path and header info to a database. If I scan my HDD it works very well, but if I scan an CD then I got an exception in your class at Opening the File.
The CD's files aren't damaged, I've already checked this and in Winamp it's also possible to read all the information. I don't know why this execption is fired.
Greetz RF
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
I think I have an answer for you. It looks like the file is being opened for read/write access, but when they are on a CD this is not possible. I was having the same issue, but through code I copied the file to the hard drive, changed the file attributes from readonly to normal and I was able to access it with no problems. I then deleted the "temp" file once i was done with it.
It's not the best solution, but it works.
Just thought I would throw my 2 cents in.
Thanks!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
RF: Your mp3 manager is exactly what I'm looking to build in .NET 2005. I'm very new to the whole .NET thing, have been reading, but I know I'm not quite up to the task at hand, and was wondering if you might post your code.
Thanks for your time.
Fred
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I ran into the same problem when I tried to do this in a web site also.
I didn't want to give right access to the folder the files were in so I changed:
MP3FileStream = New FileStream(MP3FilePath, FileMode.Open) to MP3FileStream = New FileStream(MP3FilePath, FileMode.Open, FileAccess.Read)
and it now works.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hello.
I try your new classes and I get an error message: "Add is not a member of System.windows.forms.listview"
Sub monotic()
With ListView1 Dim objMP3Info As New Monotic.Multimedia.MP3.MP3Info
''' Set the filename property objMP3Info.Filename = "c:\test.mp3"
''' Add the header information to a listview .Add("Filesize").SubItems.Add(objMP3Info.Filesize & " Byte") .Add("SamplingRateFrequency").SubItems.Add(objMP3Info.SamplingRateFrequency & " Hz"
..... ENd sub
What kind of listview do you use ? I get the same eror message with a textbox or a listbox.
I am using VB.NET 7.1.3088.
Regards from France. Didier.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I'm using the "normal" ListView from System.Windows.Forms namespace. If you want to populate some textbox, try the following:
TextBox1.Text = "Filesize: " & objMP3Info.Filesize [...]
Thommy
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
Your classes are very useful.
Anyhow, I cannot use "Listview1.add command: I get the error Add is not a member of System.windows.forms.listview.
I have uninstalled -reinstalled my legaly purchased vb.net "initiation version" software and I get the same error.
May be the add property is not included in the initiation version for listviews !.
I use commands like "tagartiste = objMP3Info.ID3v1Tag.Artist" and it works.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
| |