1

我们正在使用 JavaFx MediaPlayer 播放 .mp4 格式,我的时间线有问题,我的问题是如果我们点击时间线上的任何点,它应该从那个点开始播放。为此,我使用了以下代码

timeSlider.setOnMouseClicked(new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent t) {
        mediaPlayer.seek(Duration.seconds(timeSlider.getValue()));
       }
    });

但这不能正常工作。任何人都可以帮我解决上述问题吗

提前致谢

4

3 回答 3

1

Oracle 提供了一个关于为 JavaFX 创建视频播放器控件的精彩教程。

您可以在JavaFX Ensemble应用程序中看到正在运行的教程播放器。

本教程包含有关合并播放器时间线的信息。

这是来自 Ensemble 的带有时间轴的 JavaFX 视频播放器控件的屏幕截图。

javafx媒体播放器

创建一个滑块来控制MediaView位置的步骤是:

  1. 创建MediaView和它的关联MediaPlayer
  2. 创建一个Slider来控制时间。
  3. 侦听对 的更改Slider并根据需要更新MediaPlayer位置。
  4. 监听MediaPlayer当前时间的变化,并Slider酌情更新。

示例中的某些时间滑块特定代码片段是:

// Media player
MediaPlayer mp = new MediaPlayer(new Media(MEDIA_URL));

// Time label
Label timeLabel = new Label("Time: ");
timeLabel.setMinWidth(Control.USE_PREF_SIZE);
mediaBar.getChildren().add(timeLabel);

// Time slider
timeSlider = new Slider();
HBox.setHgrow(timeSlider, Priority.ALWAYS);
timeSlider.setMinWidth(50);
timeSlider.setMaxWidth(Double.MAX_VALUE);
timeSlider.valueProperty().addListener(new InvalidationListener() {
    public void invalidated(Observable ov) {
        if (timeSlider.isValueChanging()) {
            // multiply duration by percentage calculated by slider position
            if(duration!=null) {
                mp.seek(duration.multiply(timeSlider.getValue() / 100.0));
            }
            updateValues();
       }
    }
});
....
protected void updateValues() {
    if (playTime != null && timeSlider != null && volumeSlider != null && duration != null) {
        Platform.runLater(new Runnable() {
            public void run() {
                Duration currentTime = mp.getCurrentTime();
                playTime.setText(formatTime(currentTime, duration));
                timeSlider.setDisable(duration.isUnknown());
                if (!timeSlider.isDisabled() && duration.greaterThan(Duration.ZERO) && !timeSlider.isValueChanging()) {
                    timeSlider.setValue(currentTime.divide(duration).toMillis() * 100.0);
                }
                if (!volumeSlider.isValueChanging()) {
                    volumeSlider.setValue((int) Math.round(mp.getVolume() * 100));
                }
            }
        });
    }
}
...
mp.currentTimeProperty().addListener(new ChangeListener<Duration>() {
    @Override
        public void changed(ObservableValue<? extends Duration> observable, Duration oldValue, Duration newValue) {
            updateValues();
    }
});
// and also invoke updateValues when the MediaPlayer is played, paused, etc.
于 2013-03-18T17:34:14.253 回答
0

在滑块值失效的侦听器中,您应该检查用户最近是否按下了鼠标按钮(例如,在过去 100 毫秒内)。Scala 中的示例代码(翻译成 Java 相当简单):

val timeSlider = new Slider {
  /**
   * @return true, if user was pressed mouse button within last `t` ms
   */
  def mouseWasPressedWithinLast(t: Long): Boolean =
    (System.currentTimeMillis() - lastTimeMousePressed) <= t

  private var lastTimeMousePressed = 0l

  addEventFilter(MouseEvent.MOUSE_PRESSED, (e: MouseEvent) => {
    lastTimeMousePressed = System.currentTimeMillis()
  })
}

timeSlider.valueProperty().addListener(new InvalidationListener() {
  def invalidated(ov: Observable) {
    // Position should be updated in one of the two cases:
    //   1. if user is sliding (then isValueChanging == true), or
    //   2. if user clicked on slider to set it to new position (has recently pressed mouse button).
    if (timeSlider.isValueChanging || timeSlider.mouseWasPressedWithinLast(100)) {
      updatePosition(timeSlider.getValue)
    }
  }
})
于 2013-12-26T13:05:36.127 回答
0

与原始问题相关并扩展尼古拉的观点:

使用在源代码 MediaPlayer.zip 中找到的“ http://docs.oracle.com/javafx/2/swing/media-player.htm ”中的Oracle 原始代码,该代码存在以下问题。当用户单击滑块内的按钮/旋钮小部件或旋钮外部的条形区域时,值会相应更改。然而,当媒体正在播放时,用户只能通过移动旋钮来调整播放时间位置或音量。播放视频时,滑块也会通过旋钮小部件缓慢移动。

Nikolay 的建议缓解了修复问题。应将此建议添加到两个滑块中。如果您将两个滑块都更改为下面的 YieldingSlider,即使在播放视频时以及通过单击滑块的栏或滑块的旋钮来调整滑块小部件时,您也会看到更灵敏的滑块反应。

class YieldingSlider extends Slider
{
    private long lastTimeMousePressed = 0;

    public YieldingSlider()
    {
        addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>()
        {
            @Override
            public void handle(final MouseEvent event)
            {
                lastTimeMousePressed = System.currentTimeMillis();
            }
        });
    }

    public boolean mouseWasPressedWithinLast(long t)
    {
        return (System.currentTimeMillis() - lastTimeMousePressed) <= t;
    }
}
于 2014-02-10T20:03:34.367 回答