Javaアプリケーションからmp3ファイルを再生するための本当に簡単な方法が欲しかったのです。調べてみると、Java 7 SEの最新バージョンがJavaFXにパッケージ化されていることがわかったので、試してみようと思いました。この質問は、mp3ファイルを再生することではなく、JavaFXを正常に動作させることについてです。
そのため、JavaFXを使用した最初の実験では、stackoverflowへの投稿で提案されたコードを使用して(ここを参照)、基本的に次のテストプログラムを作成しました。
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() */
}
(これは、元のテストプログラムよりも少し洗練されています。このバージョンは、プログラムを実行することについて投稿した以前の質問に答えて、jewelseaからの提案があった後に作成されました(ここを参照)。)
このコードをコンパイルするために私は使用しました:
javac -cp "c:\Program Files\Oracle\JavaFX 2.1 Runtime\lib\jfxrt.jar";..\bin -d ..\bin ..\src\progtest.java
そして、コードを実行するために、.. \ binディレクトリに移動し、次を使用しました。
java -cp .;"c:\Program Files\Oracle\JavaFX 2.1 Runtime\lib\jfxrt.jar" progtest
このプログラムが実行され、クリップが再生されます。ただし、Ctrl-Cを実行しない限り、プログラムはコマンドプロンプトに戻りません。
その振る舞いは、ある種のスレッドの問題のように見えました。私はこの種の振る舞いがJavaスレッドで動作するのを何度も見てきました(悲しいことに、プログラムからの正常な終了を可能にする実際の問題があります)。
そのため、コードを独自のスレッドに配置し、そのスレッドが終了したときにプログラムのメインスレッドを終了すれば、問題はないと思いました。(これは完全に説得力のある考えではないことがわかりましたが、とにかく、試してみようと思いました。)そこで、次の2番目のバージョンのコードを作成しました。
メインスレッドは次のとおりです。
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() */
}
そして、実際にmp3ファイルを再生する必要があるMsgスレッドのコードは次のとおりです。
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() */
}
(これらのファイルは、上記と同じコマンド(必要な変更を加えてファイル名とクラス名)を使用して作成および実行しました。)
プログラムが実行され、mp3ファイルが再生されます。ファイルを聞く前に、「Msgスレッドを離れる」と表示されます。次に「Here。」です。これは、ご覧のとおり、それぞれMsgスレッドとメインスレッドからのものです。しかし、繰り返しになりますが、プログラムは終了しません。コマンドプロンプトに戻るには、Ctrl-Cを押す必要があります。
動作がどうなるかを確認するために、メインスレッドの最後にSystem.exit()呼び出しを配置しました。動作は、クリップが聞こえなかったというものでした。System.exit()呼び出しは、クリップが再生される前にプロセスを終了したように見えました。
そこで、次に、System.out.println("Here。\n");の間に次の行を入れてみました。そして私が行ったSystem.exit()呼び出し:
System.out.print("Press ENTER to end...");
KeyIO.ReadLine();
(KeyIOは、キーボード入出力を単純に行うために作成したクラスです。詳細はここではあまり関係ありません。)
これにより、クリップが再生されるまでメインスレッドが進むのをブロックするだけだと思いました。
しかし、違います。代わりに、クリップは再生されませんでした。ENTERを押すと、クリップを再生せずにプログラムが終了しました。
さて、今はそのキーボード入力ブロッキングコードを残しましたが、System.exit()呼び出しを削除しました。これでオーディオクリップが再生されましたが、プログラムは再び終了しませんでした。
うーん!
これを優雅に機能させる方法について、それが機能したいと思うような明白な方法で何かアイデアはありますか?クリップを再生するために電話をかけたいだけで、プログラムを終了できるようにしたいと思います。
前もって感謝します!