媒体对象上的javafx UNKNOWN持续时间

时间:2014-11-29 23:14:52

标签: java audio javafx media

我是Java和JavaFX的新手,我花了几年时间用QT开发Python,现在我正在用Java和JavaFX开发。

我正在开发一个程序,为用户设置的时间播放音乐文件,然后停止。就这样,我需要从媒体对象获取持续时间以告诉音频何时停止(基于用户时间输入),但是,媒体对象上的getDuration()方法总是返回UNKNOWN。

我在Windows 8.1和openSuSE 13.2上使用JDK8u25(最新的稳定版本)(两者都有相同的问题):

File filestring = new File("my/file/dir/file.mp3")
Media file = new Media(filestring.toURI().toString());
file.getDuration(); // Returns UNKNOWN on both wav and mp3 files
file.getDuration().toMinutes()) // Also tested with toHours() toSeconds(), toMilli()...
// Above returns NaN because the file's duration is unknown

就像测试一样,我把我的整个mp3音乐收藏(1000多首歌曲同时包含CBR和VBR)并让java遍历每个文件,所有这些都说明持续时间是未知的。我还尝试了来自多个不同来源的wav文件(只是为了确保它不是mp3格式),看看是否有变化而且......没有;只有UNKNOWN持续时间。我还检查了标签是否在位,其他每个程序都说这些文件的文件属性的长度或持续时间都很好。

奇怪的是,当我将Media对象传递到MediaPlayer时,文件播放效果非常好。虽然我可以使用外部库来获取长度,但是看到整个程序使用java和javafx库,这将更容易和更简化。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:16)

如果您阅读Media课程的javadoc,它会说您应该等待媒体播放器做好准备:

  

媒体信息是异步获取的,因此在实例化类之后不一定立即可用。但是,如果实例已与MediaPlayer关联且该播放器已转换为Status.READY状态,则所有信息均应可用

所以你只需要创建MediaPlayer的实例并听取Status.READY

    File filestring = new File("my/file/dir/file.mp3");
    Media file = new Media(filestring.toURI().toString());  

    MediaPlayer mediaPlayer = new MediaPlayer(file);

    mediaPlayer.setOnReady(new Runnable() {

        @Override
        public void run() {

            System.out.println("Duration: "+file.getDuration().toSeconds());

            // display media's metadata
            for (Map.Entry<String, Object> entry : file.getMetadata().entrySet()){
                System.out.println(entry.getKey() + ": " + entry.getValue());
            }

            // play if you want
            mediaPlayer.play();
        }
    });

答案 1 :(得分:1)

看起来媒体需要一些时间才能完全初始化。在getDuration行之前添加一个Thread sleep,然后再试一次!