Back
Fix Bad iTunes Locations 2019-10-20

I've used iTunes (and SoundJam MP before it) to listen to music and keep it organized. In general, I've done an okay job, but there were hundreds of songs that didn't have any album art, or even an associated album, or whose ID3 tags could not possibly be correct.

Enter MusicBrainz along with their Picard application, which is designed to fill in that missing information from a publically curated database of music. One can even submit a fingerprint of a file to find metadata about a song that you otherwise have no information about. I use it whenever I get new music, and occasionally to update my collection with newer tags from their db.

However, because I've always used iTunes in organize-my-library mode, when I change the tags on the mp3 files, iTunes get confused and forgets where these files are exactly. This is annoying, because in the last few version of iTunes, it now politely skips over missing tracks in a playlist rather than stop playback to ask me modally if I'd like to find that track right now, but then I don't even know that they are missing.

To fix this, I wrote a quick AppleScript to find those files. It uses the sherlock database (is that still what it's called?!) to look for files with the name of the song. If there's only one match, it updates the location to that file in iTunes. It fixed about 300 of my songs very quickly, and I'm putting it here in case you want to use it.

on theSplit(theString, theDelimiter)
  -- save delimiters to restore old settings
  set oldDelimiters to AppleScript's text item delimiters
  -- set delimiters to delimiter to be used
  set AppleScript's text item delimiters to theDelimiter
  -- create the array
  set theArray to every text item of theString
  -- restore the old setting
  set AppleScript's text item delimiters to oldDelimiters
  -- return the result
  return theArray
end theSplit

set newline to "
"
tell application "iTunes"
  set theLibrary to (get library playlist 1)
  set theTracks to every file track of theLibrary
  repeat with theTrack in theTracks
    if location of theTrack is missing value then
      set theCmd to "mdfind -name " & quote & (get name of theTrack) & quote
      set theOutput to do shell script theCmd
      set theLines to my theSplit(theOutput, newline)
      log (get count of theLines)
      if (count of theLines) is 1 then
        log ("1 result found: " & (item 1 of theLines))
        set location of theTrack to item 1 of theLines
      end if
    end if
  end repeat
end tell
Back