Java and the iTunes COM interface REDUX

This entry has now been superseded by the Using the iTunes COM Interface with Java and Swing article, which contains a fuller explanation of how to use the iTunes COM interface with Java

Well, yesterday I said that I’d managed to get Java talking to iTunes in Windows, using the COM interface. Then I updated, and said that this had changed again. Lets try and write a less muddled entry today, shall we?

I’m using the JACOB interface now. The reason that it wasn’t working yesterday was that I needed to update the jacob.dll from the one on the JACOB homepage, to the jacob.dll hosted on the yahoo group for the project (you’ll probably need to join the group to get at this file). I’ve now got JACOB working with a Java 1.5 install on a Windows XP Pro SP2 box. (UPDATE: Just download the newer files from the new SourceForge JACOB project pages. They’ve been recompiled, and work nicely with Java 1.5)

I’ve written a new little test class which grabs hold of a reference to the iTunes COM interface, starts listening for any events produced by iTunes, changes the internal iTunes volume to 90% and then toggles the play state of the iTunes player. So, if the player was playing, then it would become paused, and vice versa. Once this has all happened, the class continues listening for any events generated by iTunes, until the user presses enter. The class then releases the reference to the iTunes COM interface, and exits gracefully.

import com.jacob.com.*;
import com.jacob.activeX.*;

public class ComPrototype {
  public ComPrototype() {
    ComThread.InitMTA(true);
    Dispatch sControl = null;
    ActiveXComponent sC = null;
    ITunesEvents te = null;

    try {

      sC = new ActiveXComponent("iTunes.Application");

      // gets hold of a handle onto iTunes
      sControl = (Dispatch)sC.getObject();

      // registers events produced by iTunes with the iTunesEvents class
      te = new ITunesEvents();
      DispatchEvents de = new DispatchEvents(sControl, te);

      // changes the volume to 90% and then toggles the Play/Pause value
      Dispatch.put(sControl, "SoundVolume", 90);
      Dispatch.call(sControl, "PlayPause");

      // the test class will end when the user presses enter
      System.in.read();

    } catch (Exception e) {
      e.printStackTrace();
    } finally {
    // without the release, iTunes still thinks there is
    // an application using its COM interface, and nothing
    // else can receive any events.
    sC = null;
    te = null;
    ComThread.Release();
    System.out.println("Finished finally");
    System.exit(0);
    }
  }


  public static void main(String args[]) throws Exception {
    ComPrototype com = new ComPrototype();
  }

  protected class ITunesEvents {
    public void OnDatabaseChangedEvent(Variant[] args) {
      System.out.println("OnDatabaseChangedEvent");
    }

    public void OnPlayerPlayEvent(Variant[] args) {
      System.out.println("OnPlayerPlayEvent");

      Dispatch event = (Dispatch)args[0].getDispatch();

      System.out.println("Artist: " + Dispatch.get(event, "Artist"));
      System.out.println("Album: " + Dispatch.get(event, "Album"));
      System.out.println("Name: " + Dispatch.get(event, "Name"));
    }

    public void OnPlayerStopEvent(Variant[] args) {
      System.out.println("OnPlayerStopEvent");
    }

    public void OnPlayerPlayingTrackChangedEvent(Variant[] args) {
      System.out.println("OnPlayerPlayingTrackChangedEvent");
    }
  }
}

This should be about all you need to be able to work out how to get Java talking to the iTunes COM model in its entirety. I may write a full article about this at a later date though if it is wanted/needed.

If you enjoyed reading this and would like other people to read it as well, please add it to del.icio.us, digg or furl.

If you really enjoyed what you just read, why not buy yourself something from Amazon? You get something nice for yourself, and I get a little bit of commission to pay for servers and the like. Everyone's a winner!

comments (1) | write a comment | permalink | View blog reactions

Comments

  1. by Alex on February 14, 2007 11:46 AM

    Thx to publish your source codes. Very useful! I got a problem. I have java 1.5 and Jacob 1.11.1.

    The class ITunesEvents need to be public and not protected otherwise the folowing error is shown :

    java.lang.IllegalArgumentException: InvocationProxy only public classes can receive event notifications at com.jacob.com.InvocationProxy.(InvocationProxy.java:80) at com.jacob.com.DispatchEvents.(DispatchEvents.java:111) at com.jacob.com.DispatchEvents.(DispatchEvents.java:84) at com.jacob.com.DispatchEvents.(DispatchEvents.java:70) at ComPrototype.(ComPrototype.java:20) at ComPrototype.main(ComPrototype.java:45)

other relevant pages

about wwm

workingwith.me.uk is a resource for web developers created by Neil Crosby, a web developer who lives and works in London, England. More about the site.

Neil Crosby now blogs at The Code Train and also runs NeilCrosby.com, The Ten Word Review and Everything is Rubbish.