38 Comments

  1. Biinjo
    March 24, 2012

    It doesn’t do a thing! Please help..

  2. Eirik
    March 25, 2012

    On Lion running the sudo gem commands gives me an error;

    ERROR: Error installing json:
    ERROR: Failed to build gem native extension.

    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby extconf.rb
    mkmf.rb can’t find header files for ruby at /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/ruby.h

    Any idea? I saw somewhere suggested to install Xcode; but I don’t feel like installing a 1,3GB program to run a short script…

    • Beau Giles
      March 28, 2012

      Hey Elrik – you can try the other application mentioned at the end of the post – else unfortunately you may be required to download XCode.

      • Eirik
        March 29, 2012

        Ok. Thanks. I tried that other mac program, but it also didn’t work on my computer…

    • Brian
      October 29, 2012

      Probably because you have to install the Command Line Tools with XCode. With OSX Lion they disabled a lot of commands in terminal unless you install the Command Line Tools for developers.

  3. Dim
    April 1, 2012

    Thanks for sharing the script!
    It’s awesome!

  4. Christian
    May 21, 2012

    This didn´t work on my Mac. I installed XCode but this didn´t help. I got that message:

    Building native extensions. This could take a while…
    ERROR: Error installing json:
    ERROR: Failed to build gem native extension.

    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby extconf.rb
    mkmf.rb can’t find header files for ruby at /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/ruby.h

    Gem files will remain installed in /Library/Ruby/Gems/1.8/gems/json-1.7.3 for inspection.
    Results logged to /Library/Ruby/Gems/1.8/gems/json-1.7.3/ext/json/ext/parser/gem_make.out

  5. July 4, 2012

    Hmm, terminal throws me this error:

    method_missing’: Unknown property, element or command: ‘selection’ (RuntimeError)
    from iTunesMatchMetadata.rb:54

    • Stephen
      August 2, 2012

      I also get the error: method missing'. The complete error that was returned is:

      /Library/Ruby/Gems/1.8/gems/rb-appscript-0.6.1/lib/appscript.rb:676:in method_missing’: Unknown property, element or command: ‘selection’ (RuntimeError)
      from iTunesMatchMetadata.rb:54

      Any suggestions? I would love to update my metadata!

      Please. And thank you.

  6. Christian
    September 19, 2012

    What would it take to make this work on 10.6? I’m stuck on a 64bit iMac that cannot be upgraded. Thanks!

    • Christian
      September 19, 2012

      Can’t edit posts, disregard the previous post. What I meant to ask is why I am getting this error after installing ruby and running the script:

      /Library/Ruby/Gems/1.8/gems/rb-appscript-0.6.1/lib/_aem/connect.rb:89:in launch_application': The Classic emulation environment was required but is not available. (-10828) (Connect::CantLaunchApplicationError)
      from /Library/Ruby/Gems/1.8/gems/rb-appscript-0.6.1/lib/_aem/connect.rb:182:in
      local_app’
      from /Library/Ruby/Gems/1.8/gems/rb-appscript-0.6.1/lib/aem.rb:146:in by_path'
      from /Library/Ruby/Gems/1.8/gems/rb-appscript-0.6.1/lib/appscript.rb:57:in
      send’
      from /Library/Ruby/Gems/1.8/gems/rb-appscript-0.6.1/lib/appscript.rb:57:in connect'
      from /Library/Ruby/Gems/1.8/gems/rb-appscript-0.6.1/lib/appscript.rb:159:in
      reference_by_name’
      from /Library/Ruby/Gems/1.8/gems/rb-appscript-0.6.1/lib/appscript.rb:633:in `method_missing’
      from meta.rb:55

  7. Appleman
    October 2, 2012

    You need to install the command line tools for Xcode too…

    You can get Xcode from the Mac App Store. You’ll need at least version 4.4 of Xcode for it to work with OS X Mountain Lion. After the installation, open up Xcode in your /Applications folder. You’d want to go to Xcode -> Preferences -> Downloads tab then install the “Command Line Tools.” After you’re done, quit Xcode and fire up Terminal and follow the steps mentioned prior.

    Good Luck!

    • October 26, 2012

      Thanks Appleman; have added this to the post.

  8. Rahoof PM
    November 24, 2012

    Thanks a lot. nice post 🙂

  9. November 24, 2012

    For italian users, you can change code on line 63 with this:

    if iTunes_track.kind.get == ‘File audio AAC corrispondente’

    It will works fine!

  10. pedro
    December 4, 2012

    it’s not working in iTunes 11 =(

  11. Gabriel
    December 21, 2012

    Worked fine (also in iTunes 11). However I needed to change the language of my system preferences to english.

  12. George
    December 27, 2012

    Thank you for the post!
    I’m getting this error:

    Found 1793 matched tracks
    Querying AU store for 1793 tracks */Library/Ruby/Gems/1.8/gems/rb-appscript-0.6.1/lib/appscript.rb:542:in _send_command': CommandError (Appscript::CommandError)
    OSERROR: -1700
    MESSAGE: Can't make some data into the expected type.
    COMMAND: app("/Applications/iTunes.app").sources.ID(73).user_playlists.ID(18643).file_tracks.ID(18652).album.set(nil)
    from /Library/Ruby/Gems/1.8/gems/rb-appscript-0.6.1/lib/appscript.rb:642:in
    method_missing’
    from iTunesMatchMetadata.rb:38:in update_track'
    from iTunesMatchMetadata.rb:92
    from iTunesMatchMetadata.rb:90:in
    each’
    from iTunesMatchMetadata.rb:90
    from iTunesMatchMetadata.rb:88:in each'
    from iTunesMatchMetadata.rb:88
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/delegate.rb:137:in
    each_slice’
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/delegate.rb:137:in each'
    from iTunesMatchMetadata.rb:84:in
    each_slice’
    from iTunesMatchMetadata.rb:84
    from iTunesMatchMetadata.rb:81:in `each’
    from iTunesMatchMetadata.rb:81

    Any idea?

  13. Mark
    January 5, 2013

    Hello,

    I’m getting the same error as George. What goes wrong?

    MacBook-Pro-van-Mark-Ramaekers:desktop Mark$ ruby iTunesMatchMetadata.rb
    Reading 8077 tracks ********************************************************************************
    Found 8077 matched tracks
    Querying AU store for 8077 tracks */Library/Ruby/Gems/1.8/gems/rb-appscript-0.6.1/lib/appscript.rb:542:in _send_command': CommandError (Appscript::CommandError)
    OSERROR: -1700
    MESSAGE: Can't make some data into the expected type.
    COMMAND: app("/Applications/iTunes.app").sources.ID(72).user_playlists.ID(100410).file_tracks.ID(100430).album.set(nil)
    from /Library/Ruby/Gems/1.8/gems/rb-appscript-0.6.1/lib/appscript.rb:642:in
    method_missing’
    from iTunesMatchMetadata.rb:38:in update_track'
    from iTunesMatchMetadata.rb:92
    from iTunesMatchMetadata.rb:90:in
    each’
    from iTunesMatchMetadata.rb:90
    from iTunesMatchMetadata.rb:88:in each'
    from iTunesMatchMetadata.rb:88
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/delegate.rb:137:in
    each_slice’
    from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/delegate.rb:137:in each'
    from iTunesMatchMetadata.rb:84:in
    each_slice’
    from iTunesMatchMetadata.rb:84
    from iTunesMatchMetadata.rb:81:in `each’
    from iTunesMatchMetadata.rb:81

  14. Bo
    January 7, 2013

    Hi Mark and George,
    Issue seems to be when iTunes store doesn’t have an album associated with the song. The code can’t handle an empty album name.

    Just place a little if statement in the “update_track” method.
    It should look like this now (minus the line numbers of course, also line 36 was only for debugging):

    35 def update_track(result)
    36 puts “Track Id= #{result[‘trackId’]} | Artist Name= #{result[‘artistName’]} | Album Name= #{result[‘collectionName’]} | Track Name= #{result[‘trackName’]}”
    37 @iTunes_track.name.set(result[‘trackName’])
    38 if !result[‘collectionName’].nil?
    39 @iTunes_track.album.set(result[‘collectionName’])
    40 end
    41 @iTunes_track.artist.set(result[‘artistName’])
    42 @iTunes_track.track_count.set(result[‘trackCount’])
    43 @iTunes_track.track_number.set(result[‘trackNumber’])
    44 @iTunes_track.genre.set(result[‘primaryGenreName’])
    45 @iTunes_track.disc_count.set(result[‘discCount’])
    46 @iTunes_track.disc_number.set(result[‘discNumber’])
    47 end

    • Mark
      January 8, 2013

      Hi Bo,

      I’m a total nitwit. My script now looks like below.
      I’m getting the message:

      MacBook-Pro-van-Mark-Ramaekers:desktop Mark$ ruby iTunesMatchMetadata.rb
      iTunesMatchMetadata.rb:37: Invalid char \342' in expression
      iTunesMatchMetadata.rb:37: Invalid char
      \200′ in expression
      iTunesMatchMetadata.rb:37: Invalid char `\234′ in expression
      iTunesMatchMetadata.rb:37: dynamic constant assignment
      puts “Track Id= #{result[‘trackId’]} | Artist…

      What am I doing wrong?

      #!/usr/bin/env ruby
      # by @tapbot_paul
      # Don’t blame me if this nukes your metadata, formats your drive, kills your kids
      # This script goes through any iCloud Matched songs in your iTunes library and tries to update the
      # metadata from the iTunes Store
      # Will run against selected tracks or if nothing selected entire library
      # install the required gems with the following commands
      # sudo gem install json
      # sudo gem install rb-appscript
      # then run the script with “ruby meta.rb”
      require ‘rubygems’
      require ‘appscript’
      require ‘json’
      require ‘open-uri’
      require(“~/Library/iTunes/tunes.rb”)

      class Track
      attr_reader :iTunes_id
      attr_reader :iTunes_track
      def initialize(iTunes_track)
      @iTunes_track = iTunes_track
      path = @iTunes_track.location.get.path
      file_string = File.open(path, ‘r’).read(1024) # data always seems to be around 600-700 bytes in
      index = file_string.index(‘song’)
      if index
      @iTunes_id = file_string[index+4,4].unpack(‘N’)[0]
      else
      puts “Couldn’t find @iTunes_track id #{track.name.get}”
      end
      end

      def valid?
      @iTunes_id.nil?
      end

      def update_track(result)
      puts “Track Id= #{result[‘trackId’]} | Artist Name= #{result[‘artistName’]} | Album Name= #{result[‘collectionName’]} | Track Name= #{result[‘trackName’]}”
      @iTunes_track.name.set(result[‘trackName’])
      if !result[‘collectionName’].nil?
      @iTunes_track.album.set(result[‘collectionName’])
      end
      @iTunes_track.artist.set(result[‘artistName’])
      @iTunes_track.track_count.set(result[‘trackCount’])
      @iTunes_track.track_number.set(result[‘trackNumber’])
      @iTunes_track.genre.set(result[‘primaryGenreName’])
      @iTunes_track.disc_count.set(result[‘discCount’])
      @iTunes_track.disc_number.set(result[‘discNumber’])
      end

      end

      WORK_SIZE = 100
      STDOUT.sync = true
      tracks = []

      app = Appscript.app.by_name(“iTunes”, Tunes)

      iTunes_tracks = app.selection.get
      if iTunes_tracks.count == 0
      iTunes_tracks = app.library_playlists[1].tracks.get
      end

      print “Reading #{iTunes_tracks.count} tracks ”
      iTunes_tracks.each do | iTunes_track |
      begin
      if iTunes_track.kind.get == ‘Gematcht AAC-audiobestand’
      track = Track.new(iTunes_track)
      unless track.valid?
      tracks < e
      puts e
      end
      end
      puts ”

      # all 2 char countries codes lots currently not valid %w(AF AX AL DZ AS AD AO AI AQ AG AR AM AW AU AT AZ BS BH BD BB BY BE BZ BJ BM BT BO BQ BA BW BV BR IO BN BG BF BI KH CM CA CV KY CF TD CL CN CX CC CO KM CG CD CK CR CI HR CU CW CY CZ DK DJ DM DO EC EG SV GQ ER EE ET FK FO FJ FI FR GF PF TF GA GM GE DE GH GI GR GL GD GP GU GT GG GN GW GY HT HM VA HN HK HU IS IN ID IR IQ IE IM IL IT JM JP JE JO KZ KE KI KP KR KW KG LA LV LB LS LR LY LI LT LU MO MK MG MW MY MV ML MT MH MQ MR MU YT MX FM MD MC MN ME MS MA MZ MM NA NR NP NL NC NZ NI NE NG NU NF MP NO OM PK PW PS PA PG PY PE PH PN PL PT PR QA RE RO RU RW BL SH KN LC MF PM VC WS SM ST SA SN RS SC SL SG SX SK SI SB SO ZA GS SS ES LK SD SR SJ SZ SE CH SY TW TJ TZ TH TL TG TK TO TT TN TR TM TC TV UG UA AE GB US UM UY UZ VU VE VN VG VI WF EH YE ZM ZW)

      countries = %w(NL US GB FR DE CA IT JP DZ AO AI AG AR AM AT AZ BS BH BD BB BY BE BZ BM BO BW BR BN BG CM KY CL CN CO CR CI HR CY CZ DK DM DO EC EG SV EE ET FI GH GR GD GT GY HN HK HU IS IN ID IE IL JM JO KZ KE KR KW LV LB LY LI LT LU MO MK MG MY MV ML MT MU MX MD MS MM NP AU NZ NI NE NG NO OM PK PA PY PE PH PL PT QA RO RU KN LC VC SA SN RS SG SK SI ZA ES LK SR SE CH TW TZ TH TT TN TR TC UG UA AE UY UZ VE VN VG YE)

      puts “Found #{tracks.count} matched tracks”
      countries.each do | country |
      print “Querying #{country} store for #{tracks.count} tracks ”
      counter = 0
      tracks.dup.each.each_slice(WORK_SIZE) do | subtracks |
      ids = subtracks.map { | track | track.iTunes_id }
      iTunesHash = JSON.parse(open(“http://itunes.apple.com/lookup?id=#{ids.join(‘,’)}&country=#{country}”).read)
      print ‘*’
      iTunesHash[‘results’].each do | result |
      result_id = result[‘trackId’]
      subtracks.each do | track |
      if result_id == track.iTunes_id
      track.update_track(result)
      tracks.delete(track)
      counter += 1
      break
      end
      end
      end
      end
      puts ” #{counter} updated”
      break if tracks.empty?
      end

      puts “Couldn’t find meatadata for #{tracks.count} tracks” if tracks.count != 0

      • Carlos
        January 18, 2013

        Just remove line 36 and voila!

  15. LALA
    February 26, 2013

    Does this add the copyright tag as well?

    • February 26, 2013

      Hey Lala,
      Could you please explain what you mean by ‘copyright’ tag?
      This script should only change the title, album and artist fields, without touching anything else.

      • Lala
        February 26, 2013

        By copyright tag I mean the record label field that appears under the title, album and artist tags when clicking on “Get Info” on iTunes. Thank you for the reply in advance.

  16. Anthony
    May 19, 2013

    I absolutely loved this post, and I had no problems running the script. Thanks so much!

    The only question I have is if there is any way to make this script gather and replace any other information, like genre, year, explicit/clean, etc? Or is that related to a limitation of the API?

  17. Ludovic Salmeron
    June 9, 2013

    Hey sorry for my bad english i’m french, I don’t know why :

    new-host:Desktop ludovicsalmeron$ ruby iTunesMatchMetadata.rb
    Reading 1003 tracks
    Found 0 matched tracks
    Querying AU store for 0 tracks 0 updated

    Only AU store and no others. Can U help me ?

  18. Rinma
    June 26, 2013

    Where can i find tunes.rb and itunesmatchmetadata.rb?

  19. Brad
    July 20, 2013

    Have you found a workaround for tracks that are not found in any of the stores? Seems odd to me that ANY would be skipped if they are still available on iTunes.

    Awesome script! I can’t thank you enough.

  20. David
    October 3, 2013

    Thanks! This works like a charm. I fixed up a couple hundred tunes tonight that had been resisting everything else.

  21. Zee
    October 12, 2013

    This was working fine on my iMac with OS 10.8 today I updated to OS 10.9 and now it’s not working.

    what do you think changed on 10.9 ?

  22. Gert-Jan
    October 15, 2013

    Hey Guys,
    I got some problems with getting updated tracks, this is what termanl said:

    Reading 1119 tracks
    Found 0 matched tracks
    Querying AU store for 0 tracks 0 updated
    MacBook-Pro-van-Gert-Jan:Desktop GertJan$
    MacBook-Pro-van-Gert-Jan:Desktop GertJan$
    MacBook-Pro-van-Gert-Jan:Desktop GertJan$
    MacBook-Pro-van-Gert-Jan:Desktop GertJan$ ruby iTunesMatchMetadata.rb

    Can anyone see whats the problem of not getting any updated tracks?

    Thanks in advance!

    Gert-Jan

  23. Connor
    October 15, 2013

    This is working quite well, however I have the same question as some of the guys above, i.e. Lala and Anthony. Is there a way to edit the script so that it adds other metadata, e.g. Copyright information and explicit/clean tags? I have tried adding to the script myself (although I really am no expert) but I can never get it to work.

    Replies would be much appreciated (either from the author or someone who knows how to do this).

    Thanks

  24. Carlo
    November 13, 2013

    I am wondering if there has been a update to this script for Ituness 11 and Maverick OSX

  25. Tim
    January 3, 2014

    Any updates on this?

Comments are closed.