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

60 Views Asked by At

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!

2

There are 2 best solutions below

2
red_menace On BEST ANSWER

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
0
tardy pigeon On

So after help from @red_menace this is the solution that retagged files in a playlist based on their filenames minus extension:

tell application "Music"
set playlistName to "Filename Retag"
set filenameRetagPlaylist to playlist playlistName

set processed to 0

--gets filename of a track
repeat with aTrack in (file tracks of filenameRetagPlaylist)
    set fileName to name of aTrack
    set trackLocation to location of aTrack
    set posixPath to POSIX path of trackLocation
    set fullName to do shell script "basename " & quoted form of posixPath
    
    
    -- Extract data from filename
    set tempTID to AppleScript's text item delimiters
    set AppleScript's text item delimiters to " - "
    set textItems to text items of fullName
    set AppleScript's text item delimiters to tempTID
    
    if (count textItems) = 3 then
        try
            set {titleText, artistText, yearText} to textItems
            -- Remove ".mp3" extension from yearText
            if yearText ends with ".mp3" then
                set yearText to text 1 thru -5 of yearText
            end if
            -- Update track metadata
            set name of aTrack to titleText
            set artist of aTrack to artistText
            set year of aTrack to yearText
            
            set processed to processed + 1
        on error errmess
            log errmess
        end try
    else
        log "Invalid filename format: " & fileName
    end if
end repeat

end tell