如何使用javafx播放视频时使用时间轴

时间:2013-03-18 11:14:28

标签: javafx-2

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

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

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

提前致谢

3 个答案:

答案 0 :(得分:1)

Oracle提供了一个关于creating a Video Player Control for JavaFX的精彩教程。

您可以在JavaFX Ensemble应用程序中查看教程播放器。

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

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

javafxmediaplayer

创建滑块以控制MediaView位置的步骤如下:

  1. 创建MediaView,并将其与MediaPlayer
  2. 相关联
  3. 创建Slider以控制时间。
  4. 聆听Slider的更改并根据需要更新MediaPlayer位置。
  5. 聆听更改为MediaPlayer当前时间并根据需要更新Slider
  6. 示例中的某些时间滑块特定代码段是:

    // 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.
    

答案 1 :(得分: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)
    }
  }
})

答案 2 :(得分: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;
    }
}