gpt4 book ai didi

JavaFX MediaPlayer 不播放 M4A 文件

转载 作者:行者123 更新时间:2023-11-30 02:42:30 24 4
gpt4 key购买 nike

给出以下代码:

import java.io.File;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;

public class Main extends Application {

@Override
public void start(Stage stage) throws Exception {
StackPane stackPane = new StackPane();
stackPane.setOnMouseClicked((event) -> {
String path = "audio.ext";
Media media = new Media(new File(path).toURI().toString());
MediaPlayer mp = new MediaPlayer(media);
mp.setAutoPlay(true);
});
stage.setScene(new Scene(stackPane));
stage.show();
}

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

当我点击屏幕时,音频文件(audio.ext)应该播放。我可以获得 MP3 文件和 WAV 文件来播放音频。但是,当我使用 M4A 文件尝试相同的代码时,音频无法播放。

在稍微修改代码以解决问题时,我注意到一些有趣的情况。

情况 1:将 MediaPlayer 设为实例变量而不是局部变量。

如果我将 MediaPlayer 对象 (mp) 设为实例变量并在 setOnMouseClicked block 中初始化它,则音频将按预期播放我没有任何问题。

情况 2:将以下代码添加到 setOnMouseClicked block 的末尾:

MediaView mv = new MediaView(mp);
stackPane.getChildren().add(mv);

如果我这样做,那么音频将按其应有的方式播放,并且屏幕在视觉上不会发生变化(即,将 MediaView 对象添加到 StackPane 在视觉上不会发生变化改变它)。

<小时/>

我的问题是:为什么会发生这种情况,有什么方法可以让音频播放而无需使用这些解决方法?

我的一个怀疑是,MediaPlayer 的工作需要对该对象的外部引用。在情况 1 中,实例变量充当外部引用,在情况 2 中,StackPane 持有对 MediaView 的引用,而后者又具有对 MediaView 的引用。 >媒体播放器。但是,这并不能解释为什么这种情况仅发生在 M4A 文件中,而不是 MP3WAV 文件中。也许由于某种原因,MediaPlayer 将 M4A 文件视为视频文件而不是音频文件。然而,这都是猜测,我不确定为什么会发生这种情况。

最佳答案

当您不存储对象的引用时,Java 垃圾收集器可以在引用超出范围时清理它。

来自How Garbage Collection Works :

garbage collector

当您添加代码时:

MediaPlayer mp = new MediaPlayer(media);
MediaView mv = new MediaView(mp);
stackPane.getChildren().add(mv);

对媒体播放器的引用保留在 MediaView 和 StackPane 中,因此媒体播放器不会被垃圾回收。但是,当您没有保留引用的代码时,MediaPlayer 可以随时被垃圾回收。

另请注意 MediaPlayer javadoc :

The operation of a MediaPlayer is inherently asynchronous. A player is not prepared to respond to commands quasi-immediately until its status has transitioned to MediaPlayer.Status.READY, which in effect generally occurs when media pre-roll completes.

由于操作是异步的,如果您不存储对 MediaPlayer 的引用,则代码可能会受到 race condition 的影响。 ,垃圾收集器会在 MediaPlayer 完成媒体播放之前清理 MediaPlayer。由于竞争条件的本质,受其影响的代码的行为是不可预测的,这通常是一个不受欢迎的功能。

至于为什么在不保留对 MediaPlayer 的引用的情况下播放 MP3 和 WAV 文件,这可能只是运气。当您不再引用 MediaPlayer 时,垃圾回收可能会在任何时候发生。因此,在不保留引用的 MediaPlayer 中播放媒体并不是我所依赖的行为。相反,最好至少保留对 MediaPlayer 的引用,直到它完成播放关联的媒体为止。

关于JavaFX MediaPlayer 不播放 M4A 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41231404/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com