多个媒体文件需要多个 MediaPlayer 吗?
Do I need multiple MediaPlayers for multiple media files?
我正在使用 JavaFX 开发一个音乐库应用程序,我在正确使用 MediaPlayer 的方式上遇到了一些问题 class。
这是我目前设置和播放音频文件的方法:
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
...以及将这两个文件之一发送到上述方法的两个按钮:
button1.setOnAction(event -> {
setMedia("file1.mp3");
});
button2.setOnAction(event -> {
setMedia("file2.mp3");
});
通常情况下,两个音频文件会相互播放是有意义的,因为我每次调用该方法时都会创建一个新的 MediaPlayer 对象,但是,该对象是静态的。也许我误解了静态对象的工作方式,但这不应该意味着这个对象只能有一个实例吗?反过来,这是否意味着无论何时调用 setMedia 方法,MediaPlayer 对象的媒体都会被覆盖?
我还没有找到任何方法来 "set" 或 "overwrite" MediaPlayer 对象的媒体而不创建它的新实例。它似乎没有这样做的方法。
这让我相信我必须为每个音频文件创建一个 MediaPlayer 对象数组。这个对吗?或者我只是在这里遗漏了什么?
您似乎混淆了两个概念:静态变量与单例。你在这里说的 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
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?
没错。 documentation for the MediaPlayer
constructor 明确说明了这一点:
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?
是的,你误解了这一点。
引用 MediaPlayer
静态仅仅意味着你的 class 只有一个引用 MediaPlayer
。 (通常的说法是,单个 MediaPlayer
引用是你的 class 的“所有实例共享”。我不喜欢这样:它有点暗示你必须至少有一个实例您的 class,这不是真的。将其设为静态实际上仅意味着 MediaPlayer
引用是 class 的 属性,而不是 属性 的 属性 class.) 的简单替换引用(使其引用不同的 MediaPlayer
)不会从堆中删除先前的对象。它仍然存在于内存中,仍然具有它的所有属性,等等。你的 class 只是不再有对它的引用。
一般来说,如果没有对对象的实时引用,那么它就有资格进行垃圾回收。然而,在这种情况下,如果媒体正在播放,则 FX 工具包将维护对它的引用,以使其保持实际物理播放。 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());
}
}
几乎可以肯定没有必要制作所有东西static
:它对你没有任何帮助。
我正在使用 JavaFX 开发一个音乐库应用程序,我在正确使用 MediaPlayer 的方式上遇到了一些问题 class。
这是我目前设置和播放音频文件的方法:
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
...以及将这两个文件之一发送到上述方法的两个按钮:
button1.setOnAction(event -> {
setMedia("file1.mp3");
});
button2.setOnAction(event -> {
setMedia("file2.mp3");
});
通常情况下,两个音频文件会相互播放是有意义的,因为我每次调用该方法时都会创建一个新的 MediaPlayer 对象,但是,该对象是静态的。也许我误解了静态对象的工作方式,但这不应该意味着这个对象只能有一个实例吗?反过来,这是否意味着无论何时调用 setMedia 方法,MediaPlayer 对象的媒体都会被覆盖?
我还没有找到任何方法来 "set" 或 "overwrite" MediaPlayer 对象的媒体而不创建它的新实例。它似乎没有这样做的方法。 这让我相信我必须为每个音频文件创建一个 MediaPlayer 对象数组。这个对吗?或者我只是在这里遗漏了什么?
您似乎混淆了两个概念:静态变量与单例。你在这里说的 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
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?
没错。 documentation for the MediaPlayer
constructor 明确说明了这一点:
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?
是的,你误解了这一点。
引用 MediaPlayer
静态仅仅意味着你的 class 只有一个引用 MediaPlayer
。 (通常的说法是,单个 MediaPlayer
引用是你的 class 的“所有实例共享”。我不喜欢这样:它有点暗示你必须至少有一个实例您的 class,这不是真的。将其设为静态实际上仅意味着 MediaPlayer
引用是 class 的 属性,而不是 属性 的 属性 class.) 的简单替换引用(使其引用不同的 MediaPlayer
)不会从堆中删除先前的对象。它仍然存在于内存中,仍然具有它的所有属性,等等。你的 class 只是不再有对它的引用。
一般来说,如果没有对对象的实时引用,那么它就有资格进行垃圾回收。然而,在这种情况下,如果媒体正在播放,则 FX 工具包将维护对它的引用,以使其保持实际物理播放。 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());
}
}
几乎可以肯定没有必要制作所有东西static
:它对你没有任何帮助。