Search code examples
applescriptmp3itunes

It is possible to write an Applescript droplet which can take mp3 files and retag them based on the file's name?


Is anyone able to write an Applescript as the basis to create a droplet app that when I drop a bunch of mp3s on it, it uses the filename pattern "TITLE - ARTIST - YEAR" to change the id3 tags of each file accordingly?

I have a sample of what I was trying to do but keep getting errors:

tell application "Music"
    try
        -- Get the "Filename Retag" playlist
        set playlistName to playlist "Filename Retag"
        set filenameRetagPlaylist to playlistName
        
        -- Process each track in the playlist
        repeat with aTrack in file tracks of filenameRetagPlaylist
            set filePath to location of aTrack
            set fileName to name of (info for filePath)
            
            -- Extract data from filename
            set textDelimiters to " - "
            set textItems to text items of fileName
            if (count of textItems) = 3 then
                set title to text 1 thru -2 of (item 1 of textItems)
                set artist to text 1 thru -2 of (item 2 of textItems)
                set year to item 1 of textItems
                
                -- Update track metadata
                set name of aTrack to title
                set artist of aTrack to artist
                set year of aTrack to year
            else
                do shell script "echo \"Invalid filename format: " & fileName & "\" >> /var/log/system.log"
            end if
        end repeat
        
        do shell script "echo \"Metadata updated for tracks in playlist \\\"" & playlistName & "\\\".\" >> /var/log/system.log"
        
    on error
        do shell script "echo \"Playlist \\\"" & playlistName & "\\\" not found in iTunes.\" >> /var/log/system.log"
    end try
end tell

This gives me the error: error "Can’t make «class cUsP» id 2444 of «class cSrc» id 64 of application "Music" into type Unicode text." number -1700 from «class cUsP» id 2444 of «class cSrc» id 64 to Unicode text

I add this code because it might be that I'm really close to a solution but someone can see what I'm doing wrong!


Solution

  • For a droplet, the items would need to be added to the music library, unless they have already been added to the "Filename Retag" playlist. Note that the name of a file path also includes the extension, so if you are going that route, the extension would need to be removed when working with the name pattern.

    • In your script, the playlistName variable is set to a playlist, but filenameRetagPlaylist is also set to playlistName, so it looks like those two statements got mixed up and should have been:
        set playlistName to "Filename Retag"
        set filenameRetagPlaylist to playlist playlistName
      
    • The track location isn’t used, and info for is also not needed, as a track has a name property;
    • It looks like you are wanting to use text item delimiters, so instead of the textDelimiters variable, you should be setting AppleScript’s text item delimiters property;
    • You also need to be careful about using variable names that are the same as scripting terms, such as name, artist, year, etc. In this case they can all be set with a single statement.

    Your posted script, cleaned up a little and with more error handling, would look something like:

    tell application "Music"
       try
          -- Get the "Filename Retag" playlist
          set playlistName to "Filename Retag"
          set filenameRetagPlaylist to playlist playlistName
          
          -- Process each track in the playlist
          set processed to 0 -- this will be the number of successfully processed items
          set theTracks to file tracks of filenameRetagPlaylist
          repeat with aTrack in theTracks
             set fileName to name of aTrack
             
             -- Extract data from filename
             set tempTID to AppleScript's text item delimiters -- stash current delimiters
             set AppleScript's text item delimiters to " - "
             set textItems to text items of fileName
             set AppleScript's text item delimiters to tempTID -- restore previous delimiters
             
             if (count textItems) = 3 then
                try
                   if item 3 of textItems as integer < 1700 or item 3 of textItems as integer > 2100 then error "Invalid year - value is out of range." -- check the text for a year
                   tell aTrack to set {its name, its artist, its year} to textItems -- Update track metadata
                   set processed to processed + 1
                on error errmess -- year is not a number, etc
                   log errmess
                   do shell script "echo 'Error with track \"" & fileName & "\":  " & errmess & "' >> /var/log/system.log"
                end try
             else
                do shell script "echo 'Invalid filename format:  \"" & fileName & "\"' >> /var/log/system.log"
             end if
          end repeat
          
          do shell script "echo 'Metadata updated for " & processed & " of " & (count theTracks) & " tracks in playlist \"" & playlistName & "\".' >> /var/log/system.log"
          
       on error errmess -- no playlist, etc
          log errmess
          do shell script "echo 'Script error:  " & errmess & "' >> /var/log/system.log"
       end try
    end tell