2013-06-18 5 views
6

Um eine mp3-Datei abzuspielen, verwende ich die Klasse javafx.scene.media.MediaPlayer. Aber ich habe festgestellt, dass die currentTimeProperty nach der Verwendung der seek() Methode nicht zuverlässig ist.javaFX MediaPlayer getCurrentTime() unzuverlässig

Die Methode initMediaPlayer() im folgenden Code wird aufgerufen, wenn der Benutzer eine MP3-Datei ausgewählt hat. Die Wiedergabezeit wird in einem Zeitschieberegler (=timeSlider) angezeigt, den der Benutzer verschieben kann, um die Wiedergabe von jedem Punkt des Songs aus zu starten. Die aktuelle Position im Song wird auch in einem Label angezeigt (=timeLabel).

Wenn ich die Wiedergabe mit play() starte, und wenn ich den Song mit pause() oder stop() pausiere oder neu starte, funktioniert alles gut. Das Problem ist, dass nach seek() die currentTimeProperty nicht mehr korrekt ist. Dies wird gegen Ende des Songs sehr bemerkbar, dann ist die currentTimeProperty manchmal bis zu 4 Sekunden länger als die Gesamtzeit des Songs.

Was ist die Ursache für dieses Problem und gibt es eine Möglichkeit, um es zu umgehen?

private void initMediaPlayer() { 
    try { 
     audio = new Media(audioFile.toURI().toURL().toString()); 
     audioPlayer = new MediaPlayer(audio); 
    } catch (MalformedURLException ex) { 
     Logger.getLogger(MainWindowController.class.getName()) 
      .log(Level.SEVERE, null, ex); 
    } 

    audioPlayer.currentTimeProperty().addListener(new InvalidationListener() { 
     public void invalidated(Observable ov) { 
      Duration time = audioPlayer.getCurrentTime(); 
      Duration total = audioPlayer.getTotalDuration(); 

      if (!timeSlider.isValueChanging() && 
       total.greaterThan(Duration.ZERO)){ 

       timeSlider.setValue(time.toMillis()/total.toMillis() * 100); 
      } 

      timeLabel.setText(formatTime(time,total)); 
     } 
    }); 

    timeSlider.valueChangingProperty().addListener(new InvalidationListener() { 
     public void invalidated(Observable ov) { 
      audioPlayer.seek(audioPlayer.getTotalDuration() 
       .multiply(timeSlider.getValue()/100.0)); 
     } 
    }); 

} 
+0

Haben Sie eine [SSCCE] (http://sscce.org/), die Ihr Problem darstellt? – ItachiUchiha

Antwort

1

Sie wollen ChangeListener<Duration>, nicht InvalidationListener.

audioPlayer.currentTimeProperty().addListener((observableValue, oldDuration, newDuration) -> { 
    System.out.println("Player:" + observableValue + " | Changed from playing at: " + oldDuration + " to play at " + newDuration); 
}); 
+0

Wären Sie in der Lage, Ihrer Antwort ein bisschen mehr Details zu geben? – NT3RP

+1

@ NT3RP Ich habe ein Beispiel Code hinzugefügt. Er fügt nur den falschen Zuhörer hinzu. Ich bin mir nicht sicher, welche Folgefragen es geben könnte. :) – Xabster