DMCA-legal playlist generator?

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

wormyrocks

New member
Joined
Mar 8, 2009
Messages
20
Points
0
I need to write a script that creates a playlist that is legal by the DMCA for use on Internet radio. This requires that I have no more than two songs in a row by the same artist. How can I code an applescript that will check if, in a given playlist, there are no more than 2 songs in a row by the same artist, and if so, re-shuffle the playlist?
Thanks in advance!
 

wormyrocks

New member
Joined
Mar 8, 2009
Messages
20
Points
0
New question (if someone would reply >.>) How do I make a song in a playlist play until the song finishes, and then pause?
Also, how can I write the name of a playlist to a text file?
Thanks again.
 

S2_Mac

New member
Joined
Oct 24, 2006
Messages
4,878
Points
0
Location
About 3 feet in front of the monitor
Well, nuts....since you need to write the script <g>, I was going to point you to the official AppleScript Language Guide, but it's been offline since the 12th.

That I know of, there's no (easy, built-in) way to make iTunes "shuffle" the tracks in a playlist; you'd have to do something like:
1) put the playlist's tracks in a list, then check to see if there's 3-or-more-in-a-row; if so,
2) re-order the tracks until there's no 3-or-more-in-a-row, then
3) clear the playlist and re-fill it with the re-ordered tracks

The logic to check for 3-or-more-in-a-row is fairly simple; here's an example that disables excess tracks (so that they won't play; a human can choose to manually re-order them and then enable the tracks):
Code:
tell application "iTunes"
	set pl to view of front browser window
	set enabled of every track of pl to true
	set trax to tracks of pl
	
	set prev_artist to ""
	set hits to 1
	repeat with trak in trax
		set cur_artist to artist of trak
		if cur_artist is prev_artist then
			set hits to hits + 1
		else
			set prev_artist to cur_artist
			set hits to 1
		end if
		if hits > 2 then set enabled of trak to false
	end repeat
	return
end tell
Your second question is a bit tricky. iTunes ApleScript doesn't signal when a track has finished playing (maybe Growl could pick it up?), so a script would have to constantly monitor iTunes to detect a track change. This would be done in an on idle handler, checking every second or so. However, it would be terribly imprecise in timing, and would likely "miss" track changes by some small-but-irritating amount of time (less than a second, maybe, but still audible).

Another approach would be to detect the current playlist (see code above), get a list of its tracks, and then disable all tracks; this will defintely ensure that nothing else plays after the current track, and then an on idle handler could detect that playback has stopped (there will be an error trying to get the current track), and then determine what the next track would be and start playing it.

For your third question, here's the nutshell version of writing to a file:
Code:
set some_data to "some data"
set some_file to choose file -- or any means of getting an alias or file path
try
	set file_handle to open for access some_file with write permission
	--set eof of file_handle to 0 -- uncomment this line to overwrite the file
	write some_data to file_handle starting at eof
	close access file_handle
on error
	close access file_handle
end try
 

wormyrocks

New member
Joined
Mar 8, 2009
Messages
20
Points
0
Thanks!
I think I've got the file writing figured out. Just FYI, this is for the Casual Collective Radio (casualcollective. com/ [remove the space]), of which I am a DJ. I've written my first real Applescript - a program which formats a playlist for easy use in a text file. If anyone's interested, they can download it here. dl.getdropbox. com/u/585860/PFormat11.zip (remove the space)

Oh, and there in fact is a simple way to tell iTunes to auto-shuffle the playlist:
Code:
set shuffle to on
set shuffle to off
Sorry about the lack of links - n00bs aren't allowed to post 'em. :p
 

S2_Mac

New member
Joined
Oct 24, 2006
Messages
4,878
Points
0
Location
About 3 feet in front of the monitor
Oh, and there in fact is a simple way to tell iTunes to auto-shuffle the playlist

Yeah, that's what I thought...but then I tried it on three different user playlists and it didn't work. Then you posted, and I tried it again on a different iTunes install, and it worked. So that's a Huh? and a D'uh!

Nice job on winnowing down Block Party; you only held onto one bit of unneeded code (that's excellent for a first go;-). I've got a feeling that Doug chose "duration" for a track's time length since it returns a number of seconds; that's easy to compare to the user input number of seconds. You did a great job working out how to format seconds into MM:SS -- but if you dig around in the iTunes Applescript dictionary, you'll find cool stuff like "time".

On the theory that you're gonna want to do more with this (the urge to format the text with tab characters usually comes next ;-), I cleaned out the unneeded stuff and subbed "time" for "duration":
Code:
tell application "Finder" to set myPrefsFile to (container of (path to me) as string) & "username.txt" as string
set PrefsFileRef to open for access myPrefsFile
try
	set username to first paragraph of (read PrefsFileRef)
on error
	set username to "--Your Name Here--"
end try
close access PrefsFileRef

tell application "iTunes"
	set playlist_list to (get name of (every user playlist whose special kind is none))
	set use_this_playlist to (choose from list playlist_list with prompt "Format which playlist?" with title "Playlist Formatter!") as text
	if use_this_playlist is "false" then return
	
	set use_this_playlist to playlist use_this_playlist
	set timestr to time of use_this_playlist
	set pls_name to name of use_this_playlist
	tell application "Finder" to set theFilePath to (container of (path to me) as string) & pls_name as string
	set theFileReference to open for access theFilePath with write permission
	set eof theFileReference to 0
	write pls_name & " by " & username & return & "Total time: " & timestr & return & return to theFileReference starting at eof
	repeat with i from 1 to count of tracks of use_this_playlist
		tell track i of use_this_playlist to set {art, nom, durstr} to {artist, name, time}
		set theText to art & " - " & nom & " (" & durstr & ")" & return
		write theText to theFileReference starting at eof
	end repeat
	close access theFileReference
end tell
 

wormyrocks

New member
Joined
Mar 8, 2009
Messages
20
Points
0
NExt question: I'm working on a so-called DJ bot, that will play each track of a playlist and then announce, using TTS, the title of the song and some other stuff. Is there a very simple way to do this?
 

wormyrocks

New member
Joined
Mar 8, 2009
Messages
20
Points
0
Here's the code I have; it is within a tell statement. When I run it, it tells me that it "cannot get every track" of the playlist.
Code:
		set good to false
		repeat until good = true
			set good to true
			set trax to tracks of blockpartyplaylist
			set prev_artist to ""
			set hits to 1
			repeat with trak in trax
				set cur_artist to artist of trak
				if cur_artist is prev_artist then
					set hits to hits + 1
				else
					set prev_artist to cur_artist
					set hits to 1
				end if
				if hits > 2 then set good to false
			end repeat
			return
			if good = false then
				set shuffle to false
				set shuffle to true
			end if
		end repeat
 

S2_Mac

New member
Joined
Oct 24, 2006
Messages
4,878
Points
0
Location
About 3 feet in front of the monitor
When I run it, it tells me that it "cannot get every track" of the playlist.

The error message is iTunes' attempt to tell you that whatever value or object is in the blockpartyplaylist variable, it isn't a playlist. Let's assume that the block party playlist name is "Block Party"; what the error message is really saying is Can't complete the command get every track of "Block Party", because "Block Party" doesn't represent a playlist object. (If the first line in your sample code was display dialog class of blockpartyplaylist as text, I'm guessing you'd p'bly see "text", meaning that your variable holds a string instead of a playlist.)

So all you have to do is get a playlist object for "tracks of" to work on. Again using "Block Party" as a playlist name, you could:
Code:
set blockpartyplaylist to playlist "Block Party"
. . .
set trax to tracks of blockpartyplaylist
or
Code:
set blockpartyplaylist to "Block Party"
. . .
set trax to tracks of playlist blockpartyplaylist

For speaking, something like this:
Code:
tell application "iTunes"
	set trak to current track
	set trak_name to name of trak
	set trak_artist to artist of trak
	set trak_year to year of trak
end tell

say ("The current track is: " & trak_name & ", by: " & trak_artist & ", released in: " & trak_year)
(The "say" line could go inside the "tell" block, but it doesn't have to.) Lottsa sample code on the net.
 

wormyrocks

New member
Joined
Mar 8, 2009
Messages
20
Points
0
Here's what I have so far, it won't do the shuffle. :(
http: // dl.getdropbox. com/u/585860/Block%20Party%21. scpt
(remove all spaces)
By the way, I know how to do the speech thing, but what I don't know how to do is how to play the song all the way to the end, pause, and then talk.
 

S2_Mac

New member
Joined
Oct 24, 2006
Messages
4,878
Points
0
Location
About 3 feet in front of the monitor
I haven't tested very much, but I suspect the shuffle problem arises from trying it on a programmatically-populated playlist (p'bly what made it fail for me, at the top of this thread). You'll just have to keep testing/banging your head on the wall....

To be able to detect when a track has finished playing you'll need to use an "on idle" loop in a stay-open application, since iTunes doesn't signal when tracks are changing. In the idle loop you'll need to check the current track every so often; when current track changes you jump in and do the speech thing. Applescript timing isn't horribly precise, and you'll p'bly be dissatisfied with the results.... Another option is to programmatically uncheck all the tracks, then watch the player status in an idle loop; when the status changes from "playing" you can do the speech stuff, then start playing the next track. Doug's site has a few apps that use "on idle"...he might have an info page on it as well. Plus there's lottsa info on the web about using "on idle" (including the ever-helpful Language Guide).

Just a note -- you really should include notice of your modifications in the script; that's one of the requirements of the GPL under which the script is licensed. As it is now, the entire script appears to be entirely Doug's work, which is misleading.
 

wormyrocks

New member
Joined
Mar 8, 2009
Messages
20
Points
0
Okay, epic bump.
I need to make a program that essentially is the Playlist Formatter but instead formats the whole library into a text file. Is there a simple way to do this?
 

S2_Mac

New member
Joined
Oct 24, 2006
Messages
4,878
Points
0
Location
About 3 feet in front of the monitor
There's one or two scripts at Doug's that list playlists (IIRC); they use pure Applescript and are quite slow ('cuz text handling is not Applescript's strong suit ;-); they can get you started on what the code would look like.

Then there's this script that lists an entire library all at once...BUT...it only runs in 10.3 and 10.4. I used Perl to do the heavy lifting (no iTunes required), and it's faster than...well, snot, crap, lightning, take your pick ;-) (On an Intel Mac, it will run a 10MB XML file and produce a web page listing Album Artist, Track Artist, Album, Track, Genre, Rating, Kind, Time, Year in just a few seconds, compared to the tens of minutes needed by Applescript.) If interested, make sure you use the link above, since I don't have it listed on my Downloads page. (And don't even bother if you're running Leopard ;-)
 

wormyrocks

New member
Joined
Mar 8, 2009
Messages
20
Points
0
Hmm, well I am running Leopard. But I remember being able to create a text file of the library quite quickly with an older version of my Playlist Formatter that still uses lots of Block Party!
http://dl.getdropbox.com/u/585860/plsformat.scpt
^Clicking on Use ALL Audio Files will get it working. Problem is, there's lots of old code in there and I'm not quite sure how to streamline it, or how to figure out what to get rid of.

Oh, also: iTunes 'Digital Booklets' kill this program. How does one skip 'em?
 

S2_Mac

New member
Joined
Oct 24, 2006
Messages
4,878
Points
0
Location
About 3 feet in front of the monitor
Your code would be good for quickly generating a list of all artists in the library; that's the Perl at work. However, such a list of artists never gets used later in the code, so for now it's a moot point ;-)

This runs more than twice as fast (using nothing but Applescript), is a wee bit safer if problems occur with the output file, and uses "time" instead of "duration" (you were forgetting to account for hours in your duration calcs; the time property is easier 'cuz us humans don't have to think in order to use it ;-)
Code:
-- This rev runs more than twice as fast
set username to "WormyRocks"
tell application "iTunes"
	set playlist_list to (get name of (every user playlist whose special kind is none))
	set choose_playlist to (choose from list playlist_list with prompt "Format which playlist?" cancel button name "Use ALL audio files" with title "Playlist Formatter!" without multiple selections allowed) as text
	-- the all_artists var was never being used, so it's gone (along with all its subroutines ;-)
	if choose_playlist is not "false" then
		set use_this_playlist to playlist choose_playlist
	else
		set use_this_playlist to some playlist whose special kind is Music
	end if
	set pls_name to name of use_this_playlist
	
	-- we'll use the ready-to-go "time" property instead of making calculations around "duration"
	set out_list to {pls_name & " by " & username & return & "Total time: " & time of use_this_playlist & return & return}
	repeat with i from 1 to count of tracks of use_this_playlist
		tell track i of use_this_playlist to set {art, nom, dur} to {artist, name, time}
		set end of out_list to (art & " - " & nom & " (" & dur & ")" & return)
	end repeat
	
	-- write to the file just once, instead of one line at a time
	-- error handling to prevent the file from being undelete-able if something goes wrong
	set some_file to (path to desktop as string) & pls_name as string
	try
		set file_handle to open for access some_file with write permission
	on error
		display dialog "Couldn’t open the file “" & some_file & "”!" buttons {"OK"} default button 1
		return 0
	end try
	try
		set eof of file_handle to 0
		write (out_list as string) to file_handle
		close access file_handle
	on error
		close access file_handle
	end try
end tell
I'll work up a little Perl for you, but not for a couple of days...overly frantic here (Windows problems ;-)
 

wormyrocks

New member
Joined
Mar 8, 2009
Messages
20
Points
0
Thanks, but I actually don't need any Perl.
I should probably tell you my overall purpose of this project. I want to make an Applescript that, when run, generates a webpage with an interface (javascript based) that will basically mimic the man iTunes window. So you could click "Name" and it would sort by name, etc...
I've modified the script to make a basic website with styling, the script can be found here: http://dl.getdropbox.com/u/585860/libformat.zip
and the website it creates can be found here
http://www.snurl.com/wormysmusiclist
The current version of the formatter creates a website with basic styling. However, I have to re-run the script to sort by "Name" Time" and "Artist". Is there any way to make the iTunes window sort by Name, Time, Artist with Applescript instead of having to sort the iTunes window manually?

Also, I want to get rid of the "Format which playlist?" dialog. As it is, I've made it so that it is irrelevant what you click (it always formats the entire library) but for some reason I cannot just delete the chunk of code that runs the dialog box without an error.
Anyways, those are my questions. THanks for the help.
 

S2_Mac

New member
Joined
Oct 24, 2006
Messages
4,878
Points
0
Location
About 3 feet in front of the monitor
Can't really address your specific script issues, since your link doesn't contain the script that generated your sample page ;-)

AFAIK, the active "sort column" can't be selected via iTunes Applescript. Using GUI scripting you could try to set a mouse click at a specific spot (or a specific object) in the iTunes window....

But before you tackle that, you p'bly want to get a sorted list of any kind ;-) Looking at your sample page, it appears you're still agglomerating multiple playlists instead of getting the Music playlist (there is order in sections of the page, but not in the whole page).

Happy to help you sort it out, but you've got to link to the actual script you're using.
 

S2_Mac

New member
Joined
Oct 24, 2006
Messages
4,878
Points
0
Location
About 3 feet in front of the monitor
I want to get rid of the "Format which playlist?" dialog.

Getting rid of these 2 lines worked for me:
Code:
set playlist_list to (get name of (every user playlist whose special kind is none))
set choose_playlist to (choose from list playlist_list with prompt ¬
	"Format which playlist?" cancel button name ¬
	"Use ALL audio files" with title "Playlist Formatter!" without multiple selections allowed) as text
 

wormyrocks

New member
Joined
Mar 8, 2009
Messages
20
Points
0
Okay, making progress.
However, I know nothing about GUI scripting. How exactly can I make it click on "Artists"?
 

S2_Mac

New member
Joined
Oct 24, 2006
Messages
4,878
Points
0
Location
About 3 feet in front of the monitor
How exactly can I make it click on "Artists"?

Lottsa hard work ;-) You'll have to figure out the name or ID of the "object" you want to click (a column header) and where it sits in the hierarchy of the window's objects. Then you tell System Events "where" the object is and what to do to it (click). It's usually not easy, and it's more work than I want to do right now <g>.

Here's Apple's intro to GUI Scripting. Lots of how-to info online and in books, but p'bly no specific examples you can lift...
 
Top