Enumerating Folder Structures with VBScript to Extract ID3 Information from MP3 Files


Okay, so this has nothing to do with federated infrastructure.  However, occasionally, I come across something worth preserving so I wanted to make sure I wrote it down.  The hat tip here really goes to Antonin Foller (http://www.motobit.com/tips/detpg_list-id3-tags-script/), but I did make some modifications to his code to make it easier for my specific situation.


The goal of this script is to extract the ID3 meta data from my entire MP3 collection so that I can use it to ensure consistency (of artist name and genre mostly) as well as use the information for generating playlists that follow certain prescriptions like those used in formatted radio (ensuring that the same artist isn't played twice in the same hour, etc.).  The script contains two sub-procedures and a very generic main procedure.


To run the script, I use the command prompt (cscript) and redirect the output to a txt file. 


Sub ListID3TagsFS(Root)
Dim SubFolder, File
 
'*** enumerate all files In the folder
For Each File In Root.Files
 Select Case LCase(Right(File.Name, 4))
       Case ".mp3"
  ListID3TagsFile File
 End Select
Next


'*** process all subfolders
For Each SubFolder In Root.SubFolders
 ListID3TagsFS SubFolder
Next


End Sub


Sub ListID3TagsFile(File)
'*** Get id3 object To change data
Dim id3
Set id3 = CreateObject("CDDBControl.CddbID3Tag")


'*** load id3 data from a file, read only
id3.LoadFromFile File.Path, True
 
'*** print some of id3 tags
WScript.Echo File.Path & chr(9) & id3.LeadArtist & Chr(9) & id3.Title & Chr(9) & id3.Album & Chr(9) & id3.Year & Chr(9) & id3.Genre


End Sub


'******************************************************************
'*** Main Procedure                                             ***
'******************************************************************

'*** Get Arguments

set oArgs = wscript.arguments
sFolder = oArgs(0)


'*** get FileSystemObject To enumerate files
Dim oFS
Set oFS = CreateObject("Scripting.FileSystemObject")


'*** call ListID3TagsFS Function with a folder object
ListID3TagsFS oFS.GetFolder(sFolder)


The output of the script is a single text file (tab delimited) that contains the entire MP3 collection.  This can be edited in Excel or Access for consistency and used as an input file for the following script that will individually update each MP3 file (note however, that Excel will add quotes to some of these fields if saved as a text file - tab delimited.  I found it better to actually copy the entire spreadsheet and paste it into notepad to get a "clean" text file for input.  Once the output file has been cleaned up, the following script can be used to read the information from the output file back into the individual ID3 tags.


On Error Resume Next
set oArgs = wscript.arguments
sFolder = oArgs(0)


'*** get FileSystemObject To enumerate files
Dim oFS
Set oFS = CreateObject("Scripting.FileSystemObject")
Set iFile = oFS.OpenTextFile(sFolder, 1)


Do Until iFile.AtEndofStream


 LineA = iFile.Readline
 Values = Split(LineA, Chr(9))
 EditID3Tags Values(0), Values(1), Values(2), Values(3)
Loop


Sub EditID3Tags(File,Artist,SongTitle,Album)
'*** Get id3 object To change data
Dim id3
Set id3 = CreateObject("CDDBControl.CddbID3Tag")


'*** load id3 data from a file, read only
id3.LoadFromFile File, True
 
'*** Save the id3 tags
id3.Album = Album
id3.Title = SongTitle
id3.LeadArtist = Artist


id3.SaveToFile File
If Err <> 0 Then
 wScript.Echo "Error: " & Artist & ": " & SongTitle & "[" & Album & "]"
 Err.Clear
Else
 wscript.echo "Completed " & Artist & ": " & SongTitle & "[" & Album & "]"
End If


End Sub

Comments (4)

  1. JkO says:

    The last line in the first script should read:

    ListID3TagsFS oFS.GetFolder(sFolder)

    Also, the output of this script appears to be a never-ending series of pop-up windows, not a tab-delimited text file.

    Anthony: Thanks,  I will correct the typo.  The reason you’re getting the never ending series of pop-ups is that you need to run the script in command shell mode.  For example, at the command prompt type: cscript GetID3Tags.vbs c:albums

  2. DieselDragon says:

    Hi Anthony!

    The above code is pretty much what I’m searching for as I’m trying to write a script to insert ID2/ID3 tag information (Mainly Artist, Album and Track names) into my own rather badly managed MP3 collection. However, it would appear that the CDDBControl.CddbID3Tag object doesn’t exist on a standard Windows installation (At least not on XP Pro SP2) and I’d like this script to be as portable and driver/library free as possible. Could you possibly suggest a native Windows Explorer or Media Player object that I could use insted?

    Failing that, basic instructions and/or a link to the CDDBControl.CddbID3Tag component would at least solve my initial problem and get my MP3 library sorted out! 🙂

    On another note: I also write scripts mainly for CScript out of personal preferance. Although most of my code is designed to be compatable with WScript as well, I’ve come up with the following code to switch hosts if a specific one is required:

    ‘This code starts the script in CScript, then terminates the current instance of WScript:

    If Not UCase(Right(WScript.FullName, 11))="CSCRIPT.EXE" Then

     Dim objShell

     Set objShell = CreateObject("WScript.Shell")

     objShell.Run "CSCRIPT.EXE " & Chr(34) & WScript.ScriptFullName & Chr(34)

     Set objShell = Nothing

     WScript.Quit

    End If

    Farewell, and thanks for the tutorial! 🙂

    +++ DieselDragon +++

  3. DieselDragon says:

    Hi again!

    I managed to source a copy of the CDDBControl.CddbID3Tag component (As CDDBCONTROL.DLL) from a drivers website, and managed to get a test script working fine with reading ID3 data from an MP3 file…But for some reason, after changing data and calling the SaveToFile method the changes aren’t committed to the file at all. 🙁

    I have full read/access to the MP3 file in question (Located in My Documents) and it’s not set to read only…So is there a "commit" command (Like in SQL) that I ought to be calling, or is there something else awry?

    Apologies for the double-comment, but there’s no way to edit this into my previous post. 😐

    Farewell, and thanks again… 🙂

    +++ DieselDragon +++

  4. Dommer says:

    I believe the second attribute in the id3.LoadFromFile method controls whether or not you are opening the file as readonly. Try setting this to False or 0

    ANTHONW SAYS: Dommer may be right, although I’ve not had any problems with the read-only flag set to true.  I have seen one problem with the existing code fairly consistently.  Whenever my file name, or any of the fields I am trying to modify, contains a comma, my script errs out.  Interestingly enough, however, the error handling doesn’t kick in until the next iteration.  I haven’t had a chance to run it through a script debugger to see where it might be having the problem.  My guess is that the CDDB control isn’t very robust and is treating the comma as a separator.  Of course, the documentation seems hard to come by, so I cannot tell if there is anyway to escape the comma that is acceptable to the dll.

Skip to main content