iTunes lyrics to desktop - guinea pigs pls

Hello & please be gentle! :wink:

Below is a script I wrote to put the lyrics of the currently playing track in iTunes onto your desktop using GeekTool. http://homepage.mac.com/bonkers/macnn/ss-lyrics.jpg

I’d appreciate any feedback/suggestion/critiques.

Thanks, Chris

(* this is to get the script to automatically run when iTunes is open & write the currently playing track's lyrics to a file *)

(* to randomize the track list *)
on unsortList(lst)
	try
		if lst's class is not list then error "Not a list." number -1704
		script k
			property l : lst's items
		end script
		set len to count k's l
		set lastNum to random number from 1 to 9.999999999971E+12 -- calling osax only once improves overall performance approx 40%
		repeat with idx1 from 1 to len
			set lastNum to (lastNum * 67128023) mod 9.999999999971E+12
			set idx2 to (lastNum mod len) + 1
			set tmp to k's l's item idx1
			set k's l's item idx1 to (get k's l's item idx2)
			set k's l's item idx2 to tmp
		end repeat
		return k's l
	on error eMsg number eNum
		error "Can't unsortList: " & eMsg number eNum
	end try
end unsortList
--
(* This subroutine gets the lyrics from iTunes of the current track and writes them to a text file. *)
on lyrinfo()
	
	tell application "iTunes"
		set ct to current track
		set {nom, lyr, art} to {"", "", ""}
		tell ct
			try
				if artist is "" then
					set art to (" by " & "unknown artist")
				else
					set art to (" by " & artist)
				end if
				if lyrics is "" then
					set lyr to return & return & "missing lyrics" -- this adds two line returns after song title & artist
				else
					set lyr to return & return & lyrics -- this adds two line returns after song title & artist
				end if
				if name is missing value then
					set nom to "unknown track title"
				else
					set nom to name
				end if
			end try
		end tell
		-- basic info (feel free to format your own message!)
		set the clipboard to ("\"" & nom & "\"" & art & lyr)
	end tell
	
	-- let's create a log file that is constantly updated with the current track's lyrics
	set Filename to "ct_lyrics" --Name of the hidden file (remove the period to make visible)
	set this_data to (the clipboard) & return as string --Any text here
	set target_file to ((path to desktop folder as Unicode text) & Filename) --You can eliminate "Filename" as a variable and type the filename as part of the path (if you wish) but you need a full path
	set append_data to false --Set this to false if you want to overwrite, true if you want to add text to an existing file
	
	try --This part writes the file
		set the target_file to the target_file as text
		set the open_target_file to open for access file target_file with write permission
		if append_data is false then set eof of the open_target_file to 0
		write this_data to the open_target_file starting at eof
		close access the open_target_file
	on error
		try
			close access file target_file
		end try
	end try
	
end lyrinfo
--
(* This subroutine monitors user modification of iTunes playback. It will check track name & player position every 5 seconds. If a user skips a track or skips forward/backward in a track it will rerun this subroutine & get new lyrics (if track has been changed) *)
on alter_playbk()
	
	tell application "iTunes"
		set tme to (duration of current track)
		set pos to player position
		set remain to tme - pos
		set rpt_num to round ((remain - 10) / 5)
		set xyz to 0
		log rpt_num
		repeat rpt_num times
			set y to name of current track
			set z to player position
			delay 5
			if name of current track is not equal to y then
				--display dialog "Track has been changed"
				my lyrinfo()
				set xyz to 1
				exit repeat
			else
				set pos_buff to {z + 5, z + 6, z + 7, z + 8, z + 9}
				if {player position} is not in pos_buff then
					--display dialog "Leave the slider alone"
					set xyz to 1
					exit repeat
				end if
			end if
		end repeat
		if xyz is 1 then --this is to rerun the subroutine if normal playback has been modified
			my alter_playbk()
		end if
	end tell
	
end alter_playbk
--
global trk_list

on idle --change to "on idle" when saving as an application
	
	tell application "iTunes"
		activate
		display dialog "Pick a playlist & let's start rockin'!" buttons ¬
			{"Master Library", "Let me pick!"} default button 2
		if the button returned of the result is "Master Library" then
			tell application "iTunes"
				set lst to get index of every track of library playlist 1
				set trk_list to my unsortList(lst) --> randomize trkList here
				
				repeat until trk_list is {}
					set limit to length of trk_list
					set dummyList to {}
					set rmvd_lst to {}
					--
					play track (item 1 of trk_list) of library playlist 1
					--
					my lyrinfo()
					--
					my alter_playbk()
					--
					if index of current track is not (item 1 of trk_list) then
						set y to index of current track
						set x to item 1 of trk_list
						repeat with i from x to y
							copy i to end of rmvd_lst
						end repeat
						--log lst
						repeat with i from 1 to limit
							if {trk_list's item i} is not in rmvd_lst then ¬
								set dummyList's end to trk_list's item i
						end repeat
						set trk_list to dummyList
						--log trk_list
					else
						set trk_list to rest of trk_list
					end if
					--					
					set tme to (duration of current track)
					set pos to player position
					set remain to tme - pos
					delay remain - 1 --> wait track length in second + 1  for loop repeat
				end repeat
			end tell
		else
			tell application "iTunes"
				set list_pl to name of every playlist
			end tell
			try
				choose from list list_pl
				set plChoice to the contents of the result as text
				set lst to get index of every track of playlist (plChoice)
				set trk_list to my unsortList(lst) --> randomize trkList here
				
				repeat until trk_list is {}
					set limit to length of trk_list
					set dummyList to {}
					set rmvd_lst to {}
					--
					play track (item 1 of trk_list) of playlist (plChoice)
					--
					my lyrinfo()
					--
					my alter_playbk()
					--
					if index of current track is not (item 1 of trk_list) then
						set y to index of current track
						set x to item 1 of trk_list
						repeat with i from x to y
							copy i to end of rmvd_lst
						end repeat
						--log lst
						repeat with i from 1 to limit
							if {trk_list's item i} is not in rmvd_lst then ¬
								set dummyList's end to trk_list's item i
						end repeat
						set trk_list to dummyList
						--log trk_list
					else
						set trk_list to rest of trk_list
					end if
					--
					set tme to (duration of current track)
					set pos to player position
					set remain to tme - pos
					delay remain - 1 --> wait remaining time of track + 1  for loop repeat (this could be substituted with just 10 sec)
				end repeat
			end try
		end if
		quit
		quit me
	end tell
	
end idle --change to "on idle" when saving as an application


(* things to work on: 
how to interrupt script? 
--
commands for GeekTool
window #1: tr "\r" "\n" < ~/Desktop/ct_lyrics | head -n 55
window #2: tr "\r" "\n" < ~/Desktop/ct_lyrics | sed -n '56,$p'
*)

Hi, Chris.

I haven’t been able to study your script fully yet, but there’s a potentially fatal problem in the lyrinfo() handler. The word ‘lyrics’ compiles as a variable name, whereas presumably it’s meant to be an ‘iTunes’ keyword. There’s no ‘lyrics’ property in either iTunes 3.0.1 (Jaguar) or iTunes 4.7.1 (Tiger). If your script requires a later version of the app., or if that’s what GeekTool does, you’ll have to mention the fact in the covering literature and also (ideally) at the appropriate point(s) in the script.

Presumably it works for you though, so good luck when it’s released. :slight_smile:

You are correct. I think the ability to store lyrics was introduced in iTunes 5.x so this script will not work on earlier versions. I will include this requirement in the notes.

It’s a moot point, but how would I be able to change the word ‘lyrics’ from a variable name to an ‘iTunes’ keyword? (for my own edjumacation… ;-))

Requirements for my script to run successfully.

iTunes 5.x
GeekTool

Can someone test this script so I can know if it will work on other people’s systems. Thanks.

Cheers

hi, i’d like to try out your script but could you please clarify what exactly i need to do or type to use geektool to achieve this? thanks.

at the end of the applescript, you will see the following…

I use two windows to display the lyrics because I have a 17" monitor & would like to accomodate the longest lyrics in my collection. The first command displays the first 55 lines of lyrics & the second command displays lines 56 to the end of the lyrics.

in GeekTool
a) add a new entry “dsktp lyrics1”
b) select “shell” from the dropdown menu
c) select the “command” button & type in the unix command above w/ refresh a 10 secs
d) repeat steps a-c for “dsktp lyrics2”

Hope this helps. Cheers

gotcha. so i just have to put the script in itunes script folder?

Sorry, I guess I haven’t been clear.

Save the script as a stay-open application & then double-click to run the script.