多媒体文件需要多个MediaPlayers吗?

时间:2017-05-30 03:09:54

标签: java file javafx media-player media

我正在使用JavaFX开发一个音乐库应用程序,我对如何正确使用MediaPlayer类有一些问题。

这是我目前设置和播放音频文件的方法:

Iterator<T>.iterator() = this

比方说,我有两个音频文件......

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());
    }
}

...两个按钮将这两个文件中的一个发送到上述方法:

file1.mp3
file2.mp3

通常情况下,两个音频文件会互相播放是有道理的,因为每次调用该方法时我都会创建一个新的MediaPlayer对象,但是,这个对象是静态的。也许我误解了静态对象是如何工作的,但是它不应该意味着只能存在这个对象的一个​​实例吗?反过来,这是不是意味着每当调用setMedia方法时,MediaPlayer对象的媒体都会被覆盖?

我没有找到任何方法为MediaPlayer对象“设置”或“覆盖”媒体而不创建它的新实例。它似乎没有这样做的方法。 这让我相信我必须为每个音频文件都有一个MediaPlayer对象数组。它是否正确?或者我只是在这里遗漏了什么?

2 个答案:

答案 0 :(得分:1)

你似乎对两个概念感到困惑:静态变量与单身。你在这里所说的there can only ever be one instance of this object适用于单身人士,但一般不适用于静态变量。对于静态变量,它仅表示变量的范围是全局的。换句话说,这个变量只有一个参考。

一个例子:

// This is just a general static variable
private static MediaPlayer mediaPlayer;
mediaPlayer = new MediaPlayer(...);
mediaPlayer = new MediaPlayer(...); // this second assignment is ok

// This is a singleton - note the key word `final`
private static final MediaPlayer mediaPlayer;
mediaPlayer = new MediaPlayer(...); // ok
mediaPlayer = new MediaPlayer(...); // compile error

答案 1 :(得分:1)

  

我没有找到任何方法为MediaPlayer对象“设置”或“覆盖”媒体而不创建它的新实例。它似乎没有这样做的方法。这让我相信我必须为每个音频文件都有一个MediaPlayer对象数组。它是否正确?或者我只是在这里遗漏了什么?

这是正确的。 documentation for the MediaPlayer constructor明确说明了这一点:

  

public MediaPlayer(Media media)

     

为特定媒体创建播放器。这是将Media对象与MediaPlayer关联的唯一方法:一旦创建了播放器,就无法更改。

  

也许我误解了静态对象是如何工作的,但是它不应该意味着只能存在这个对象的一个​​实例吗?

是的,你误解了这个。

MediaPlayer静态的引用仅表示您的类只有一个对MediaPlayer的引用。 (通常的说法是单个MediaPlayer引用是“所有实例共享”的类。我不喜欢它:它意味着你必须至少拥有一个类的实例,这不是真的。让它静态只是意味着MediaPlayer引用是类的属性,而不是类的实例的属性。)简单地替换引用(以便它引用不同的{{ 1}})不会从堆中删除前一个对象。它仍然存在于内存中,仍具有其所有属性等。您的类不再具有对它的引用。

通常,如果没有对象的实时引用,则它有资格进行垃圾回收。但是,在这种情况下,如果正在播放媒体,FX工具包将保持对它的引用,以使其实际上在物理上播放。 MediaPlayer定义了MediaPlayer方法来释放其底层资源。所以你的方法应该看起来像这样:

dispose

几乎可以肯定没有必要做任何事情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()); } } :它没有做任何对你有用的事情。