|
|||||||
![]() |
|
|
Thread Tools | Rate Thread | Display Modes |
|
|
#1 |
|
Triple-A Player
Join Date: Oct 2006
Posts: 135
|
Script to duplicate Apple Lossless iTunes library as MP3 files
Hi,
I have written the applescript below to duplicate my Apple Lossless iTunes library as a MP3 Library. I wanted the script to be able to do the following things: 1. For all Apple Lossless tracks in iTunes Library (at the moment the script is just set to work with a selection for testing purposes) check if track already exists in MP3 folder with more recent modification date and: a If yes, do nothing b If same track with earlier modification date convert and replace track (so that tag changes are transferred) c If track doesn't exist convert track. 2. If there are any MP3 files in the target folder that aren't in the source folder (i.e. the iTunes Music Folder), delete these files. This is for the scenario when I delete files from my iTunes Library that I no longer want, and I want the equivalent MP3 file to be deleted as well. So once the script has finished running there should be an exact match between the Apple Lossless library and the MP3 folder. The script below does everything I want it to do with the following caveats: 1. I am not sure how to go about deleting the MP3 files as in part 2. I guess it would have to be an additional section of script which compares each file by name in the folder/subfolder in the iTunes Music Library with the equivalent folders in the target music folder, deleting any files found in the target music folder that don't exist in the iTunes Music folders, but I'm not sure if this is the best/only method, and how I would go about scripting this. 2. Because I need to specify the conversion twice (once if no file exists in target folder and once if it does but with an older modification date) I am wondering about using a subroutine method here. I tried doing so, but no conversions happened even though some should have happened. I wonder if this is because the relevant variables aren't picked up properly by the script when it's a subroutine. I can leave things as they are, just thought it would be good to make the script neater. Code:
tell application "iTunes"
activate
set sel to selection
set encoderBackup to name of current encoder
set this_folder to "Macintosh HD:Users:nick:Desktop:music:" as text
set current encoder to encoder "MP3 Encoder"
repeat with this_track in sel
set trackComposer to this_track's composer
set trackAlbum to this_track's album
set trackName to this_track's name
tell application "Finder"
set path1 to "Macintosh HD:Users:nick:Desktop:music:" & trackComposer as text
if folder path1 exists then
{}
else
make new folder at this_folder with properties {name:trackComposer}
end if
set path2 to this_folder & trackComposer & ":" & trackAlbum as text
if folder path2 exists then
{}
else
make new folder at path1 with properties {name:trackAlbum}
end if
if exists file (path2 & ":" & trackName & ".mp3") then
set file2 to (path2 & ":" & trackName & ".mp3") as alias
set modDate to modification date of file2
set modDate2 to this_track's modification date
if modDate is greater than modDate2 then
{}
else
tell application "iTunes"
try -- skip on failure
set new_track to item 1 of (convert this_track)
set loc to new_track's location
set dbid to new_track's database ID
delete artworks of new_track
-- move the file to new location
do shell script "mv " & (quoted form of POSIX path of loc) & " " & (quoted form of POSIX path of path2 as string)
-- delete the track
delete new_track
end try
end tell
end if
else
tell application "iTunes"
try -- skip on failure
set new_track to item 1 of (convert this_track)
set loc to new_track's location
set dbid to new_track's database ID
delete artworks of new_track
-- move the file to new location
do shell script "mv " & (quoted form of POSIX path of loc) & " " & (quoted form of POSIX path of path2 as string)
-- delete the track
delete new_track
end try
end tell
end if
end tell
end repeat
set current encoder to encoder encoderBackup
display dialog "done"
end tell
Thanks Nick
__________________
OS X 10.6.2 Mac Pro 2 x 3 GHz Dual-Core Intel Xeon 8 GB RAM |
|
|
|
|
|
#2 |
|
Hall of Famer
Join Date: Apr 2007
Posts: 4,262
|
This should work. I've gotten rid of the senseless shell script call and converted files paths to Finder objects, but it's essentially the same script.
Code:
set this_folder to (path to desktop folder from user domain as text) & "music:"
tell application "iTunes"
-- activate -- not really necessary to activate iTunes
set sel to selection
set encoderBackup to name of current encoder
set current encoder to encoder "MP3 Encoder"
end tell
repeat with this_track in sel
tell application "iTunes"
set trackComposer to this_track's composer
set trackAlbum to this_track's album
set trackName to this_track's name
set tunesModDate to this_track's modification date
end tell
tell application "Finder"
-- build folder hierarchy, if it doesn't already exist
try
make new folder at folder this_folder with properties {name:trackComposer}
end try
try
make new folder at folder trackComposer of folder this_folder with properties {name:trackAlbum}
end try
set folder_path to folder trackAlbum of folder trackComposer of folder this_folder
try
-- throws error if file doesn't exist
set theExtantFile to file (trackName & ".mp3") of folder_path
if modification date of theExtantFile is less than tunesModDate then
delete theExtantFile
tell me to set theConvertedFile to ConvertTune(this_track)
end if
on error
-- no extant file
tell me to set theConvertedFile to ConvertTune(this_track)
end try
if theConvertedFile is not false then
move theConvertedFile to folder_path
end if
end tell
end repeat
tell application "iTunes"
set current encoder to encoder encoderBackup
display dialog "done"
end tell
to ConvertTune(t)
tell application "iTunes"
try -- skip on failure
set new_track to item 1 of (convert t)
set loc to new_track's location
set dbid to new_track's database ID
delete artworks of new_track
delete new_track -- deletes track from library; does not delete the file itself
return loc
on error
return false
end try
end tell
end ConvertTune
__________________
Philosophy is a battle against the bewitchment of our intelligence by means of language. -LW- |
|
|
|
|
|
#3 |
|
Triple-A Player
Join Date: Oct 2006
Posts: 135
|
Thanks. I have been working on the script further and got it to do everything I want it to do except the deleting of MP3 files that are present in the destination folders that aren't present in m4a format in the source (iTunes) folders:
Code:
tell application "iTunes"
activate
set sel to selection
set encoderBackup to name of current encoder
set this_folder to "Macintosh HD:Users:nick:Desktop:music:" as text
set current encoder to encoder "MP3 Encoder"
repeat with this_track in sel
set trackComposer to this_track's composer
set trackAlbum to this_track's album
set trackName to this_track's name
tell application "Finder"
set path1 to "Macintosh HD:Users:nick:Desktop:music:" & trackComposer as text
if not (folder path1 exists) then
make new folder at this_folder with properties {name:trackComposer}
end if
local path2
set path2 to this_folder & trackComposer & ":" & trackAlbum as text
if not (folder path2 exists) then
make new folder at path1 with properties {name:trackAlbum}
end if
if exists file (path2 & ":" & trackName & ".mp3") then
set file2 to (path2 & ":" & trackName & ".mp3") as alias
set modDate to modification date of file2
set modDate2 to this_track's modification date
if not (modDate is greater than modDate2) then
my convertTrack(this_track, path2)
end if
else
my convertTrack(this_track, path2)
end if
end tell
end repeat
set current encoder to encoder encoderBackup
display dialog "done"
end tell
on convertTrack(this_track, path2)
tell application "iTunes"
try -- skip on failure
set new_track to item 1 of (convert this_track)
set loc to new_track's location
set dbid to new_track's database ID
delete artworks of new_track
-- move the file to new location
do shell script "mv " & (quoted form of POSIX path of loc) & " " & (quoted form of POSIX path of path2 as string)
-- delete the track
delete new_track
end try
end tell
end convertTrack
error "Finder got an error: An item with the same name already exists in this location." number -15267 I am not sure if there are advantages to your script over mine (once the issue is resolved). Also, do you have any ideas as to how to delete any MP3 files in the destination folders/subfolders, that don't exist as m4a files in the source (iTunes) folders/subfolders (i.e. point 1 in my second post above). Thanks again Nick
__________________
OS X 10.6.2 Mac Pro 2 x 3 GHz Dual-Core Intel Xeon 8 GB RAM |
|
|
|
|
|
#4 |
|
Hall of Famer
Join Date: Apr 2007
Posts: 4,262
|
The main advantage of my script over yours is that mine is cleaner, for the following reasons:
The reason the script is throwing an error is that - because I switched to using the Finder's special properties - it now sees an error in your script that your script was ignoring before. there is a difference between the track name as displayed in iTunes and the file name under which iTunes stores the track. commonly, for instance, iTunes will append extra info: a track called "Snufflehead" might be stored as "03 - Snufflehead.xxx" (sorry for the example; have allergies this morning). You were building filenames different than the filenames that iTunes uses, which may or may not cause problems down the line (depending on what you're using this for). doing back checks (trying to delete extraneous tracks) is a bit of a problem the way you have things up. The Finder only knows file names, but iTunes won't search by location, and as noted the file name of the track may not correspond to the track name in itunes. your best bet is actually to rewrite the script and maintain the list of mp3s within your itunes library - just make sure to set the enabled key to false and to add the tracks to a category, playlist, or etc., or use comments to mark them as recoded duplicates. That makes it fairly easy to check for absent originals within iTunes itself. (you might also add recoded m4v files to a playlist to cut down the search time when you're trying to find missing originals - easier to search a short list of files you know you've recoded than to search the entire library).
__________________
Philosophy is a battle against the bewitchment of our intelligence by means of language. -LW- |
|
|
|
|
|
#5 |
|
Triple-A Player
Join Date: Oct 2006
Posts: 135
|
Thanks. My filenames are set to be the same as the name of the tracks in my iTunes Library, so I don't think this is the issue.
The error in your script is occurring here: Code:
if theConvertedFile is not false then move theConvertedFile to folder_path end if Regarding the second point, I would rather avoid having the MP3s in my iTunes Library. I'd like to be able to just click on 'Music' in the iTunes library and get one version of each track, and also I'd like to avoid having to add 'kind is Apple Lossless Audio File' to all my smart playlists. If there is no other way of deleting the unneeded MP3 files I will consider this, but was hoping there was a way of just comparing the destination directory with the source directory using Finder in the script. oh, and the purpose of the script is to create an exact duplicate of my Apple Lossless Library in MP3 format. The script would be run periodically and would add new tracks, update mp3 tracks that I have updated in my iTunes library, delete tracks that no longer exist in my iTunes library, and leave the rest alone. Nick
__________________
OS X 10.6.2 Mac Pro 2 x 3 GHz Dual-Core Intel Xeon 8 GB RAM Last edited by nick_harambee; 09-27-2010 at 02:11 PM. |
|
|
|
|
|
#6 | |||||||||||||||||||||||
|
Hall of Famer
Join Date: Apr 2007
Posts: 4,262
|
Yes, I know where the error is, and I told you why it's happening. I haven't got the time to fix it right at the moment, however (mostly since it would involve restructuring the concept, but I don't want to do that without a better sense of what you want from the script). Deleting without having the files as part of your iTunes library is not impossible, just a bit of a pain. The easiest way I can think of to do it is as follows: Code:
tell application "iTunes"
-- get a text list of all paths of all files in the library
set theLocations to location of every file track of source "library"
set {oldTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, return}
set theLocations to theLocations as text
set AppleScript's text item delimiters to oldTID
set killTheseFiles to {}
repeat with thisPath in theRecodedFilesFolder
-- get the album:artist:file name of a given recoded file, withut the extension
set {oldTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ":"}
set pathSnippet to (text items -3 thru -1 of (thisPath as text)) as text
set AppleScript's text item delimiters to oldTID
set pathSnippet to (text 1 thru -5 of pathSnippet)
-- see if that snippet is in the text list of file locations, store it for deletion if so
if theLocations does not contain pathSnippet then
copy thisPath to end of killTheseFiles
end if
end repeat
end tell
-- delete the stored files
tell application "Finder" to delete killTheseFiles
However, I'm going to suggest that you stop trying to do this with iTunes. there are a number of free music conversions apps on the web, and I suspect that if you look a bit you will find one that will convert your music library to a new location without invoking itunes at all (and probably one that will automatically synchronize the folders).
__________________
Philosophy is a battle against the bewitchment of our intelligence by means of language. -LW- |
|||||||||||||||||||||||
|
|
|
|
|
#7 |
|
Triple-A Player
Join Date: Oct 2006
Posts: 135
|
Thanks. I know there's other apps to convert files, but, despite quite a bit of searching I have not found an app on the Mac that will synchronize an Apple Lossless library with a Compressed Format Library. J River Media Center on Windows will do it, but I'd rather not go down the Parallels route for this. Hence the need for this script.
So I made a small adjustment to your script so that it just lists my main Music Playlist, which contains the files I want to synchronize with. Then I needed to set theRecodedFilesFolder (I hope I did this right). Then when I run the script I get the error: error "Can’t get text 1 thru -5 of \"M\"." number -1728 from text 1 thru -5 of "M" Code:
tell application "iTunes"
-- get a text list of all paths of all files in Music Playlist
set theLocations to location of every file track of playlist "Music"
set {oldTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, return}
set theLocations to theLocations as text
set AppleScript's text item delimiters to oldTID
set killTheseFiles to {}
set theRecodedFilesFolder to "Macintosh HD:Users:nick:Desktop:music:" as text
repeat with thisPath in theRecodedFilesFolder
-- get the album:artist:file name of a given recoded file, withut the extension
set {oldTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ":"}
set pathSnippet to (text items -3 thru -1 of (thisPath as text)) as text
set AppleScript's text item delimiters to oldTID
set pathSnippet to (text 1 thru -5 of pathSnippet)
-- see if that snippet is in the text list of file locations, store it for deletion if so
if theLocations does not contain pathSnippet then
copy thisPath to end of killTheseFiles
end if
end repeat
end tell
-- delete the stored files
tell application "Finder" to delete killTheseFiles
__________________
OS X 10.6.2 Mac Pro 2 x 3 GHz Dual-Core Intel Xeon 8 GB RAM |
|
|
|
|
|
#8 |
|
Hall of Famer
Join Date: Apr 2007
Posts: 4,262
|
ah, no. you need a list of the all the files in the folder, not just the folder name itself. add the following code right before the 'tell application "iTunes"' line:
Code:
tell application "Finder" set theRecodedFilesFolder to (every file of entire contents of folder "Macintosh HD:Users:nick:Desktop:music:") as alias list end tell You might want to look at PowerTunes and Max. PowerTunes might be just the thing you're looking for, but it costs $20. Max won't synchronize folders, but it's a good converter, and it's scriptable, and it might be easier to use (all things considered) than iTunes.
__________________
Philosophy is a battle against the bewitchment of our intelligence by means of language. -LW- |
|
|
|
|
|
#9 |
|
Triple-A Player
Join Date: Oct 2006
Posts: 135
|
Many thanks tw. That seems to work fine. When I have more time I'll test it more thoroughly and report back.
I have been in communication with the developer of PowerTunes and he is thinking of implementing the feature to sync two versions of iTunes Libraries in different formats, but it's not there yet. Sure, I could use Max for the conversions if I was just comparing two directories. It would still need scripting though. I appreciate you taking the time to help me on my way... Nick
__________________
OS X 10.6.2 Mac Pro 2 x 3 GHz Dual-Core Intel Xeon 8 GB RAM |
|
|
|
|
|
#10 |
|
Hall of Famer
Join Date: Apr 2007
Posts: 4,262
|
well, the advantage of scripting Max is that Max doesn't care whether a file is in the music library. iTunes is limited in what it can do with non-library files; Max is equal opportunity. makes life easier.
my pleasure though.
__________________
Philosophy is a battle against the bewitchment of our intelligence by means of language. -LW- |
|
|
|
|
|
#11 |
|
Triple-A Player
Join Date: Oct 2006
Posts: 135
|
one issue that has emerged with this script is that Finder does not permit the character '?' in file names, and replaces them with '_', so if tracks in iTunes have a question mark in the title the script will want to re-convert these files even if no changes have been made.
I am wondering if there is a way of adapting the script so that it can account for this difference, i.e. so that when the script is looking to see whether the track exists in Finder it will interpret a ? in the track Name in iTunes as a _ in the track Name in Finder.
__________________
OS X 10.6.2 Mac Pro 2 x 3 GHz Dual-Core Intel Xeon 8 GB RAM |
|
|
|
|
|
#12 |
|
Triple-A Player
Join Date: Oct 2006
Posts: 135
|
I now realise there are other characters that are not supported by Finder, namely / and :. So these would need to be built into the script as well, presumably for albums and composer tags as well as track name.
__________________
OS X 10.6.2 Mac Pro 2 x 3 GHz Dual-Core Intel Xeon 8 GB RAM |
|
|
|
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|