Quería una manera muy simple de reproducir un archivo mp3 desde una aplicación Java. Después de algunas investigaciones, descubrí que las versiones más recientes de Java 7 SE están empacadas con JavaFX, así que pensé que lo intentaría. Esta pregunta NO se trata de reproducir archivos mp3, sino de hacer que JavaFX funcione de forma correcta.JavaFX 2.1 y subprocesos? -o bien - ¿Finaliza una aplicación JavaFX correctamente?
Por lo tanto, en mi primer experimento con JavaFX, he utilizado un código sugerido en un puesto de stackoverflow (see here) y creó, en esencia, el siguiente programa de prueba:
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
public class progtest extends Application
{
/*---------------------------------------------------------*\
FUNCTION: main()
\*---------------------------------------------------------*/
public static void main(String args[])
{
launch(args);
} /* END: main() */
/*---------------------------------------------------------*\
FUNCTION: start()
\*---------------------------------------------------------*/
@Override
public void start(Stage stage)
{
Media medMsg
=
new Media(getClass().getResource("msg.mp3").toExternalForm());
MediaPlayer medplMsg = new MediaPlayer(medMsg);
medplMsg.play();
System.out.println("Here.\n");
} /* END: start() */
}
(Esto es un poco más sofisticado que mi programa de prueba original: esta versión se produjo después de las sugerencias de jewelsea hechas en respuesta a una pregunta anterior que he publicado acerca de cómo obtener el programa que se ejecuta en absoluto (see here))
para compilar el código utilicé:.
javac -cp "c:\Program Files\Oracle\JavaFX 2.1 Runtime\lib\jfxrt.jar";..\bin -d ..\bin ..\src\progtest.java
Y, para ejecutar el código Fui a mi .. \ bin y utilicé:
java -cp .;"c:\Program Files\Oracle\JavaFX 2.1 Runtime\lib\jfxrt.jar" progtest
Este programa corre y juega la reproducción del clip. Sin embargo, el programa no regresa al símbolo del sistema a menos que haga una Ctrl-C.
Ese comportamiento parecía un tipo de problema de hilo. He visto este tipo de comportamiento muchas veces trabajando con subprocesos de Java (que, lamentablemente, tienen problemas reales que permiten salidas graciosas de los programas).
Entonces, pensé, quizás si pongo el código en su propio hilo y luego termino el hilo principal del programa cuando termina ese hilo, las cosas estarían bien. (Pude ver que esto no era del todo un pensamiento coherente, pero de todos modos, pensé que iba a tratar.) Por lo tanto, escribí la siguiente segunda versión del código:
Aquí está el hilo principal:
import javafx.application.Application;
import javafx.stage.Stage;
import Msg.*;
public class progtest2 extends Application
{
/*---------------------------------------------------------*\
FUNCTION: main()
\*---------------------------------------------------------*/
public static void main(String args[])
{
launch(args);
} /* END: main() */
/*---------------------------------------------------------*\
FUNCTION: start()
\*---------------------------------------------------------*/
@Override
public void start(Stage stage)
{
Msg msgTime = new Msg();
msgTime.passClass(getClass());
msgTime.start();
try
{
msgTime.join();
}
catch (InterruptedException e)
{
}
System.out.println("Here.\n");
} /* END: start() */
}
y aquí está el código para el hilo de mensajes que en realidad debería reproducir el archivo MP3:
package Msg;
import KeyIO.*;
import javafx.application.Application;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
public class Msg extends Thread
{
private Class classRt = null;
/*--------------------------------------------------------*\
FUNCTION: passClass()
\*--------------------------------------------------------*/
public void passClass(Class rt)
{
classRt = rt;
} /* END: passClass() */
/*--------------------------------------------------------*\
FUNCTION: run()
\*--------------------------------------------------------*/
public void run()
{
Media medMsg
= new Media(classRt.getResource("msg.mp3").toExternalForm());
MediaPlayer medplMsg = new MediaPlayer(medMsg);
medplMsg.play();
System.out.println("Leaving Msg thread.\n");
} /* END: run() */
}
(I construyó y gestionó estos archivos con el mismo comando (mutatis mutandis re los nombres de archivo y los nombres de las clases) que el anterior.)
El programa ejecuta y reproduce el archivo mp3. Antes de escuchar el archivo, verá "Dejar hilo Msg". y luego "Aquí.", que como puede ver provienen del hilo Msg y el hilo principal, respectivamente. Pero, nuevamente, el programa no termina. Tengo que presionar Ctrl-C para regresar al símbolo del sistema.
Puse una llamada System.exit() justo al final del hilo principal allí solo para ver cuál sería el comportamiento. El comportamiento fue que el clip no se escuchó. Parecía que la llamada System.exit() finalizaba el proceso antes de reproducir el clip.
Por lo tanto, a continuación intenté poner las siguientes líneas entre System.out.println ("Here. \ N"); y la System.exit() llamada que hice:.
System.out.print("Press ENTER to end...");
KeyIO.ReadLine();
(KeyIO es una clase que hice sólo por hacer la salida la entrada del teclado simplemente Los detalles no son realmente relevante aquí.)
Pensé que esto simplemente bloquearía el hilo principal para avanzar hasta que se reprodujera el clip.
Pero, no. En cambio, el clip no se reprodujo. Cuando presiono ENTER, el programa salió sin reproducir el clip.
Bien, entonces dejé ese código de bloqueo de entrada de teclado, pero saqué la llamada a System.exit(). Ahora se reproducía el clip de audio, pero el programa no terminaba de nuevo.
Urgh!
¿Alguna idea de cómo hacer que esto funcione correctamente de la manera en que es obvio que uno quisiera que funcione? Solo quiero hacer una llamada para reproducir el clip, y luego quiero poder finalizar el programa.
¡Gracias de antemano!
¡Excelente! Funciona a las mil maravillas. Publicaré el código completo a continuación. ¡Gracias, jewelsea! Muy útil. Y me ha dado mucha información acerca de cómo puedo descubrir algunas de estas cosas en el futuro. Gracias. –