remove itunes drm

Hello all.

I’m a web developer by trade, but I am completely new to applescript. I hope I can learn through this forum!

The problem I’m trying to solve is this: I have roughly 500 itunes songs with drm on it. I realize there are programs I can purchase that will remove it for me, but i’d rather not pay for it. The free programs I’ve found are all for much older versions of itunes. I realize I can remove the drm by burning the songs, but that would take roughly 29 cds, so that sounds pretty tedious.

I’m wondering if there is a way, using applescript, I can put a CD-RW into my laptop, tell itunes to burn part of a playlist, reimport the songs, wipe the CD-RW using disk utility, then start over again. Is applescript this powerful?

I’d love any tips or ideas you guys could give me for this. Or, if I’m completely on the wrong track with my strategy for removing the drm, I’d love to hear that too.

I’m excited to hear your thoughts!

Will you be surprised to read that I hope that nobody will answer.

I guess that as a Web developer you want to be paid for your work.
It’s the same for the beings working upon music items.

If you dislike files with drm, buy the ones which haven’t.

Of course what I wrote is my own advice.
I don’t know if it’s shared by this forum’s moderators.

Yvan KOENIG (VALLAURIS, France) dimanche 4 septembre 2011 14:15:29

I completely understand the music world, having two parents who are professional musicians. I have no interest in stealing music, or distributing free music to my friends. I do not torrent music on that principle. Seeing as profitable music put me through college, I have great respect for hard-working musicians.

I would like to remove the drm from my music because it limits how I can use it and what I can play it on. I would love to set up a home music server, so I can stream my music from a web browser anywhere. I have no interest in distributing my music to anyone else. This is merely for personal use, so please don’t assume I am trying to steal music from anyone. That’s not what this is about. My intentions completely fall under fair use.

Besides, if I wanted to legally remove the drm I could simply burn a bunch of cds. That would be fine. Essentially, that is what I am trying to do with this script. I’m not “cracking” anything here.

Sorry for the double post, but I wanted to give an update on the progress I’ve made. I’ve decided to go the GUI scripting route because iTunes doesn’t seem to support burning through applescript. I’ve figured most of it out, except for one small part. I need to autocreate playlists in itunes. In other words, I have one main playlist with all the songs I want to burn – I need to split this playlist up into several smaller playlists using applescript. Any ideas?

hey,

i had a scriplet from this forum for creating playlists for an specific file size. Probably it can be changed to use time instead of file size.

here is the script

with timeout of 1000 seconds
	tell application "iTunes"
		if exists user playlist "Copy to iPod" then
			delete every file track of user playlist "Copy to iPod"
		else
			make new user playlist at folder playlist "Test" with properties {name:"Copy to iPod"}
		end if
		repeat with aTrack in (file tracks of user playlist "Recently Played")
			set tempAlbum to album of aTrack
			--Make sure we haven't already added this album
			set testAlbum to count (every file track of user playlist "Copy to iPod" whose album is tempAlbum)
			if testAlbum = 0 then
				-- Nope, it's not in the playlist
				-- Let's check and see if there's room to add it
				-- Edit the next row (after: is less than) to set the maximum size limit. 15 GB for example is 1.5E+10, 7GB is 7E+9
				if (size of user playlist "Copy to iPod" is less than 4.0E+9) then
					duplicate (every file track of library playlist 1 whose album is tempAlbum) to user playlist "Copy to iPod"
				else
					exit repeat
				end if
			end if
		end repeat
	end tell
end timeout

just saw, that probably “size” can be exchanged with “time” :slight_smile:

hope I could help

cheers

goeste

ps: i just found in the library of itunes the following:

I certainly agree, Yvan.

goeste, that looks amazing. I’ll definitely look into that avenue, thanks for the help!

Yvan and Adam, I completely agree that musicians should be paid for their work. I could not agree more with that. I am completely against stealing music in any way, shape, or form. But at the same time, I want the flexibility to use my paid-for music on whichever device I choose. I admit, I made the mistake of purchasing music with drm. But apple has provided a way for users to burn that music onto a cd, which removes the drm. Is burning a cd of your own drm music illegal or morally wrong? of course not. That is all that I am doing! Would either of you have a problem if I burned 30 cds, then reripped them? I’m curious to know…

Additionally, please keep in mind that in order to burn a protected song, you must first be authorized to play that song. So it’s not like the script I am writing is able to be really abused.

Goeste, with your help I came up with this! It does exactly what I need it to :slight_smile:


set originalPlaylist to "aaaaaa" -- the original playlist with tons of tracks
set playlistNameBase to "burnMe" -- the base name of each newly created playlist
set playlistNum to 1 -- the number we start incrementing at

tell application "iTunes"
	repeat with aTrack in (file tracks of user playlist originalPlaylist)
		set playlistName to playlistNameBase & playlistNum
		-- we're gonna have to create each new playlist, if it doesn't already exist
		if not (exists user playlist playlistName) then
			make new user playlist with properties {name:playlistName}
		end if
		-- make sure each playlist will fit onto a CD (max 80min == 4800s) but some songs
		-- long, so use a lower number for fudge room
		if (duration of user playlist playlistName is less than 4300) then
			duplicate aTrack to user playlist playlistName
		else
			set playlistNum to playlistNum + 1
		end if
	end repeat
end tell

Yet another question:

Anybody have any ideas as to how I can have my script wait until iTunes finishes burning a playlist? I suppose I could just enter a delay…but I don’t think that would be the most efficient or reliable. Ideas? Thanks!

Edit: I figured that one out. Turns out the new album automounts in itunes when it finishes burning…so:


-- don't progress until the burning is finished
			tell application "iTunes"
				repeat while not (exists source cdName)
					delay 0.5
				end repeat
			end tell

Now I just have to figure out how to have my script pause while importing…

nice to see I could help you at least a little :wink:

You can have iTunes import songs automatically. Whenever a cd is inserted. The playlists are created beforehand as i can tall, right? So I suggest:

  1. Let script create playlists
  2. Burn first playlist
  3. delete playlist AND songs out of iTunes
  4. Import AudioCD

how far is you script up to now? Does it also burn the playlists? Please share as it is nice to see how to back up and “undrm” iTunes-bought music :slight_smile:

My script is essentially done, now I’m just fixing little bugs here and there. I tried to run it last night, but the gui scripting part ran ahead of the launching of the burning window, so it errored out. I basically have it written though.

How I dealt with the importing issue:

I was originally thinking I could set itunes to auto-import when the cd was mounted, but then I realized I had to insert some kind of delay in my script so that it wouldn’t jump ahead and error out. I didn’t just want to choose a random length of time, because I felt like that was inefficient and unreliable. So I looked at some of the code on the site doug’s applescripts for itunes, and found another way to import the album:

I don’t actually have my script with me on this computer, I’m visiting friends for the weekend and I left my mac at home. So I will post my entire script once I get home and fix the bugs. But essentially my import solution was this:

my script does a repeat loop through all the cd album tracks
then there is some kind of “convert” function that essentially rips each track off the album

so it was something like:


repeat aTrack through aCD
convert aTrack
end repeat


Like I said, I don’t remember the exact code, but I will post it when I have it available.

Thanks again for the help you gave me goeste, it was key for my script!

The basic logic for my script is:
create cd-sized playlists from one source playlist
iterate through the newly created playlists and burn, import, and erase the cd each time
delete all the newly created playlists

EDIT:
Goeste, the exact code I used to import the CD was:


tell application "iTunes"
				repeat with thisTrack in every audio CD track of source cdName
					try
						convert thisTrack
					end try
				end repeat
			end tell

So my script works, except for one little strange bug. It occurs during the GUI scripting part when iTunes tries to open the burn window in File->Burn Playlist to Disk.

My script goes through the first iteration perfectly, the first playlist is burnt, reimported, and the disk is erased fine. The issue comes when my script tries to burn the second playlist. It appears like it clicks on the “Burn Playlist to Disk” menu item just fine, but for whatever reason the window doesn’t actually come up. When that happens, my script continues checking for the burn window, but never sees it so it just continues in a delay loop until I come along and stop it. The funny thing is, as soon as I stop the script and click into the Finder, the burn window pops up. Its not like the window is hiding behind the iTunes main window, its as if the window doesn’t actually pop up until I bring up another application. Being completely new to applescript and gui scripting, I have no idea what might be going on here. I’ve posted my code below for reference.

This is my fist foray into applescript, so if I’ve missed any conventions or done anything incorrectly please let me know!

Any GUI scripting gurus…I’d love some tips on what might be going on with this bug. I really don’t know very much about this! Thanks!


(*

Error I get is:
error "System Events got an error: Can't get window \"Burn Settings\" of process \"iTunes\"." number -1728 from window "Burn Settings" of process "iTunes"
...the window doesn't actually come up until I click into another application...



**	DRM Removal Script v2.0
**  
** PREREQUISITES:
** A CD-RW
** A PLAYLIST CONTAINING THE PROTECTED TRACKS YOU WISH TO REMOVE DRM FROM
**
** Summary:
** create a long list of playlists to burn, sourced from one master playlist
** -------- start loop ------------
** burn playlist to cd
** import cd
** diskutil eraseOptical <optical disk>
** iterate to next playlist
** -------- end loop -------------
** delete list of playlists
**)


-- The following section was taken from http://www.mactech.com/articles/mactech/Vol.21/21.06/UserInterfaceScripting/index.html
-- this code block makes sure the "access for assistive devices" is enabled in sys prefs for GUI scripting
tell application "System Events" to set isUIScriptingEnabled to UI elements enabled
if isUIScriptingEnabled = false then
	tell application "System Preferences"
		activate
		set current pane to pane "com.apple.preference.universalaccess"
		display dialog "Your system is not properly configured to run this script.  
         Please select the \"Enable access for assistive devices\" 
         checkbox and trigger the script again to proceed."
		return
	end tell
end if


-- *** VARIABLES ***
set originalPlaylist to "aaaaaa" -- playlist of all the songs you want to remove the DRM from
-- this script increments from playlist to playlist, after finding the first auto created playlist
-- so make sure there aren't any "normal" playlists in the newly created block of playlists to burn
-- just having a unique name in playlistNameBase should probably be enough, but I'm just warning you ;)
set playlistNameBase to "burnMe" -- the base name of each newly created playlist
set playlistNum to 1 -- the number we start incrementing at
set opticalDisk to "/dev/disk1" -- to locate your optical disk: "diskutil list" **!! MAKE SURE YOU HAVE THE RIGHT DISK !!**
set playlistList to {}


-- *******************************************************
-- ***** this code block creates all the playlists we are going to burn *****
-- *******************************************************
"creating playlists..."
tell application "iTunes"
	set playlistCurrentNum to playlistNum
	repeat with aTrack in (file tracks of user playlist originalPlaylist)
		set playlistName to playlistNameBase & playlistCurrentNum
		-- we're gonna have to create each new playlist, if it doesn't already exist
		if not (exists user playlist playlistName) then
			make new user playlist with properties {name:playlistName}
			set playlistList to playlistList & playlistName
		end if
		-- make sure each playlist will fit onto a CD (max 80min == 4800s) but some songs
		-- are long, so use a lower number for fudge room
		-- if you get error messages that the playlist won't fit on a single cd, lower this number
		if (duration of user playlist playlistName is less than 4300) then
			duplicate aTrack to user playlist playlistName
		else
			set playlistCurrentNum to playlistCurrentNum + 1
		end if
	end repeat
end tell

"playlists created"

-- *****************************************************************************
-- ******** GUI SCRIPTING PART (WARNING: EASILY BREAKABLE BY ITUNES UPDATES!!!) *********
-- *****************************************************************************
-- ***** this code section burns each playlist, unmounts and remounts it (which automatically *******
-- ***** imports it again), wipes the CD-RW, increments the playlist num, and starts over again ******
-- *****************************************************************************

set playlistName to playlistNameBase & playlistNum
set listSize to count of playlistList
set currentPlaylistNum to playlistNum

"starting burn loop..."
activate application "iTunes"
tell application "System Events"
	tell process "iTunes"
		
		-- determine the location of first playlist to burn
		-- the subsequent playlists should all be sequentially next, this script assumes and relies on that
		set x to 1
		repeat
			if exists static text playlistName of row x of outline 1 of scroll area 2 of window "iTunes" then
				set playlistPosition to x
				exit repeat
			end if
			set x to x + 1
		end repeat
		
		"starting at playlist location: " & playlistPosition
		
		repeat while currentPlaylistNum ≤ listSize
			set currentPlaylistName to playlistNameBase & currentPlaylistNum
			"burning playlist: " & currentPlaylistName
			
			select row playlistPosition of outline 1 of scroll area 2 of window "iTunes"
			click menu item 9 of menu 1 of menu bar item "File" of menu bar 1
			
			tell application "Finder"
				activate
			end tell
			tell application "iTunes"
				activate
			end tell
			
			-- wait until burn window pops up
			repeat while not (exists static text "Disc Burner:" of window "Burn Settings")
				delay 0.5
			end repeat
			
			select window "Burn Settings"
			click button "Burn" of window "Burn Settings"
			
			"burning cd..."
			
			-- don't progress until the burning is finished
			tell application "iTunes"
				repeat while not (exists source currentPlaylistName)
					delay 0.5
				end repeat
			end tell
			
			"importing cd..."
			-- import the audio cd
			tell application "iTunes"
				repeat with thisTrack in every audio CD track of source playlistName
					try
						convert thisTrack
					end try
				end repeat
			end tell
			
			"erasing optical disk..."
			do shell script ("/usr/sbin/diskutil eraseOptical " & opticalDisk)
			
			tell application "System Events"
				tell process "SystemUIServer"
					repeat while not (exists static text "You inserted a blank CD. Choose an action from the pop-up menu or click Ignore." of window 1)
						delay 0.05
					end repeat
					click button "OK" of window 1
				end tell
			end tell
			
			"incrementing playlist and starting loop again..."
			set playlistPosition to playlistPosition + 1
			set currentPlaylistNum to currentPlaylistNum + 1
		end repeat
	end tell
end tell


-- ***************************************************************
-- ****** this code block deletes all the previously created temporary playlists ******
-- ***************************************************************
tell application "iTunes"
	repeat with thePlaylistToDelete in playlistList
		delete user playlist thePlaylistToDelete
	end repeat
end tell

I finished my script and it works perfectly now! Enjoy using it! Mods, should i post this anywhere else?

Also, let me know if I missed any applescript conventions here. This is my first real applescript so I have no idea if I did this correctly! Thanks!


(*
**	DRM Removal Script v2.0
**  
** PREREQUISITES:
** A CD-RW
** A PLAYLIST CONTAINING THE PROTECTED TRACKS YOU WISH TO REMOVE DRM FROM
**
** Summary:
** create a long list of playlists to burn, sourced from one master playlist
** -------- start loop ------------
** burn playlist to cd
** import cd
** diskutil eraseOptical <optical disk>
** iterate to next playlist
** -------- end loop -------------
** delete list of playlists


** INSTRUCTIONS:
** 1. insert the CD-RW
** 2. put all your protected music into a single playlist, note the name of the playlist
** 3. change the originalPlaylist variable to be the name of your playlist
** 4. make sure the CD-RW is mounted and open terminal --> enter "diskutil list".
** 5. find the device with a size of 0B (hopefully that will be your optical disk! make
**    sure!) and then enter the name of that device into the opticalDisk variable
**
**   you can change playlistNameBase to whatever you like, just make sure it has a 
**   completely unique name among your playlists


** NOTICE: this has been tested with OS X 10.6.8 and iTunes 10.4.1
** I have no idea what other versions it might work on. Be careful 
** when running this if your versions do not match up with mine.
**)




-- *** VARIABLES ***
set originalPlaylist to "aaaaaa" -- playlist of all the songs you want to remove the DRM from
-- this script increments from playlist to playlist, after finding the first auto created playlist
-- so make sure there aren't any "normal" playlists in the newly created block of playlists to burn
-- just having a unique name in playlistNameBase should probably be enough, but I'm just warning you ;)
set playlistNameBase to "burnMeNOW" -- the base name of each newly created playlist
set playlistNum to 1 -- the number we start incrementing at
set opticalDisk to "/dev/disk1" -- to locate your optical disk: "diskutil list" **!! MAKE SURE YOU HAVE THE RIGHT DISK !!**
set playlistList to {}


-- The following section was taken from http://www.mactech.com/articles/mactech/Vol.21/21.06/UserInterfaceScripting/index.html
-- this code block makes sure the "access for assistive devices" is enabled in sys prefs for GUI scripting
tell application "System Events" to set isUIScriptingEnabled to UI elements enabled
if isUIScriptingEnabled = false then
	tell application "System Preferences"
		activate
		set current pane to pane "com.apple.preference.universalaccess"
		display dialog "Your system is not properly configured to run this script.  
         Please select the \"Enable access for assistive devices\" 
         checkbox and trigger the script again to proceed."
		return
	end tell
end if

-- *******************************************************
-- ***** this code block creates all the playlists we are going to burn *****
-- *******************************************************
"creating playlists..."
tell application "iTunes"
	set playlistCurrentNum to playlistNum
	repeat with aTrack in (file tracks of user playlist originalPlaylist)
		set playlistName to playlistNameBase & playlistCurrentNum
		-- we're gonna have to create each new playlist, if it doesn't already exist
		if not (exists user playlist playlistName) then
			make new user playlist with properties {name:playlistName}
			set playlistList to playlistList & playlistName
		end if
		-- make sure each playlist will fit onto a CD (max 80min == 4800s) but some songs
		-- are long, so use a lower number for fudge room
		-- if you get error messages that the playlist won't fit on a single cd, lower this number
		if (duration of user playlist playlistName is less than 4300) then
			duplicate aTrack to user playlist playlistName
		else
			set playlistCurrentNum to playlistCurrentNum + 1
		end if
	end repeat
end tell

"playlists created"

-- *****************************************************************************
-- ******** GUI SCRIPTING PART (WARNING: EASILY BREAKABLE BY ITUNES UPDATES!!!) *********
-- *****************************************************************************
-- ***** this code section searches for and burns each playlist, unmounts and remounts it (which *****
-- ***** automatically imports it again), wipes the CD-RW, increments the playlist num, and  starts ***
-- ***** over again 															 	     ******
-- *****************************************************************************

set listSize to count of playlistList
set currentPlaylistNum to playlistNum

--"starting at playlist location: " & playlistPosition

repeat while currentPlaylistNum ≤ listSize
	set currentPlaylistName to playlistNameBase & currentPlaylistNum
	"burning playlist: " & currentPlaylistName
	
	activate application "iTunes"
	tell application "System Events"
		tell process "iTunes"
			
			-- determine the location of playlist to burn
			set x to 1
			repeat
				if exists static text currentPlaylistName of row x of outline 1 of scroll area 2 of window "iTunes" then
					set currentPlaylistPosition to x
					exit repeat
				end if
				set x to x + 1
			end repeat
			
			select row currentPlaylistPosition of outline 1 of scroll area 2 of window "iTunes"
			click menu item 9 of menu 1 of menu bar item "File" of menu bar 1
			
			-- wait until burn window pops up
			repeat while not (exists static text "Disc Burner:" of window "Burn Settings")
				delay 0.5
			end repeat
			
			select window "Burn Settings"
			click button "Burn" of window "Burn Settings"
			
			"burning cd..."
			
			-- don't progress until the burning is finished
			tell application "iTunes"
				repeat while not (exists source currentPlaylistName)
					delay 0.5
				end repeat
			end tell
			
			"importing cd..."
			-- import the audio cd
			tell application "iTunes"
				repeat with thisTrack in every audio CD track of source currentPlaylistName
					try
						convert thisTrack
					end try
				end repeat
			end tell
			
			"erasing optical disk..."
			do shell script ("/usr/sbin/diskutil eraseOptical " & opticalDisk)
			
			-- hit "OK" when the new cd mounts
			tell application "System Events"
				tell process "SystemUIServer"
					repeat while not (exists static text "You inserted a blank CD. Choose an action from the pop-up menu or click Ignore." of window 1)
						delay 0.05
					end repeat
					click button "OK" of window 1
				end tell
			end tell
			
			"incrementing playlist and starting loop again..."
			set currentPlaylistNum to currentPlaylistNum + 1
		end tell
	end tell
end repeat


-- ***************************************************************
-- ****** this code block deletes all the previously created temporary playlists ******
-- ***************************************************************
tell application "iTunes"
	repeat with thePlaylistToDelete in playlistList
		delete user playlist thePlaylistToDelete
	end repeat
end tell