Renaming music files via AutoHotkey and metadata

As a sequel to my previous post, I’ve always wanted to use the metadata embedded in a file (which is usually correct on most downloaded music) to fix the filenames of an arbitrary number of files. Well, I took a little time today and figured it out.

First, I prefer working with context-sensitive methods via Windows Explorer, although there’s no reason you couldn’t build a wrapper that edited the filename of every mp3 on your hard drive. So I look for Windows Explorer, and listen to a keyboard shortcut or extra mouse button press. It loops through the filenames of the items on the clipboard and performs an action on each one.

#IfWinActive ahk_class CabinetWClass
	;; rename the selected files to Author - Album - # - Title
	XButton1::
	^+m::
		;; get the selected files by copying them from the clipboard
		Copy()
		Send {Shift Up}
	
		;; parse through these files
		Loop parse, clipboard, `n, `r
		{
			RenameMp3WithAttributes(A_LoopField)
		}
	Return
#IfWinActive

The magic happens in a function that I named RenameMp3WithAttributes and placed in the file I use as a function library.

RenameMp3WithAttributes(input)
{
	;; splits a path into a filename and directory
	SplitPath, input, FileName, FileDir, FileExt
	
	objShell := ComObjCreate("Shell.Application") 
	objFolder := objShell.Namespace(FileDir . "\") 
	objFilename := objFolder.Parsename(FileName)

	;; We want: Artist - Album - # - Title 
	;; That is: 13 - 14 - 26 - 21
	artist := objFolder.GetDetailsOf(objFilename, 13)
	album := objFolder.GetDetailsOf(objFilename, 14) 
	tracknum := objFolder.GetDetailsOf(objFilename, 26) 
	title := objFolder.GetDetailsOf(objFilename, 21) 
	
	;; construct a file name based on the available info
	newname := ""
	if StrLen(artist) > 0
	{
		newname .= artist
	}
	if StrLen(tracknum) > 0
	{
		if StrLen(newname) > 0
		{
			newname .= " - "
		}
		newname .= tracknum
	}
	if StrLen(album) > 0
	{
		if StrLen(newname) > 0
		{
			newname .= " - "
		}
		newname .= album
	}
	if StrLen(title) > 0
	{
		if StrLen(newname) > 0
		{
			newname .= " - "
		}
		newname .= title
	}

	;; only rename the target file if we have a new name
	;; (this prevents non-music files from having their names killed)
	if StrLen(newname) > 0
	{
		FileMove %input%, %FileDir%\%newname%.%FileExt%
	}
}

Now, I realize that the attribute numbers are basically pulled from nowhere – I did some research, and these are the first couple hundred values. I imagine the image-based ones would be the other particularly useful ones.


/* Windows attribute values
0: filename
1: file size
2: file type
3: date modified
4: date created
5: date accessed
6: attributes (read only, hidden archive, compressed)
7: offline status
8: offline availability
9: percieved type (audio, ???)
10: owner (COMPUTER\User Name)
11: kind (music, picture, etc)
12: date taken
13: ***contributing artists***
14: ***album***
15: year
16: genre
17: conductors 
18: tags
19: rating (Unrated, 1 Star, 2 Stars, ..., 5 Stars)
20: authors
21: ***title***
22: subject
23: categories
24: comments
25: copyright
26: ***#***
27: length
28: bit rate
29: protected
30: camera model
31: dimensions
32: camera maker
33: company
34: file description
35: program name
36: duration
37: is online
38: is recurring
39: location
40: optional attendee address
41: optional attendees
42: organizer address
43: organizer name
44: reminder time
45: required attendee addresses
46: required attendees
47: resources
48: meeting status
49: free/busy status
50: total size (of the hard drive?)
51: account name
52: task status
53: computer (computer name on which file resides)
54: anniversary
55: assistant's name
56: assistant's phone
57: birthday
58: business address
59: business city
60: business country/region
61: business p.o. box
62: business postal code
63: business state or province
64: business street
65: business fax
66: business home page
67: business phone
68: callback number
69: car phone
70: children
71: company main phone
72: department
73: email address
74: email 2
75: email 3
76: email list
77: email display name
78: file as
79: first name
80: full name
81: gender
82: given name
83: hobbies
84: home address
85: home city
86: home country/region
87: home p.o. box
88: home postal code
89: home state or province
90: home street
91: home fax
92: home phone
93: IM addresses
94: initials
95: job title
96: label
97: last name
98: mailing address
99: middle name
100: cell phone
101: nickname
102: office location
103: other address
104: other city
105: other country/region
106: other p.o. box
107: other postal code
108: other state or province
109: other street
110: pager
111: personal title
112: city
113: country/region
114: p.o. box
115: postal code
116: state or province
117: street
118: primary email
119: primary phone
120: profession
121: spouse/partner
122: suffix
123: tty/ttd phone
124: telex
125: webpage
126: content status
127: content type
128: date acquired
129: date archived
130: date completed
131: device category
132: connected
133: discovery method
134: friendly name
135: local computer
136: manufacturer
137: model
138: paired
139: classification
140: status
141: status
142: client id
143: contributors
144: content created
145: date printed
146: date last saved
147: division
148: document id
149: pages
150: slides
151: total editing time
152: word count
153: due date
154: end date
155: file count
156: file extension
157: filename
158: file version
159: flag color
160: flag status
161: space free (on the drive)
162: sharing type
163: bit depth
164: horizontal resolution (dpi)
165: width (px)
166: vertical resolution (dpi)
167: height (px)
168: importance
169: is attachment
170: is deleted
171: encryption status
172: has flag
173: is completed
174: incomplete
175: read status
176: shared
177: creators
178: date
179: folder name
180: folder path
181: folder ( folder name (parent path) )
182: participants
183: path
184: by location
185: type (ex: VLC media file (.mp3))
186: contact names
187: entry type
188: language
189: date visited
190: description
191: link status
192: link target
193: url
194: media created
195: date released
196: encoded by
197: episode number
198: producers
199: publisher
200: season number
201: subtitle
202: user web url
203: writers
204: attachments
205: bcc addresses
206: bcc
207: cc addresses
208: cc
209: conversation id
210: date received
*/

Andrew Guyton
http://www.disavian.net/

Leave a Reply