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