W książce Java Receptury (wyd. Helion 2003) w rozdziale 12 jest podany przykład aplikacji do odtwarzania różnych plików o nazwie JMFPLayer. Otóż ta aplikacja nie chce odtwarzać plików MIDI, chociaż poprawnie odtwarza inne typy audio a nawet video (AVI). MIDI nie chce zresztą odtwarzać żadna aplikacja używająca klas z JMF i zawsze zgłaszany jest podobny typ błędu. Używam Windows XP Professional, JDK 1.5.0 i JMF 2.3
Program, skopiowany od Heliona i lekko przeze mnie zmodyfikowany wygląda tak:

// 19.01.2005
//
// Teraz niepotrzebne import

com.darwinsys.util.WindowCloser;
//
import java.applet.;
import java.awt.
;
import javax.swing.;
import java.net.
;
import java.io.;
import java.util.
;
import javax.media.*;

/**

  • Program przedstawia prosty kod umożliwiający odtwarzania
  • klipów wideo przy wykorzystaniu Java Media Framework.
  • @Author Ian F. Darwin, [email protected]
  • @version $Id: JMFPlayer.java,v 1.7 2001/03/29 2006

ian Exp $
*/
public class JMFPlayer extends JPanel implements

ControllerListener {

/** Obiekt odtwarzacza /
Player thePlayer = null;
/
* Nadrzędna ramka w której działa program. /
JFrame parentFrame = null;
/
* Panel zawartości /
Container cp;
/
* Komponent wizualny (jeśli jakiś jest) /
Component visualComponent = null;
/
* Domyślny komponent kontrolny (jeśli jest) /
Component controlComponent = null;
/
* Nazwa używanego pliku multimedialnego. /
String mediaName;
/
* Adres URL używanego pliku dźwiękowego. */
URL theURL;

/** Tworzymy obiekt odtwarzacza oraz graficzny interfejs

użytkownika. */
public JMFPlayer(JFrame pf, String media) {
parentFrame = pf;
mediaName = media;
// cp = getContentPane();
cp = this;
cp.setLayout(new BorderLayout());
try {
theURL = new URL(getClass().getResource("."),

mediaName);
thePlayer = Manager.createPlayer(theURL);
thePlayer.addControllerListener(this);
} catch (MalformedURLException e) {
System.err.println("JMF - błąd

tworzenia adresu URL: " + e);
} catch (Exception e) {
System.err.println("Błąd tworzenia

odtwarzacza JMF : " + e);
return;
}
System.out.println("URL pliku = " + theURL);

   // Uruchamiamy odtwarzacz: spowoduje to przekazanie 

informacji
// do naszego obiektu ControllerListener.
thePlayer.start(); // rozpoczynamy

odtwarzanie
}

/** Metoda wywoływana w celu zatrzymania odtwarzania, na

przykład
* w wyniku kliknięcia przycisku Stop lub wybrania

odpowiedniej
* opcji z menu programu
*/
public void stop() {
if (thePlayer == null)
return;
thePlayer.stop(); // zatrzymujemy

odtwarzanie!
thePlayer.deallocate(); // zwalniamy zasoby

systemowe
}

/** Metoda wywoływana gdy chcemy zamknąć program (na

przykład
* po kliknięciu przycisku Wyjście
*/
public void destroy() {
if (thePlayer == null)
return;
thePlayer.close();
}

/** Metoda wywoływana przez JMF gdy odtwarzacz chce nas

o czymś
* poinformować
*/
public synchronized void

controllerUpdate(ControllerEvent event) {
System.out.println("controllerUpdate Event:\n"
+ event.toString() + "\n");
if(event instanceof ControllerErrorEvent) {
System.exit(1);
}
if(event instanceof RealizeCompleteEvent) {
if ((visualComponent =

thePlayer.getVisualComponent()) != null)
cp.add(BorderLayout.CENTER,

visualComponent);
if ((controlComponent =
thePlayer.getControlPanelComponent()) !=

null)
cp.add(BorderLayout.SOUTH,

controlComponent);
// zmieniamy wielkość głównego okna aplikacji
if (parentFrame != null) {
parentFrame.pack();
parentFrame.setTitle(mediaName);
}
}

}

public static void main(String[] argv) {
JFrame f = new JFrame("Odtwarzacz JMF -

demonstracja");
Container frameCP = f.getContentPane();
JMFPlayer p = new JMFPlayer(f, argv.length == 0 ?
"file:///C:/music/midi/beet5th.mid" : argv[0]);
frameCP.add(BorderLayout.CENTER, p);
f.setSize(200, 200);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //

DODANE
f.setVisible(true);
}
}

A takie były "wyniki" przekierowane do pliku

URL pliku = file://C:/prolog/java2recept/r12/test.wav
controllerUpdate Event:
javax.media.TransitionEvent[
source=com.sun.media.content.unknown.Handler@15ff48b,
previous=Unrealized,current=Realizing,target=Started]

controllerUpdate Event:
javax.media.DurationUpdateEvent[
source=com.sun.media.content.unknown.Handler@15ff48b,
duration=javax.media.Time@14b7453

controllerUpdate Event:
javax.media.RealizeCompleteEvent[
source=com.sun.media.content.unknown.Handler@15ff48b,
previous=Realizing,current=Realized,target=Started]

controllerUpdate Event:
javax.media.TransitionEvent[
source=com.sun.media.content.unknown.Handler@15ff48b,
previous=Realized,current=Prefetching,target=Started]

controllerUpdate Event:
javax.media.PrefetchCompleteEvent[
source=com.sun.media.content.unknown.Handler@15ff48b,
previous=Prefetching,current=Prefetched,target=Started]

controllerUpdate Event:
javax.media.StartEvent[
source=com.sun.media.content.unknown.Handler@15ff48b,
previous=Prefetched,current=Started,target=Started,
mediaTime=javax.media.Time@19616c7,
timeBaseTime=javax.media.Time@b166b5]

controllerUpdate Event:
javax.media.EndOfMediaEvent[
source=com.sun.media.content.unknown.Handler@15ff48b,
previous=Started,current=Prefetched,target=Prefetched,
mediaTime=javax.media.Time@133796]

URL pliku = file://C:/prolog/java2recept/r12/doszopy.mid
controllerUpdate Event:
javax.media.TransitionEvent[
source=com.sun.media.content.audio.midi.Handler@eee36c,
previous=Unrealized,current=Realizing,target=Started]

controllerUpdate Event:
javax.media.RealizeCompleteEvent[
source=com.sun.media.content.audio.midi.Handler@eee36c,
previous=Realizing,current=Realized,target=Started]

controllerUpdate Event:
javax.media.TransitionEvent[
source=com.sun.media.content.audio.midi.Handler@eee36c,
previous=Realized,current=Prefetching,target=Started]

controllerUpdate Event:
javax.media.ResourceUnavailableEvent[
source=com.sun.media.content.audio.midi.Handler@eee36c,
message=Failed to prefetch]

Czy ktoś może wyjaśnić dlaczego akurat MIDI nie działa ?
Przy okazji zaznaczam, że te same pliki MIDI są odtwarzane na tym samym komputerze przez inne programy napisane jeden w C++ Builderze 6, a drugi w "zwykłym" Borland C++ 5.2
Pliki MIDI są też odtwarzane przez inne klasy Javy