要播放mp3文件,我正在使用javafx.scene.media.MediaPlayer类。
但是我注意到使用seek()方法后,currentTimeProperty不可靠。

用户选择了mp3文件时,将调用以下代码中的initMediaPlayer()方法。播放时间显示在时间滑块(=timeSlider)中,用户可以移动该时间滑块以从歌曲中的任何一点开始播放。歌曲中的当前位置也会显示在标签(=timeLabel)中。

当我使用play()开始播放时,以及当我使用pause()stop()暂停或重新启动歌曲时,一切正常。

问题是,在使用seek()之后,currentTimeProperty不再正确。
在歌曲结尾时,这变得非常明显,然后currentTimeProperty有时会比歌曲的总时间长4秒。

此问题的原因是什么,是否有解决方法?

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));
        }
    });

}

最佳答案

您需要ChangeListener<Duration>,而不是InvalidationListener

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

07-24 19:47