Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javafx UNKNOWN duration on Media object

I am a newbie to both Java and JavaFX, I've spent the last couple years developing on Python with QT, and I am now developing in Java and JavaFX.

I am developing a program that plays music files for the users set time and then stops. Be that as such, I am in need of getting the duration from the Media Object in order to tell the audio when to stop (based on the users time input), however, the getDuration() method on a media object always returns UNKNOWN.

I am using JDK8u25 (the latest stable release) on both Windows 8.1 and openSuSE 13.2 (both have the same issue):

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

Just as a test, I put my whole mp3 music collection (1,000+ songs with both CBR and VBR) and had java iterate through each file and all of them said duration was UNKNOWN. I also tried wav files from multiple different sources (just to make sure it wasn't the mp3 format) to see if that changed and...nothing; nothing but UNKNOWN for duration. I also checked to make sure the tags are inplace which every other program says the length or duration in the files properties for these files are good.

What's weird is that the file plays perfectly when I pass the Media object into a MediaPlayer. Though I could use an external library for getting the length, but seeing as the whole program uses java and javafx libraries, this would be much easier and more streamlined.

Any help would be greatly appreciated.

like image 904
caleb Avatar asked Nov 29 '14 23:11

caleb


1 Answers

If you read the javadoc for Media class, it says you should wait for the media player to be ready:

The media information is obtained asynchronously and so not necessarily available immediately after instantiation of the class. All information should however be available if the instance has been associated with a MediaPlayer and that player has transitioned to Status.READY status

So you just need to create an instance of MediaPlayer and listen for the 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();
        }
    });
like image 137
José Pereda Avatar answered Nov 07 '22 12:11

José Pereda