How to use JavaFX MediaPlayer correctly?


Question

I'm writing a simple game and trying to play sounds but I can't get it to work when I create the Media object it throws IllegalArgumentException. I'm not much of a Java coder and any help will be appreciated. Here is a sample code:

import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;

public class Main{
    public static void main(String[] args) {

        Media pick = new Media("put.mp3"); //throws here
        MediaPlayer player = new MediaPlayer(pick);
        player.play();
    }
}

Obviously "put.mp3" exists and located in the correct directory, I checked the path using: System.out.println(System.getProperty("user.dir"));

what am I doing wrong here?

1
2
3/18/2014 8:15:05 PM

Accepted Answer

The problem is because you are trying to run JavaFX scene graph control outside of JavaFX Application thread.

Run all JavaFX scene graph nodes inside the JavaFX application thread.

You can start a JavaFX thread by extending JavaFX Application class and overriding the start() method.

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) {

        Media pick = new Media("put.mp3"); // replace this with your own audio file
        MediaPlayer player = new MediaPlayer(pick);

        // Add a mediaView, to display the media. Its necessary !
        // This mediaView is added to a Pane
        MediaView mediaView = new MediaView(player);

        // Add to scene
        Group root = new Group(mediaView);
        Scene scene = new Scene(root, 500, 200);

        // Show the stage
        primaryStage.setTitle("Media Player");
        primaryStage.setScene(scene);
        primaryStage.show();

        // Play the media once the stage is shown
        player.play();
    }

    public static void main(String[] args) {
         launch(args);
    }
}
13
2/6/2018 11:51:47 AM

Ok thanks to @ItachiUchiha insight on the matter I was able to solve my problem, It seems that any code that uses javaFX must run from within javaFX application Thread but not every program has to use javaFX API. In short what I did is start my game from within the Application.start(Stage ps) like so:

import javafx.application.Application;
import javafx.stage.Stage;

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        new Game(9,9,BasicRobot.FACING.SOUTH, 19);
    }

    public static void main(String[] args) throws InterruptedException {
        launch();
    }
}

That way the Game class and everything it creates and uses can use javaFX. To play the sounds I created a Utils class:

import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;

public class Utils {

    public static void playSound(String fileName){
        Media m = new Media("file:///" + System.getProperty("user.dir").replace('\\', '/') + "/" + fileName);
        MediaPlayer player = new MediaPlayer(m);
        player.play();
    }

}

and now all I have to do to play a sound is call Utils.playSound("fileName.mp3") from anywhere inside my Game.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon