Search code examples
javafilejavafxmedia-playermedia

Do I need multiple MediaPlayers for multiple media files?


I am developing a music library application with JavaFX and I am having some issues with how I am supposed to correctly use the MediaPlayer class.

This is my current method of setting and playing audio files:

private static MediaPlayer musicPlayer;

public static void setMedia(String path) {
    try {
        musicPlayer = new MediaPlayer(new Media(new File(path).toURI().toASCIIString()));
        musicPlayer.play();
    } catch (Exception e) {
        System.out.println("invald file");
        System.out.println(e.getMessage());
    }
}

Say for example, I have two audio files...

file1.mp3
file2.mp3

...And two buttons that send one of these two files to the above method:

button1.setOnAction(event -> {
    setMedia("file1.mp3");
});

button2.setOnAction(event -> {
    setMedia("file2.mp3");
});

Normally it would make sense that both audio files would play over each other because I am creating a new MediaPlayer object each time I call the method, however, this object is static. Maybe I am misinterpreting how static objects work, but shouldn't it mean that there can only ever be one instance of this object? And in turn, wouldn't that mean that whenever the setMedia method is called, the MediaPlayer object's media would be overwritten?

I have not found any way to "set" or "overwrite" media for a MediaPlayer object without creating a new instance of it. It does not appear to have a method to do so. This leads me to believe that I must have an array of MediaPlayer objects for each audio file. Is this correct? Or am I simply missing something here?


Solution

  • I have not found any way to "set" or "overwrite" media for a MediaPlayer object without creating a new instance of it. It does not appear to have a method to do so. This leads me to believe that I must have an array of MediaPlayer objects for each audio file. Is this correct? Or am I simply missing something here?

    That is correct. The documentation for the MediaPlayer constructor explicitly spells this out:

    public MediaPlayer(Media media)

    Create a player for a specific media. This is the only way to associate a Media object with a MediaPlayer: once the player is created it cannot be changed.


    Maybe I am misinterpreting how static objects work, but shouldn't it mean that there can only ever be one instance of this object?

    Yes, you are misinterpreting this.

    Making the reference to the MediaPlayer static merely means that your class has only one reference to a MediaPlayer. (The usual statement is that the single MediaPlayer reference is "shared by all instances" of your class. I don't like that: it sort of implies that you have to have at least one instance of your class, which isn't true. Making it static really just means that the MediaPlayer reference is a property of the class, not a property of instances of the class.) Simply replacing the reference (so that it refers to a different MediaPlayer) doesn't remove the previous object from the heap. It still exists in memory, still has all its properties, etc. Your class just no longer has a reference to it.

    In general, if there is no live reference to an object, then it is eligible for garbage collection. In this case, however, if the media is playing, the FX toolkit will maintain a reference to it in order to keep it actually physically playing. MediaPlayer defines a dispose method to release its underlying resources. So your method should probably look something like this:

    public static void setMedia(String path) {
    
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.dispose();
        }
        try {
            musicPlayer = new MediaPlayer(new Media(new File(path).toURI().toASCIIString()));
            musicPlayer.play();
        } catch (Exception e) {
            System.out.println("invald file");
            System.out.println(e.getMessage());
        }
    }
    

    There's almost certainly no need whatsoever to make everything static: it isn't doing anything helpful for you.