Auto Tagging Album Covers

GO TO ADMIN PANEL > ADD-ONS AND INSTALL VERTIFORO SIDEBAR TO SEE FORUMS AND SIDEBAR

sobman

New member
Joined
Mar 12, 2008
Messages
26
Points
0
I have all my album covers named, Folder.jpg (or folder.jpg if it matters)

Are there any scripts that i can run that will auto tag all the music files with the image? that will save a lot of time on my 300+ albums...

thanks
 

S2_Mac

New member
Joined
Oct 24, 2006
Messages
4,878
Points
0
Location
About 3 feet in front of the monitor
Don't understand what you've got/what you want.... every piece of album art is named "Folder.jpg"? How can anything tell them apart then? Each piece of art, or its containing folder, should be named for an album before a script could even begin to help out.

...or do you want to apply the one image -- Folder.jpg -- to every album you've got? That's a fairly straightforward task, and there's a script at Doug's that does that.

Anyway...I'm not aware of any scripts that apply stored image files to tracks/albums (which seems kinda weird; it's a very practical request). And it might be awhile until somebody does cook up something like that -- iTunes 7.7 Applescript seems to have changed how it handles art. (And there's so much to fix in 7.7 maybe Apple will change it back...maybe 7.7 is just a very bad dream... ;-)
 

sobman

New member
Joined
Mar 12, 2008
Messages
26
Points
0
I have all my music organized very well, here's what it looks like


My Documents\My Music\Tech N9ne\[2006] Everready The Religion [CD1]\

01 Enter Everready (B.L.E.S.T.).mp3
02 Riot Maker (Enjoy) (Ft. Skatterman, Snug Brim).mp3
03 No Can Do (Ft. Big Krizz Kaliko).mp3
04 Welcome To The Midwest (Ft. Big Krizz Kaliko).mp3
05 Bout Ta' Bubble.mp3
06 It's What You Thinkin'.mp3
07 Night And Day (T.E.C.H. Radio).mp3
08 Jellysickle (Ft. E-40).mp3
09 Caribou Lou.mp3
10 Hood Connection, Strange Commercial.mp3
11 My Wife, My #####, My Girl.mp3
12 Flash (Your Descent).mp3
13 Come Gangsta.mp3
14 The Melancholy Maze (My World Intro).mp3
15 My World (Ft. Brotha Lynch Hung, Dalima).mp3
16 Running Out Of Time (ROOT).mp3
17 The Rain (Welcome Back, Party Hard) (Ft. Alyia, Reign Yates).mp3
18 ####'em Girl (Ft. Big Krizz Kaliko, Kutt Calhoun).mp3
19 The Beast.mp3
20 This Is Me (Goodbye).mp3
folder.jpg

and so on for each folder

i go by

/Main Dir/Artist/Album/Music [Track # Track Name]

now, folder.jpg is the album cover. I never really knew how to tag the mp3's with the cover, so i never did, and when they are on my ipod they are coverless
 

sobman

New member
Joined
Mar 12, 2008
Messages
26
Points
0
bump


is there a place i can go to get someone to make me this or something?

is it possible?
 

S2_Mac

New member
Joined
Oct 24, 2006
Messages
4,878
Points
0
Location
About 3 feet in front of the monitor
Well, I've made progress -- I've found an Applescript way to take a jpeg file and get iTunes to accept it as album art (!!). But it's not pretty.....

(Note: you should not use this code -- it's just a proof of concept. It only handles one iTunes track at a time. To test it: select an artless track in iTunes, then activate the script; you will be prompted to locate a jpeg file. QuickTime Player will then open the file and export it as a jpeg file to the same directory (with "MOD" prepended to file name); iTunes will then happily import the new file into the album art space of the selected track.)
Code:
on prependToLastPathItem(in_path, str_to_prepend)
	set {TID, text item delimiters} to {text item delimiters, ":"}
	set path_list to text items of in_path
	set str to str_to_prepend & last item of path_list
	set str to trimFileName(str, 20)
	set last item of path_list to str
	set out_path to path_list as string
	set text item delimiters to TID
	return out_path
end prependToLastPathItem

on trimFileName(file_name, num_chars_to_keep)
	set {TID, text item delimiters} to {text item delimiters, "."}
	set file_name_list to text items of file_name
	set str to text 1 through num_chars_to_keep of item -2 of file_name_list
	set item -2 of file_name_list to str
	set txt to file_name_list as string
	set text item delimiters to TID
	return txt
end trimFileName

-- get an alias to art source:
set the_file to choose file with prompt "Select a JPEG file:" of type {"public.jpeg"}
-- make a new name for the exported file:
copy the_file as string to the_mod_file
set the_mod_file to prependToLastPathItem(the_mod_file, "MOD")
--log the_mod_file
--return

-- I'm guessin' that iTunes wants to see a jpeg inside a PICT wrapper
-- like the one generated by CGImageCreateWithJPEGDataProvider? 
-- The trick is how to get something to provide that wrapper...
-- looks like QTPlayer can do that (no "Pro" version required)!
tell application "QuickTime Player"
	open the_file
	export document 1 as picture to the_mod_file
	close document 1 saving no
end tell

-- the exported file provides a "canonical" PICT wrapper? i.e. ignore first 512 bytes
set filePtr to open for access the_mod_file
set the_image to read filePtr from 513 as JPEG picture
close access filePtr
--return

tell application "iTunes"
	set the_track to item 1 of selection
	--with timeout of 30000 seconds
	if not (exists artworks of the_track) then
		set data of artwork 1 of the_track to the_image
	end if
	--end timeout
	
end tell
I'm guessing that iTunes wants to see, for instance, a jpeg image inside a canonical PICT wrapper, like that provided by (again, a guess) CGImageCreateWithJPEGDataProvider()... so this script uses QTPlayer to export the desired jpeg file to a new file; the new file does indeed have a wrapper that iTunes can live with (after the leading 512 bytes are stripped).

Haven't quite achieved the grail, but closing in...

(So, does anyone know a quicker/better way to put a jpeg into a PICT wrapper? Preferably one that doesn't require writing another file?)
 

sobman

New member
Joined
Mar 12, 2008
Messages
26
Points
0
Any updates man? You seem to be the only guy that does scripts around here... That's kinda lame
 

Billin808

New member
Joined
Aug 14, 2008
Messages
1
Points
0
Location
Maui
Hi Sobman - I did a lot of research before tagging and organizing my 20,000 track collection, complete with artwork and in a uniform style across the library. My opinion is the best way to tag artwork is outside of iTunes, since it doesn't store the jpg in the ID3 tag but instead in a separate index. I tried the popular tagging apps in Mac, the best being iEatBrainz - which still wasn't great. If you happen to be running Windows on your Mac, I can't recommend "Tag and Rename" highly enough. If you are missing details, you can automatically fill them from Amazon while at the same time specifying how you would like the information formatted.

Your collection already looks very nicely organized by directory structure and filename - if your ID3 tags are not as organized, T&R can fill the tags automatically based on the filename PLUS if you already have the cover jpgs (which you do), you can drag and drop the cover and it will apply the cover to every track in the album. No need to update iTunes, it will automatically use the artwork the next time the track is played or next time you use cover flow.

I realize this isn't an AppleScript solution, or even a Mac solution, but in trying pretty much every app out there, nothing can touch the control or flexibility that T&R provides. Of course the best part is the artwork and metadata stay with the file where ever it goes, instead of being held prisoner by the iTunes library. I can't wait for something this good to come to OSX. Good luck!
 

S2_Mac

New member
Joined
Oct 24, 2006
Messages
4,878
Points
0
Location
About 3 feet in front of the monitor
My opinion is the best way to tag artwork is outside of iTunes, since it doesn't store the jpg in the ID3 tag but instead in a separate index.

Not sure where you got this idea....for file types that are built to handle embedded graphics, iTunes embeds the graphic (such as mp3, AAC). Easy enough to verify this -- embed an image and watch the file grow by the size of the image file (less header bytes).

The cache files you see being created are just there for iTunes' convenience; optimized and cached to make Cover Flow work faster, etc. (just like the optimized image files iTunes caches when photos are synced onto an iPod).
 

S2_Mac

New member
Joined
Oct 24, 2006
Messages
4,878
Points
0
Location
About 3 feet in front of the monitor
You mean the "Store" feature to retrieve art? It takes the tag data from a track, and checks it against the Store's inventory of art; if it finds a "match" (not 100% accurate), it DLs the image and links it to the track through the "Album Art" folder hierarchy (but does not embed the image in the file); so the art is there for the track in iTunes, but the track doesn't really have the art. (Very similar to what Windows does -- the art lives in the track's folder, but not in the track.)

In terms of what you want (from your OP), the sole stumbling block is that I can't find a way for iTunes to identify tracks by location. I would like to be able to tell iTunes:
get some track whose location is anAliasToAFile
but no joy; iTunes will report tracks "whose album is "xyz" or "whose time is 123", but it just doesn't like looking for a location. Bummer.

(The way I envision it, this thing should be an applet that lives in the Dock or on the desktop; you drop a folder onto it and the music files get put into a list and the image file gets converted into usable art; then the list of paths gets fed to iTunes, which matches them up to tracks and embeds the art. That last part is what's not working ;-)

The workaround is p'bly just to read the xml file and build a hash of persistent IDs and file paths, then go from there...but I'd really like to find a way to make iTunes give up this info via AS....

It's real do-able to start with a track from within iTunes (for instance, check out this recent script for locating and embedding art in the playing track), but your task seems to start in the Finder....
 

S2_Mac

New member
Joined
Oct 24, 2006
Messages
4,878
Points
0
Location
About 3 feet in front of the monitor
Finally got around to it...

So here's script that does what the OP asked for. Works OK with iTunes 7.x under 10.3.9 and iTunes 8 under 10.4.x; totally untested in Leopard.

If you're coming from a Windows machine and have "folder.jpg" files in each music-containing folder; and if you've added files to iTunes with the "copy files to iTunes Music folder when adding to library" pref turned off; and if you want to embed those "folder.jpg" files into the music files -- then this is for you ;-)

Scripters might enjoy the perl routine -- feed in a list of POSIX paths, and get back a list of iTunes Database IDs (since iTunes can't/won't set a_track to some track whose location is some_file_path).

I'm preparing a release for a more all-purpose version for folks who are in the process of migrating from Win/WMP -- drop folders and/or onto the app and the files will be added to iTunes and any folder.jpg images will be added to appropriate tracks. The app will work no matter how the iTunes Prefs are set.

Save the script as an application; no stay open, no startup screen. Drop folders onto it, or double-click it.
Code:
(*
	Add Folder Art to Tracks
	=--=--=--=--=--=--=--=--=--=--=--=
	
	This script is released under the MIT license.
	
*)


property validFileExts : {"mp3", "aif", "aiff", "aac", "m4a", "m4p"}
property all_folders : {}
property IDs_delim : ASCII character of 127
global path_to_xml

on run
	set dropped_items to choose folder with prompt "Select one or more music folders to add to iTunes:" with multiple selections allowed
	open dropped_items
end run

on open dropped_items
	set folders_list to {}
	tell application "iTunes" to set cur_version to the version as string
	tell application "Finder"
		repeat with i from 1 to count of dropped_items
			if class of item (item i of dropped_items) is folder then
				set end of folders_list to item i of dropped_items
			end if
		end repeat
	end tell
	
	if folders_list is {} then
		display dialog "Please drop folders onto this app." buttons {"Cancel"} default button 1
		return
	end if
	repeat with i from 1 to count folders_list
		set end of all_folders to item i of folders_list
		walk_folders(item i of folders_list)
	end repeat
	
	set path_to_xml to (escape_spaces(text 3 through -3 of (do shell script "defaults read com.apple.iapps iTunesRecentDatabasePaths"))) as string
	set skipped_paths to {}
	repeat with this_folder in all_folders
		tell application "Finder"
			set dropped_items to (every document file of this_folder)
		end tell
		repeat with i from 1 to count of dropped_items
			set item i of dropped_items to ((item i of dropped_items) as alias)
		end repeat

		set file_list to {}
		set art_file to ""
		repeat with i from 1 to count of dropped_items
			set fpath to (item i of dropped_items) as string
			set fname to my last_path_item((item i of dropped_items) as string, ":")
			if (fname is "folder.jpg") then -- get art filepath as alias
				if art_file is "" then set art_file to item i of dropped_items
			else
				set cur_file_ext to my get_file_extension(fname)
				if cur_file_ext is in validFileExts then -- get music filepaths as POSIX
					set end of file_list to POSIX path of (item i of dropped_items)
				end if
			end if
		end repeat
		
		set processed_paths to {}
		if art_file is not "" then
			set array_list to ("\"") & list_to_text(file_list, "\",\"") & ("\"")
			set track_IDs to my nested_list_from_lines(my get_listing(array_list, IDs_delim), IDs_delim)
			-- ...track_IDs is a list of 2-item lists: a dropped track's ID, that track's filepath as POSIX
			
			set the_image to null
			if cur_version < "8" then
				copy art_file as string to mod_art_file
				set mod_art_file to prepend_to_file_name(mod_art_file, "MOD", ":")
				tell application "QuickTime Player"
					open art_file
					export document 1 as picture to mod_art_file using default settings with replacing
					close document 1 saving no
				end tell
				set the_image to read (file mod_art_file) from 513 as picture
			else
				set the_image to read art_file as JPEG picture -- works in both 10.3.9 and 10.4.11
			end if
			tell application "iTunes"
				repeat with i from 1 to count of track_IDs
					set the_track to (some track of library playlist 1 whose database ID is ((item 1 of item i of track_IDs) as integer))
					if not (exists artworks of the_track) then
						set data of artwork 1 of the_track to the_image
					end if
					set end of processed_paths to item 2 of item i of track_IDs
				end repeat
			end tell
		end if
		
		repeat with a_path in file_list
			if not (a_path is in processed_paths) then
				set end of skipped_paths to a_path
			end if
		end repeat
	end repeat
	
	-- do something with performance info
	set plural to "s"
	set wplural to "s were"
	if (count of processed_paths) is 1 then set plural to ""
	if (count of skipped_paths) is 1 then set plural to " was"
	tell application "iTunes"
		display dialog ("Artwork was embedded in " & (count of processed_paths) & " iTunes track" & plural & "; " & (count of skipped_paths) & " non-iTunes file" & wplural & " skipped.") as string buttons {"Thanx"} default button 1 with icon 1 with title "Add Folder Art to Tracks"
	end tell
end open

-- --------------------
-- the functions
-- --------------------
on walk_folders(in_folder)
	tell application "Finder"
		set f to (every folder of in_folder)
		repeat with i from 1 to count of f
			set item i of f to ((item i of f) as alias)
		end repeat
	end tell
	if f is not {} then
		repeat with i from 1 to count of f
			set end of all_folders to (item i of f)
			walk_folders(item i of f)
		end repeat
	end if
end walk_folders

on escape_spaces(t)
	set {TID, text item delimiters} to {text item delimiters, " "}
	set {txt_items, text item delimiters} to {every text item of t, "\\ "}
	set {t, text item delimiters} to {txt_items as string, TID}
	return t
end escape_spaces

on last_path_item(p, delim)
	if p is "" then return p
	set TID to text item delimiters
	set text item delimiters to delim
	set p to last text item of (p as string)
	set text item delimiters to TID
	return p
end last_path_item

on nested_list_from_lines(t, delim)
	set out_list to {}
	if t is "" then return out_list
	repeat with str in paragraphs of t
		set end of out_list to text_to_list(str, delim)
	end repeat
	return out_list
end nested_list_from_lines

on text_to_list(t, delim)
	set TID to AppleScript's text item delimiters
	try
		set AppleScript's text item delimiters to {delim}
		set out_list to every text item of t
	on error errStr number errNum
		set AppleScript's text item delimiters to TID
		error errStr number errNum
	end try
	set AppleScript's text item delimiters to TID
	return out_list
end text_to_list

on list_to_text(in_list, delim)
	set TID to AppleScript's text item delimiters
	try
		set AppleScript's text item delimiters to {delim}
		set t to in_list as text
	on error errStr number errNum
		set AppleScript's text item delimiters to TID
		error errStr number errNum
	end try
	set AppleScript's text item delimiters to TID
	return t
end list_to_text

on get_file_extension(f)
	set TID to AppleScript's text item delimiters
	set AppleScript's text item delimiters to "."
	set t to last text item of f
	set AppleScript's text item delimiters to TID
	return t
end get_file_extension

on prepend_to_file_name(in_path, str_to_prepend, delim)
	set {TID, text item delimiters} to {text item delimiters, delim}
	set path_list to text items of in_path
	set str to str_to_prepend & last item of path_list
	set str to trim_file_name(str, 20)
	set last item of path_list to str
	set str to path_list as string
	set text item delimiters to TID
	return str
end prepend_to_file_name

on trim_file_name(file_name, num_chars_to_keep)
	set {TID, text item delimiters} to {text item delimiters, "."}
	set file_name_list to text items of file_name
	set diff to length of item -2 of file_name_list
	if diff > num_chars_to_keep then set diff to num_chars_to_keep - diff
	set str to text 1 through diff of item -2 of file_name_list
	set item -2 of file_name_list to str
	set str to file_name_list as string
	set text item delimiters to TID
	return str
end trim_file_name

to get_listing(path_list, delim)
	set the_cmd to "perl -e 'local $/ = undef;my @path_list=(" & path_list & ");my $s=<>;my @out=();my $delim=\"" & delim & "\";
while ($s=~m:<key>(\\d+)</key>.*?<dict>.*?<key>Location</key><string>file\\://(.*?)</string>.*?</dict>:sg ) {
  ($id,$path)=($1,$2);$path=~s/&/&/sg; $path=~s/&#3B;/;/sg;$path=~s/^localhost//sg;
  $path=~s/%([a-fA-F0-9][a-fA-F0-9])/chr(hex($1))/sge;
  $h{$path} = $id;
}
  @out = map {\"$h{$_}$delim$_\\n\"} @path_list;
print \"@out\";' " & path_to_xml
	return do shell script the_cmd
end get_listing
 

sobman

New member
Joined
Mar 12, 2008
Messages
26
Points
0
So... I have no idea how to run this... Can someone give me a quick step by step? That would be good.
 

sobman

New member
Joined
Mar 12, 2008
Messages
26
Points
0
I'm getting the impression this is for mac-only users. lol. Sucks to be PC right about now.
 

S2_Mac

New member
Joined
Oct 24, 2006
Messages
4,878
Points
0
Location
About 3 feet in front of the monitor
Here's a tip for the future, sobman -- next time you post in a forum named AppleScripts for iTunes (Mac), and you get responses that feature Macintosh lingo and links and really big clues like "If you happen to be running Windows on your Mac", and someone sticks with a project for half a year to deliver a working solution to your problem, and you finally realize that you're running the wrong platform for everything that's been discussed and implemented....try to come up with something better than "lol. Sucks to be PC right about now."
 

sobman

New member
Joined
Mar 12, 2008
Messages
26
Points
0
I didn't know that scripts were mac only. I think a mod saw it and moved it to the appropriate section.

And dude, i know you spent a good amount of time on this, and just because i cant use it doesn't mean it's not going to help lots of other people.
 
Last edited:

bubbleboy

New member
Joined
Mar 8, 2009
Messages
2
Points
0
There aren't any scripts that I know of.. however I have a large music collection and wanted to embed album art in the files. This is my first post so I don't know if naming the program is considered spam or not! Suffice to say it worked absolute wonders, hardly getting anything wrong at all and tagging a good 85% of my collection, and allowing me to do the rest very easily manually! I'll check back and post a link if it's ok!
 
Top