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

cal*_*leb 6 java media audio javafx

我是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
Run Code Online (Sandbox Code Playgroud)

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

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

任何帮助将不胜感激.

Jos*_*eda 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();
        }
    });
Run Code Online (Sandbox Code Playgroud)