Anything better?

Is there anything I can do to improve this script?

try
	set site to do shell script "curl [url=http://www.parrygripp.com/]http://www.parrygripp.com/"[/url]
on error e number m
	display dialog e buttons {"OK"} default button 1
	error number -128
end try
set T to AppleScript's text item delimiters
set AppleScript's text item delimiters to "<span class=\"smallestext\"><a href=\"http://"
set N to text items 2 thru end of site
set AppleScript's text item delimiters to "\"></a><br />"
set songs to {}
repeat with i in N
	set thesong to text item 1 of i
	set songs to songs & thesong
end repeat
tell application "QuickTime Player" to close every document saving yes
repeat with i in songs
	set thesong to "http://" & en(i) as string
	tell application "QuickTime Player"
		if thesong is not "http://www.parrygripp.com/wimpy/none" then
			open URL thesong
			try
				repeat
					if current time of front document is not duration of front document then
						delay 1
					else
						close front document
						exit repeat
					end if
				end repeat
			on error e
				if e is not "QuickTime Player got an error: Can't get document 1. Invalid index." then display dialog e buttons {"OK"} default button 1
				quit
				error number -128
			end try
		end if
	end tell
end repeat
on en(URLs)
	return do shell script "/usr/bin/python -c '" & ¬
		"from sys import argv; " & ¬
		"from urllib import quote; " & ¬
		"print quote(unicode(argv[1], \"utf8\"))' " & quoted form of URLs
end en

Here is a update. :rolleyes: It adds “round” around :smiley: the “current time of front document” and “duration of front document” so it is never fails. Sometimes it does fail to go to the next song, so this fixes it:

try
	set site to do shell script "curl [url=http://www.parrygripp.com/]http://www.parrygripp.com/"[/url]
on error e number m
	display dialog e buttons {"OK"} default button 1
	error number -128
end try
set T to AppleScript's text item delimiters
set AppleScript's text item delimiters to "<span class=\"smallestext\"><a href=\"http://"
set N to text items 2 thru end of site
set AppleScript's text item delimiters to "\"></a><br />"
set songs to {}
repeat with i in N
	set thesong to text item 1 of i
	set songs to songs & thesong
end repeat
tell application "QuickTime Player" to close every document saving yes
repeat with i in songs
	set thesong to "http://" & en(i) as string
	tell application "QuickTime Player"
		if thesong is not "http://www.parrygripp.com/wimpy/none" then
			open URL thesong
			try
				repeat
					if (round (current time of front document as integer)) is not (round (duration of front document as integer)) then
						delay 1
					else
						close front document
						exit repeat
					end if
				end repeat
			on error e
				if e is not "QuickTime Player got an error: Can't get document 1. Invalid index." then display dialog e buttons {"OK"} default button 1
				quit
				error number -128
			end try
		end if
	end tell
end repeat
on en(URLs)
	return do shell script "/usr/bin/python -c '" & ¬
		"from sys import argv; " & ¬
		"from urllib import quote; " & ¬
		"print quote(unicode(argv[1], \"utf8\"))' " & quoted form of URLs
end en

Is there a way to save the number song that it’s on, and when you open it back up the player starts playing on song (the saved number)? I tried with User Defaults confusing me. HELP! :lol:

Hi, Dylan.

You could perhaps improve your post by saying what the script’s supposed to do. That would save would-be helpers a few minutes’ work. :slight_smile:

I think the wait-out repeat while the songs are playing might benefit from using the document’s playing property (a boolean value):

.
	open URL thesong
	try
		tell front document
			repeat until playing
				delay 1
			end repeat
			repeat while playing
				delay 1
			end repeat
			close
		end tell
	on error e
	.

The script’s quite fun to use, in a perverse kind of way… :wink:

. though it palls quite quickly. :confused:

I did something like that. I didn’t like that if I paused the music it would go on to the next song, I would rather have it end the song and then move on.

Sorry. :stuck_out_tongue: The script is supposed to go thru the songs on the players of Parry Gripp’s website and stream them into Quicktime with “open URL.” The only thing wrong is that some songs are unavialible and are a path of “http://www.parrygripp.com/wimpy/[b]none[/b]” causing an error in this, in that, in this… horrible. That’s solved by

if thesong is not "http://www.parrygripp.com/wimpy/none" then

Hope that helps.

I see. And your rounding is because songs sometimes stop a few centiseconds away from the finishing line, failing to trigger the loop exit condition. How about this?

	.
	open URL thesong
	try
		tell front document
			set finishingLine to duration - 0.1 -- Allow up to, say, 0.1 seconds' shortfall at the end.
			repeat while (current time < finishingLine) or (playing)
				delay 1
			end repeat
			close
		end tell
	on error e
	.

Your going to need a “delay 2” because the song needs to load. It skipped a few songs.

open URL thesong
			delay 2
			try
				tell front document
					set finishingLine to duration - 0.1 -- Allow up to, say, 0.1 seconds' shortfall at the end.
					repeat while (current time < finishingLine) or (playing)
						delay 1
					end repeat
					close
				end tell
			on error e

Is there a way to save the song that you left off and then start back on that song?

It’s better to use a controlled delay (assuming there is only one open document at the same time)

open URL thesong
			repeat until exists document 1
				delay 0.2
			end repeat
.

What about?

tell front document to pause
			repeat until exists document 1
				delay 0.2
			end repeat
			tell front document to play

It seems to be against the rules.

logically there is no front document in the first line :wink:

And I took the pause line away and kept the play line because auto-play might be disabled.

Still, how do I make my script start where I left off?

The detail depends on how and where you intend to “leave off”. In the middle of a number? Immediately afterwards?

One approach might be to make songs a persistent property of the script. As you finish with each URL, replace it in the list with a missing value. When the script starts up, if songs contains any text values (ie. URLs), start playing at the first one. Otherwise, if the list’s all missing values or contains nothing, create a new URL list as currently and start playing from the beginning.

You can index specific classes of item in a list the same way that you can index specific element types in text, so the amount of list manipulation can be kept to a minimum.

property songs : {}

if ((count songs each text) is 0) then
	-- Fetch and process the URLs and set 'songs' to the resulting list.
end if

-- Use the specific 'text' rather than the generic 'item' to reference URLs in the list but ignore missing values.
repeat with i from 1 to (count songs each text)
	set thesong to text i of songs
	set thesong to "http://" & en(thesong)
	tell application "QuickTime Player"
		
		-- Open and play a song.
		
		-- When it's finished:
		close front document
		set text i of songs to missing value
		
	end tell
end repeat

Your script did not work for me (10.6.3) ??

So I went for a different approach…

It uses the built in command line “afplay” which allows you to play mp3 file headless.

This script is a very rough draft…

So far…
It will download the mp3 file( into the “songFilePath”) and play it. while checking what file is playing, and will not move on to the next curl
download until it gets an error from the checking. This negates me having to check track lengths.
( I have not hit the bad paths you where getting yet, mainly because I only tested with 3 tracks.
more than 3 at this time would drive me more crazy than I already am :smiley: )

If you stop the script while a track is playing, the last track name will be stored in the “lastTrack” property.
When you run the script again. It will check if “lastTrack” is empty. If it is empty the tracks start from scratch,
but if not it will play the last track.

There is a lot to still add to this script to the controls, like stop, pause/play, and the logic that goes with that, but the general idea works.

I have only tested this on one Mac, so not sure how well it will work on others yet… :slight_smile:

try
	set site to do shell script "curl [url=http://www.parrygripp.com/]http://www.parrygripp.com/"[/url]
on error e number m
	display dialog e buttons {"OK"} default button 1
	error number -128
end try
set T to AppleScript's text item delimiters
set AppleScript's text item delimiters to "<span class=\"smallestext\"><a href=\"http://"
set N to text items 2 thru end of site
set AppleScript's text item delimiters to "\"></a><br />"
set songs to {}
repeat with i in N
	set thesong to text item 1 of i
	set songs to songs & thesong
end repeat
--set counter to 0 --for testing
set songFilePath to "/Users/UserName/Downloads/media-DownLoad"
property lastTrack : ""
repeat with i in songs
	
	set thesong to "http://" & en(i) as string
	
	set bname to do shell script "basename " & (quoted form of thesong)
	if lastTrack is "" then
		my playSong(thesong, bname, songFilePath)
	else if lastTrack is bname then
		my playSong(thesong, bname, songFilePath)
	end if
	
end repeat
on playSong(thesong, bname, songFilePath) --add counter  --for testing
	--set counter to counter + 1  --for testing
	--if counter ≤ 2 then --for testing
	set g to do shell script "cd " & songFilePath & ";curl " & (quoted form of thesong) & " -O "
	do shell script "cd " & songFilePath & ";afplay " & (quoted form of bname) & " > /dev/null 2>&1 &"
	log bname
	set The_app to "afplay"
	set the_afplayName to bname
	repeat until the_afplayName is not equal to bname
		try
			set the_idle to do shell script "ps auxw |grep -i " & The_app & "|grep -v grep"
			set the_afplayName to do shell script "ps auxw |grep -i " & The_app & " |grep -v grep | awk '{print $12}'"
			set lastTrack to the_afplayName
		on error
			set lastTrack to ""
			exit repeat
		end try
		log the_afplayName
		delay 3
	end repeat
	--else --for testing
	--	exit repeat --for testing
	--end if  --for testing
end playSong
on en(URLs)
	return do shell script "/usr/bin/python -c '" & ¬
		"from sys import argv; " & ¬
		"from urllib import quote; " & ¬
		"print quote(unicode(argv[1], \"utf8\"))' " & quoted form of URLs
end en


Nigel, I only have this that doesn’t work well, it can’t “get document 1 of app “Quicktime”” :frowning:

property songs : {}

if ((count songs each text) is 0) then
	try
		set site to do shell script "curl [url=http://www.parrygripp.com/]http://www.parrygripp.com/"[/url]
	on error e number m
		display dialog e buttons {"OK"} default button 1
		error number -128
	end try
	set T to AppleScript's text item delimiters
	set AppleScript's text item delimiters to "<span class=\"smallestext\"><a href=\"http://"
	set N to text items 2 thru end of site
	set AppleScript's text item delimiters to "\"></a><br />"
	set songs to {}
	repeat with i in N
		set thesong to text item 1 of i
		set songs to songs & thesong
	end repeat
end if

-- Use the specific 'text' rather than the generic 'item' to reference URLs in the list but ignore missing values.
tell application "QuickTime Player" to close every document saving yes
repeat with i from 1 to (count songs each text)
	set thesong to text i of songs
	set thesong to "http://" & en(thesong)
	tell application "QuickTime Player"
		if thesong is not "http://www.parrygripp.com/wimpy/none" then
			open URL thesong
			repeat until exists document 1
				delay 0.2
			end repeat
			tell front document to play
			try
				tell front document
					if (round (current time of front document as integer)) is not (round (duration of front document as integer)) then
						delay 1
					else
						close front document
						set text i of songs to missing value
					end if
				end tell
			on error e
				if e is not "QuickTime Player got an error: Can't get document 1. Invalid index." then display dialog e buttons {"OK"} default button 1
				quit
				error number -128
			end try
		end if
	end tell
end repeat

on en(URLs)
	return do shell script "/usr/bin/python -c '" & ¬
		"from sys import argv; " & ¬
		"from urllib import quote; " & ¬
		"print quote(unicode(argv[1], \"utf8\"))' " & quoted form of URLs
end en

Mark, I don’t know why yours doesn’t work, but I think that something is wrong with your Quicktime Player.

It might be its QT X?

Did you try the one in my post.

I don’t know why you’re getting that particular error. The error I get from it is “Can’t make time of document 1 of document 1 of application "QuickTime Player" into type integer.” This is because of the round line, which has a number of issues, numbers 3 and 4 below being relevant to the error I’m getting:

  1. In rare end-of-song cases where one time is just under n.5 seconds and the other just over, the two figures will round to different integers and the else statement won’t be executed.

  2. The rounds are superfluous with as integer (as is getting the document’s duration every second).

  3. The of front documents are inside a tell front document statement, resulting in document 1 of document 1 references.

  4. The references are passed “as is” to round, which doesn’t understand them. They need to be resolved to the actual numbers first.

With regard to my suggestion last night, I must apologise for forgetting that when you set text i of a list to missing value, the erstwhile text (i + 1) becomes text i and is skipped next time round the repeat when i itself becomes i + 1. In this script, the reference must always be to text 1 of the list. :rolleyes:

The following works for me in OS 10.6.3 with QT Player X. It has to be saved as an application or run in AppleScript Editor for the songs property to persist. “Leaving off” is achieved by closing the Player window, quitting the Player, or stopping the script. (Command-“.” while the script’s frontmost.)

property songs : {}

if ((count songs each text) is 0) then
	try
		set site to do shell script "curl [url=http://www.parrygripp.com/]http://www.parrygripp.com/"[/url]
	on error e number m
		display dialog e buttons {"OK"} default button 1
		error number -128
	end try
	set T to AppleScript's text item delimiters
	set AppleScript's text item delimiters to "<span class=\"smallestext\"><a href=\"http://"
	set N to text items 2 thru end of site
	set AppleScript's text item delimiters to "\"></a><br />"
	set songs to {}
	repeat with i in N
		set thesong to text item 1 of i
		if (thesong is not "[url=http://www.parrygripp.com/wimpy/none]www.parrygripp.com/wimpy/none[/url]") then set end of songs to thesong
	end repeat
	set AppleScript's text item delimiters to T
end if

tell application "QuickTime Player" to close every document saving yes
-- Use the specific 'text' rather than the generic 'item' to reference URLs in the list but ignore missing values.
repeat (count songs each text) times
	set thesong to "http://" & en(text 1 of songs)
	tell application "QuickTime Player"
		open URL thesong
		try
			tell front document
				repeat until (playing)
					delay 1
				end repeat
				set finishingLine to duration - 0.1
				repeat while (current time comes before finishingLine) or (playing)
					delay 1
				end repeat
				close
			end tell
			set text 1 of songs to missing value
		on error e number errNum
			if (errNum is not in {-128, -1719}) then display dialog e buttons {"OK"} default button 1
			quit
			error number -128
		end try
	end tell
end repeat

on en(URLs)
	return do shell script "/usr/bin/python -c '" & ¬
		"from sys import argv; " & ¬
		"from urllib import quote; " & ¬
		"print quote(unicode(argv[1], \"utf8\"))' " & quoted form of URLs
end en

I haven’t looked at Mark’s script yet…

Thanks Nigel,

That works very well, now I can see what the intent was a bit better.
I’ve added the property currentTime, Which so far, will start the song playing from the current Time it was stopped.

How does that work for you.

property songs : {}
property currentTime : ""
if ((count songs each text) is 0) then
	try
		set site to do shell script "curl [url=http://www.parrygripp.com/]http://www.parrygripp.com/"[/url]
	on error e number m
		display dialog e buttons {"OK"} default button 1
		error number -128
	end try
	set T to AppleScript's text item delimiters
	set AppleScript's text item delimiters to "<span class=\"smallestext\"><a href=\"http://"
	set N to text items 2 thru end of site
	set AppleScript's text item delimiters to "\"></a><br />"
	set songs to {}
	repeat with i in N
		set thesong to text item 1 of i
		if (thesong is not "[url=http://www.parrygripp.com/wimpy/none]www.parrygripp.com/wimpy/none[/url]") then set end of songs to thesong
	end repeat
	set AppleScript's text item delimiters to T
end if

tell application "QuickTime Player" to close every document saving yes
-- Use the specific 'text' rather than the generic 'item' to reference URLs in the list but ignore missing values.
repeat (count songs each text) times
	set thesong to "http://" & en(text 1 of songs)
	tell application "QuickTime Player"
		open URL thesong
		
		try
			tell front document
				
				repeat until (playing)
					set current time to currentTime
					
					delay 1
				end repeat
				set finishingLine to duration - 0.1
				
				repeat while (current time comes before finishingLine) or (playing)
					set currentTime to (current time)
					
					delay 1
				end repeat
				set currentTime to ""
				close
			end tell
			set text 1 of songs to missing value
		on error e number errNum
			if (errNum is not in {-128, -1719}) then display dialog e buttons {"OK"} default button 1
			quit
			error number -128
		end try
	end tell
end repeat

on en(URLs)
	return do shell script "/usr/bin/python -c '" & ¬
		"from sys import argv; " & ¬
		"from urllib import quote; " & ¬
		"print quote(unicode(argv[1], \"utf8\"))' " & quoted form of URLs
end en