Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

ID3 Tag Lib


  • Please log in to reply
23 replies to this topic
Krogdor
  • Members
  • 1391 posts
  • Last active: Jun 08 2011 05:31 AM
  • Joined: 18 Apr 2008
Here is a very simple wrapper to CDDBControl.dll
It will read and write ID3v2 tags to any mp3 file.
Not that it is currently very lightly tested—use with caution.

CDDBControl.dll can be found here.

Sean's COM wrapper is required, and COM_Init() should be called before using any of these functions. Also, before using it for the first time, run (through AHK or Win+r or whatever else) "RegSvr32.exe CDDBControl.dll"
This only needs to be done once.

Documentation/Syntax can be found above each of the whopping 5 functions in the code, and here are some examples:
COM_Init() ;should be called before using any of these functions

; Ex. 1:
ID := ID3_Open("Song.mp3") ;Open "Song.mp3" for reading/editing
ID3_Write(ID,"Artist","MyArtist") ;write MyArtist to Artist tag
ID3_Write(ID,"LeadArtist","MyArtist") ;same as above
ID3_Write(ID,"Movie","MyMovie") ;write MyMovie to Movie tag
ID3_Write(ID,"Year","MyYear") ;write MyYear to Year tag
ID3_Write(ID,"Album","MyAlbum") ;write MyAlbum to Album tag
ID3_Write(ID,"CopyrightHolder","MyCopyrightHolder") ;...you get the point
ID3_Write(ID,"Title","MyTitle")
ID3_Write(ID,"Genre","MyGenre")
ID3_Write(ID,"Comments","MyComments")
ID3_Write(ID,"CopyrightYear","MyCopyrightYear")
ID3_Write(ID,"BeatsPerMinute","MyBeatsPerMinute")
ID3_Write(ID,"ISRC","MyISRC")
ID3_Write(ID,"Label","MyLabel")
ID3_Write(ID,"PartOfSet","MyPartOfSet")
ID3_Write(ID,"TrackPosition","MyTrack#")
ID3_Write(ID,"Track#","MyTrack#")  ;same as above
ID3_Write(ID,"TrackNum","MyTrack#")  ;same as above
ID3_Write(ID,"TrackNumber","MyTrack#")   ;same as above
ID3_Write(ID,"FileID","MyFileID")
ID3_Save(ID,"Song.mp3")

;Ex. 2:
ID := ID3_Open("Song.mp3") ;Open "Song.mp3" for reading/editing
ID3_Write(ID) ;clears all tags
ID3_Save(ID,"Song.mp3")

;Ex. 3:
;For this example, Artist=A, Title=T, Year=Y,Album=AL,Genre=G
ID := ID3_Open("Song.mp3") ;Open "Song.mp3" for reading/editing
MsgBox % ID3_Read(ID) ;will show T/A/AL/Y/G
MsgBox % ID3_Read(ID,"Artist&Genre&Year","&") ;will show A&G&Y 
ID3_Close(ID) ;no need to save, since no editing was done

Code:
;ID3_Open(FileName) : opens %FileName% for reading/editing
ID3_Open(FileName) {
  If !(FileExist(FileName))
    Return 0
  tag := COM_CreateObject("CDDBControlAOL.CddbID3Tag")
  COM_Invoke(tag,"LoadFromFile",FileName,0)
  Return tag
}

;ID_Write(FileID, [Tag , NewInfo ] ) : Writes to the Tag
;FileID is the return from ID3_Open
;Tag should be :  Artist,Track#,TrackNum,TrackNumber,LeadArtist,Title,Album,Genre,Year,Comments,CopyrightYear,CopyrightHolder
;,Label,BeatsPerMinute,PartOfSet,TrackPosition,FileID,ISRC, or Movie
;NewInfo is the information to write into the ID3 Tag specified
;Leave Tag and NewInfo blank to clear all tags.
ID3_Write(FileID,Tag="",NewInfo="") {
  If !FileID
    Return 0
  Tag := RegExReplace(Tag,"i)(?<!Lead)(Artist)","LeadArtist")
  Tag := RegExReplace(Tag,"i)TrackNum|Track#|TrackNumber","TrackPosition")
  AllowedList:="LeadArtist,Title,Album,Genre,Year,Comments,CopyrightYear,CopyrightHolder,Label,BeatsPerMinute,PartOfSet,TrackPosition,FileID,ISRC,Movie"
  If (!Tag && !NewInfo) {
    Loop, Parse, AllowedList, `,
      COM_Invoke(FileID,A_LoopField,"")
    Return 1
  }
  If Tag not in %AllowedList%
    Return 0
  COM_Invoke(FileID,Tag,NewInfo)
  Return 1
}


;ID3_Read(FileID, [ Tag , Delim ] ) : Reads info from specified tag(s)
;FileID is the return from ID3_Open()
;Tag should be a %Delim% delimited list of the tags that you want read
;See ID3_Write() for a list of allowed Tag names.
;If Tag is blank, will return Title/Artist/Album/Year/Genre
;Returns: %Delim% delimited list of the information
;, in the same order they are in the Tag parameter
ID3_Read(FileID,Tag="",Delim="/") {
  If (!Delim || !FileID)
    Return 0
  If (!Tag)
    Tag := "Title/LeadArtist/Album/Year/Genre", Delim:= "/"
  Tag := RegExReplace(Tag,"i)(?<!Lead)(Artist)","LeadArtist")
  Tag := RegExReplace(Tag,"i)TrackNum|Track#|TrackNumber","TrackPosition")
  AllowedList:="LeadArtist,Title,Album,Genre,Year,Comments,CopyrightYear,CopyrightHolder,Label,BeatsPerMinute,PartOfSet,TrackPosition,FileID,ISRC,Movie"
  Loop, Parse, Tag, %Delim%
    If A_LoopField not in %AllowedList%
      Return 0
    Else
      Info .= (A_Index = 1 ? "" : Delim) COM_Invoke(FileID,A_LoopField)
  Return Info
}

;ID3_Save(FileID, FileName) : Saves changes made to the tags
;FileID is the return from ID3_Open()
;FileName is the file to save the new tags to,
;in most cases the same file used in ID3_Open()
ID3_Save(FileID,FileName) {
  If (!FileID || !FileName)
    Return 0
  COM_Invoke(FileID, "SaveToFile", FileName)
  COM_Release(FileID)
  Return 1
}

;ID3_Close(FileID) : Closes/Releases the file
;FileID is the return from ID3_Open()
;Use this if you do not want to save the changes,
;but are done working with it.
ID3_Close(FileID) {
  If !FileID
    Return 0
  COM_Release(FileID)
  Return 1
}

Anyway, I'm sure there will be bugs I haven't noticed in my few minutes of testing. Please post any issues and I'll get to them as soon as I can.

Edit: Fixed a problem with the RegEx's for making some of the tag names more user friendly.

ahklerner
  • Members
  • 1386 posts
  • Last active: Oct 08 2014 10:29 AM
  • Joined: 26 Jun 2006
good job....this has been asked many time for a way to read / edit id3 tags.
Posted Image
ʞɔпɟ əɥʇ ʇɐɥʍ

heresy
  • Members
  • 291 posts
  • Last active: Sep 26 2008 10:47 PM
  • Joined: 11 Mar 2008
nice you got it finally. i never think of COM method to do this. Thanks for sharing
Easy WinAPI - Dive into Windows API World
Benchmark your AutoHotkey skills at PlayAHK.com

tkoi
  • Members
  • 56 posts
  • Last active: Feb 25 2011 02:32 AM
  • Joined: 26 Jun 2008
I keep getting this error message:

---------------------------
COM Error Notification
---------------------------
Function Name: "LoadFromFile"
ERROR: The COM Object may not be a valid one!
()

Will Continue?
---------------------------
Yes No
---------------------------

Seems to happen at this line in the ID3_Open() func:
COM_Invoke(tag,"LoadFromFile",FileName,0)


Superfraggle
  • Members
  • 1019 posts
  • Last active: Sep 25 2011 01:06 AM
  • Joined: 02 Nov 2004
I had that on a file, I opened the file up in winamp, and resaved the tag and it was ok, but would be nice to have some custom error handling.
Steve F AKA Superfraggle

http://r.yuwie.com/superfraggle

tkoi
  • Members
  • 56 posts
  • Last active: Feb 25 2011 02:32 AM
  • Joined: 26 Jun 2008
I figured it out. Somehow I had a different CDDBControl.dll than what was needed. :oops:
Works great now!

Krogdor
  • Members
  • 1391 posts
  • Last active: Jun 08 2011 05:31 AM
  • Joined: 18 Apr 2008

I had that on a file, I opened the file up in winamp, and resaved the tag and it was ok, but would be nice to have some custom error handling.


:?:

A bit confused. You had what on a file? What happened to cause you to need to open the file in WinAmp and resave the tag?

Superfraggle
  • Members
  • 1019 posts
  • Last active: Sep 25 2011 01:06 AM
  • Joined: 02 Nov 2004
I was receiving the same error message when trying to read a tag from an MP3 File.

I checked the file actually had a tag by opening it up in winamp, and it seemed to be ok.

The error then no longer occured for this file, my guess is the tag was imcomplete/currupt.
Steve F AKA Superfraggle

http://r.yuwie.com/superfraggle

Krogdor
  • Members
  • 1391 posts
  • Last active: Jun 08 2011 05:31 AM
  • Joined: 18 Apr 2008
Ah, okay. I haven't seen any error like that so far, so if you encounter this again perhaps you could send me the file and I could see if I could reproduce it?

Superfraggle
  • Members
  • 1019 posts
  • Last active: Sep 25 2011 01:06 AM
  • Joined: 02 Nov 2004
I had a copy of the original file before I resaved the tag.

https://ahknet.autoh.../Faulty Tag.zip

I have only encountered it once on this file so far so not a major problem, I might scan my whole collection later and see if I have any more affected.
Steve F AKA Superfraggle

http://r.yuwie.com/superfraggle

oliver.lipkau
  • Members
  • 97 posts
  • Last active: Jul 29 2015 07:12 AM
  • Joined: 17 Sep 2006
Hi There.

I am using your script to tag my music...

The DLL file didn't work on vista. Is this normal?

And I would like to know how to set the Disc# in the tags... there was no example for this in your script.

Thanks you.

Krogdor
  • Members
  • 1391 posts
  • Last active: Jun 08 2011 05:31 AM
  • Joined: 18 Apr 2008
The DLL file works fine on my system, which is Vista Home Premium with Service Pack 1 (32-bit).

As for Disc#... Perhaps you want TrackNumber?

@ Superfraggle:

Wow, somehow I didn't notice that post until now x_x I'll take a look at that file when I get a chance.

oliver.lipkau
  • Members
  • 97 posts
  • Last active: Jul 29 2015 07:12 AM
  • Joined: 17 Sep 2006

As for Disc#... Perhaps you want TrackNumber?

I really want Disc#, as in:
Posted Image
Posted Image


I couldn't find any tag to edit the "Album Artist" neighter.

Superfraggle
  • Members
  • 1019 posts
  • Last active: Sep 25 2011 01:06 AM
  • Joined: 02 Nov 2004
Disc number is stored in the "PartOfSet" tag.
Steve F AKA Superfraggle

http://r.yuwie.com/superfraggle

Krogdor
  • Members
  • 1391 posts
  • Last active: Jun 08 2011 05:31 AM
  • Joined: 18 Apr 2008
Aha. Thanks, Superfraggle. I just listed the values that were given with the .dll—I don't know what quite a few of them are.

Also Album Artist might be stored in "LeadArtist". I'm not sure, though.

Edit: Tested that file you put up, Superfraggle. Same error here. I guess the .dll isn't good at handling corrupted files, since you said it was fixed after you had WinAmp write over it.