【发布时间】:2016-12-20 07:53:19
【问题描述】:
给定以下代码:
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 块中对其进行初始化,音频会正常播放,我没有任何问题。
案例 2:在 setOnMouseClicked 块的末尾添加以下代码:
MediaView mv = new MediaView(mp);
stackPane.getChildren().add(mv);
如果我这样做,那么音频会按应有的方式播放,并且屏幕不会在视觉上发生变化(即,将 MediaView 对象添加到 StackPane 不会在视觉上改变它)。
我的问题是:为什么会发生这种情况,有什么方法可以在不使用这些解决方法的情况下播放音频?
我的一个怀疑是MediaPlayer 工作需要对该对象的外部引用。在案例 1 中,实例变量用作外部引用,在案例 2 中,StackPane 持有对 MediaView 的引用,而 MediaView 又引用了 MediaPlayer。但是,这并不能解释为什么这只发生在 M4A 文件而不是 MP3 或 WAV 文件中。也许MediaPlayer 出于某种原因将M4A 文件视为视频文件而不是音频文件。但是,这都是猜测,我不确定为什么会发生这种情况。
【问题讨论】:
标签: java audio javafx javasound