Move music library and update iTunes database

I’m doing some reorganization of my network shares. My music is saved on the server under its own share, “Music”. In the new scheme, I want the music folder to be located in a subfolder in the share “Multimedia”. This poses a small problem: I have to update iTunes to recognize the new file locations. I’ve got iTunes 10.6.3 on OS X Mountain Lion 10.8.1.

Edit iTunes Music Library.xml

The simple solution is to modify the Location values in the iTunes Music Library.xml file, mangle the iTunes Library.itl file, then open iTunes. iTunes will then rebuild the database file based on the xml (the .itl file is the active database file, the .xml file is regenerated based on the .itl database).  To find and replace all the locations I tried this:

cat ~/Music/iTunes/iTunes\ Music\ Library.xml | perl -pe 's/\/Volumes\/Music\//\/Volumes\/Multimedia\/music\//i' > itunes.xml

Then quickly checked to see if I was missing any other locations:

cat itunes.xml | grep "Location" | grep -v "/Volumes/Multimedia/music"

Then erase iTunes Library.itl, replace iTunes Music Library.xml with this new copy (making backups of the originals first, of course).

An unfortunate side effect of rebuilding the .itl based on the xml: the Date Added values for the entire library are reset (probably other values are reset as well). I wanted to move my library files and keep all the metadata intact.

Edit iTunes Library.itl

So, instead of editing the xml file, what about editing the itl file? Unfortunately, the .itl file is a proprietary format binary file. Luckily, there are some who have tinkered with the file in order to edit .itl database entries. Enter Tools for iTunes Libraries (titl): excellent! I cloned the mercurial repository, built the code and tried to move some files:

$ hg clone https://code.google.com/p/titl/ titl
$ cd titl
$ mvn verify
$ java -Xmx512m -XX:MaxPermSize=256m -jar titl-core/target/titl-core-0.3-SNAPSHOT.jar MoveMusic --use-urls ~/Music/iTunes/iTunes\ Library.itl "file://localhost/Volumes/Music" "file://localhost/Volumes/Multimedia/music"

That resulted in a Exception in thread "main" java.io.EOFException, the exact same issue as this one. Downloaded the patch file that the user thankfully uploaded, applied the patch to the code, and tried again (disabling the now broken unit tests with -Dmaven.test.skip=true): success! Excellent!

Final step: rename the iTunes Library.itl.processed file to iTunes Library.itl (making backup first of the original file of course). iTunes works as expected, music files are found, play count still there, “last added” dates still there.

Not that I use iTunes very often (or really at all) anymore to play music. Spotify is the scheisse these days! 😉

Updated 2011-12-16: Uploaded the patched + compiled jar (for those of you who want it)

23 comments

  1. foot

    Hi,
    very interesting I am trying to exactly the same and I’ve come to a stop due to the itl file. Would it be possible for you to edit my file for me? Can I send you a dropbox link were to download it?

  2. foot

    it DID work perfectly!! no need for me to consolidate from Windows to switch to Mac so I can keep the folder structure I have and which I don’t want to loose… thanks again a ton!!! PS SuperSync is very hand to check at the end if there are any missing tracks since it compares two XML libraries if you u want

    Thanks!!!!

    • RYan

      I’m having a bit of trouble getting this to work on my iTunes 11 on Win7 64-bit… the Google Code project doesn’t seem to have any downloads available? Where exactly do I download this program; is it an exe or do I need to download some other programs with which to run the code? Thank you in advance for any help! 🙂

      • David

        Hi!

        The “Tools for iTunes Libraries” program must be compiled first, then run (it’s a Java program). Furthermore (I haven’t checked the code recently, it might already be fixed), the code needs to be patched to fix a problem. So you’ll need to check out the code from the repository, patch it, compile it, then you can run it. All this assuming you have the Java SDK installed and build tools (java, javac compiler, maven, mercurial, etc). If you don’t want to patch + compile the code yourself, I have uploaded it as a jar file to the blog post (see the very end of the post), but this will still of course require that you have Java installed on your computer in order to run:

        $ java -Xmx512m -XX:MaxPermSize=256m -jar titl-core-0.3-SNAPSHOT.jar MoveMusic –use-urls ~/Music/iTunes/iTunes\ Library.itl "file://localhost/Volumes/Music" "file://localhost/Volumes/Multimedia/music"

  3. Miles Wolbe

    Hi David,

    Thanks so much for the detailed walkthru and for sharing your patched version.

    Do you know if MoveMusic still works on iTunes 11 itl files? When running it to move from a volume named “Old” to a volume named “New”, I received the following error:


    $ java -Xmx512m -XX:MaxPermSize=256m -jar ./titl-core-0.3-SNAPSHOT.jar MoveMusic --use-urls ./iTunes\ Library.itl "file://localhost/Volumes/Old/Music" "file://localhost/Volumes/New/Music"
    Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.kafsemo.titl.tools.Main.main(Main.java:42)
    Caused by: java.util.zip.ZipException: oversubscribed dynamic bit lengths tree
    at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:147)
    at org.kafsemo.titl.Hdfm.inflate(Hdfm.java:226)
    at org.kafsemo.titl.Hdfm.read(Hdfm.java:109)
    at org.kafsemo.titl.ProcessLibrary.process(ProcessLibrary.java:52)
    at org.kafsemo.titl.tools.MoveMusic.main(MoveMusic.java:167)
    ... 5 more

    While digging around for more info on the “iTunes Library.itl” file format, I stumbled onto this: http://code.google.com/p/picardplugins/wiki/LibraryFile

    “I read that the binary file format documentation isn’t available even to other teams at Apple, and that, at least once, they deliberately made changes just to break any code that was parsing the file so they could tell other (Apple) teams to stop doing that and use the XML file instead.”

    Given that titl apparently hasn’t been updated since the release of iTunes 11, perhaps the format has changed again?

    On a side note, one piece of info that “iTunes Library.itl” will happily divulge is the version of iTunes used to create it (found with Hex Fiend at offset 17).

    • David

      I just did a test with my latest library file (v11.0.1) and I’m not getting the ZipException you describe. I thought it might have something to do with my library being an “upgrade” from a previous version, so I moved ~/Music/iTunes to ~/Music/iTunes.bak and opened iTunes, which subsequently created new v11.0.1 library files. I added a music album to this new library, and tried the MoveMusic command again: same result, no errors, no ZipException. Another user (see the other comments) has successfully moved his v11 library as well. Strange!

      I notice there are some old bug reports mentioning a ZipException: titl issue 20 and titl issue 15. I haven’t dug in the code to see how to change this…

      Hope this info helps, and good luck!
      ./david

      • Miles Wolbe

        Thanks so much for taking the time to look into it, David!

        I tested the same “iTunes Library.itl” file (originally from iTunes 11 running under OS X 10.6) on OS X 10.7 and Windows XP; received the same error:
        java.util.zip.ZipException: oversubscribed dynamic bit lengths tree

        Then I tested a different “iTunes Library.itl” file (from iTunes 10 running under OS X 10.7) and it worked just fine.

        Thanks again!

  4. NIck

    Hi,
    I’m not savvy enough to use these tools to edit my itl file, was hoping you could make changes for me? I’m just trying to direct my library to a shared network drive now, I’d rather not lose my “date added” data using my XML (Windows 7, itunes 10.7).
    Thanks!

    • David

      Hi,

      Sure… if you want to send me your .itl file (zip it up first, then DropBox or email) I can give it a try. Most importantly, you need to tell me the two file location roots that will be find-replaced. Check your .xml file and give me the exact old location root and then new location root, look for the Location string value, e.g.:
      <key>Location</key><string>file://localhost/Volumes/Multimedia/music/Daft%20Punk/Human%20After%20All/Technologic.mp3</string>. From that example the “root” would be file://localhost/Volumes/Multimedia/music/.

      If you don’t have a way to easily share the file (DropBox or similar), I can ping you at the email address you provided and then you can mail me back with the compressed .itl file.

      ./david

      • NRS

        Any chance I could take advantage of this same offer for assistance? My dropbox account is associated with this email address. Many thanks if you’re able to assist!

  5. Michelle

    Oh thank goodness, this topic is still live! I’ve been wrestling with iTunes to get my library ported from my old XP-based pc to my Windows 7 laptop. As the folder structure is different in Win7, I was just going to find and replace all of the incorrect path information in the xml file, but as you pointed out, this doesn’t work anymore.

    I really found your post helpful, I went and got TITL, ran it (after some errors in my parameters) then held my breath in anticipation and for good luck. Alas, none came as I’m getting a FileNotFoundException being thrown over what looks like it should be a temp file created within the program (C:\tmp\iTunes Library_noCrypt_pre.itl). Could it be that there’s a permission issue that’s not being flagged when the file creation is attempted, and because it can’t be created, it then fails on write? In any case, have you any idea how to fix it?!

    Thank you again for writing such a helpful post, I find that these can read one of three ways:
    1) The helpful one : hard to find at times, especially on stack overflow.
    2) The crazy-dedicated-techie one : You need to learn a new language, install a load of software, do it on the 3rd night of the first full moon of the new Chinese calendar in the year of the Dragon (while hopping on one foot)
    3) The one that is verbatim from an API/software manual : Not helpful as the source material is usually the first port anyway.
    [Optional 4th : The post sparked by someone seeking help : Either it’s dead after two replies, it’s too niche to be useful, or it devolves into attacking the poor poster]

    You definitely fall into category 1!

    • David

      Thanks for the kind words, and I’m glad I could be of at least partial assistance!

      As far as your FileNotFoundException, could it have something to do with the filename containing a space character? It’s a shot in the dark, but perhaps try renaming your “iTunes Library.itl” to something without a space and try again (I had no problems with filenames containing spaces, but I ran this on OSX, not Windows…)?

      Good luck!

  6. Luke Smith

    I just tried compiling the latest version of titl-core-0.3-SNAPSHOT.zip which I achieved successfully. However I got a nasty java.util.zip.ZipException just like some others on here have reported.

    I just found an even easier way to achieve the same without using titl-core (well on a Mac at least). Steps are:

    1) Copy your old music to the new location say /Volumes/DirectoryB on Mac OSX
    2) Go to the directory where your existing music is stored (in my case this was /Users/Shared/Music/iTunes)
    3) Rename the directory /Users/Shared/Music/iTunes to something like /Users/Shared/Music/iTunesOLD
    4) Create a symbolic link in /Users/Shared/Music/ to the new location of the music by running a command like:

    ln -s iTunes /Volumes/DirectoryB

    5) Restart iTunes. Whenever you play a song, iTunes will follow the symbolic link and get the file from DirectoryB. In fact if you right click on the file playing and click Get Info it will even look like it’s updated its itl file to point at this location but alas I believe the iTunes Music Library.xml file will always still have the old file name. However as long as you don’t remove the symbolic link, this should still work!
    6) You can now remove your old music files by running rm -rf /Users/Shared/Music/iTunesOLD

    Hope that helps!

  7. Vitasalato

    Hi David! Thanks a lot for this usefull post, but I’m not good with that kind of things… Could you edit my “iTunes Library.itl” for me please? You’ll save 10 years of “last added”… You can shoot me an e-mail…

  8. Miles Wolbe

    “The simple solution is to modify the Location values in the iTunes Music Library.xml file, mangle the iTunes Library.itl file, then open iTunes. iTunes will then rebuild the database file based on the xml”

    This didn’t work for me with Windows XP and iTunes 11; iTunes kept overwriting the XML with a new blank one every time.

    What did work was deleting the XML and ITL files, opening iTunes, and then clicking File > Library > Import Playlist… and selecting my edited XML file.

    Thanks again for the instructions and for maintaining this thread, David!

Leave a reply to David Cancel reply