当前位置: 首页 > 知识库问答 >
问题:

JavaFX媒体播放器-将进度条与媒体播放器绑定(Mac m1芯片)

伊光赫
2023-03-14

我想用媒体播放器播放来更新进度条。但是,在开始播放我的进度条后,在一秒钟内填满100%,而媒体是15秒- 5分钟长。我想不出原因。

我的代码如下:

public static ProgressBar progress = new ProgressBar();

ObjectBinding<TimeElapsed> elapsedBinding =createElapsedBindingByBindingsAPI(player);
DoubleBinding elapsedDoubleBinding =createDoubleBindingByBindingsAPI(elapsedBinding);

progress.progressProperty().bind(elapsedDoubleBinding);

这些方法是:

    public static @NotNull ObjectBinding<TimeElapsed> createElapsedBindingByBindingsAPI(
            final @NotNull MediaPlayer player
    ) {
        return Bindings.createObjectBinding(
                new Callable<TimeElapsed>() {
                    @Override
                    public TimeElapsed call() throws Exception {
                        return new TimeElapsed(player.getCurrentTime());
                    }
                },
                player.currentTimeProperty()
        );
    }



public static @NotNull DoubleBinding createDoubleBindingByBindingsAPI(
            final ObjectBinding<TimeElapsed> elapsedBinding
    ) {
        return Bindings.createDoubleBinding(
                new Callable<Double>() {
                    @Override
                    public Double call() throws Exception {

                        
                        return  elapsedBinding.getValue().getElapsed();

                    }
                },
                elapsedBinding
        );
    }

和TimeElapsed类:

static class TimeElapsed {
        private final double elapsed;

        TimeElapsed(@NotNull Duration duration) {
          
            elapsed = duration.toSeconds();
        }

        public double getElapsed() {
            return elapsed;
        }
    }

那么,1)通过播放更新进度条,2)通过点击或拖动进度条查找歌曲的代码更改是什么?

共有1个答案

唐和洽
2023-03-14

确定时,< code>ProgressBar的进度应该在< code>0.0和< code>1.0之间(包括这两个值)。这意味着您应该将当前时间除以总持续时间来获得进度,并将条形图的progress属性绑定到该值。请注意,< code>Media的持续时间是可以观察到的,并且在实例化后的某个时间一定会被设置。

至于能够在单击或拖动进度条时查找,最简单的方法——我在下面的示例中展示了这一点——是向进度条添加一个MOUSE_CLICKED和一个MOUSE_DRAGGED处理程序,确定鼠标的x位置与进度条宽度之间的比率,然后查找计算的时间。不幸的是,这种设置可能与进度条的视觉效果不完全匹配,因为实际的“栏”小于节点占用的整个空间(至少在默认样式下)。如果您想要“像素完美”行为,您可能必须创建自己的控件。

这里有一个简单的例子来演示上面讨论的内容:

import java.util.Optional;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ProgressBar;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Main extends Application {

  @Override
  public void start(Stage primaryStage) {
    var mediaView = new MediaView();

    var progressBar = new ProgressBar();
    progressBar.setMaxWidth(Double.MAX_VALUE);
    StackPane.setAlignment(progressBar, Pos.BOTTOM_CENTER);
    StackPane.setMargin(progressBar, new Insets(10));

    var root = new StackPane(mediaView, progressBar);
    primaryStage.setScene(new Scene(root, 1000, 650));
    primaryStage.setTitle("Video Progress Demo");
    primaryStage.show();

    chooseMediaFile(primaryStage)
        .ifPresentOrElse(
            uri -> {
              var media = new Media(uri);
              var mediaPlayer = new MediaPlayer(media);
              mediaPlayer.setAutoPlay(true);
              mediaView.setMediaPlayer(mediaPlayer);

              bindProgress(mediaPlayer, progressBar);
              addSeekBehavior(mediaPlayer, progressBar);
            },
            Platform::exit);
  }

  private void bindProgress(MediaPlayer player, ProgressBar bar) {
    var binding =
        Bindings.createDoubleBinding(
            () -> {
              var currentTime = player.getCurrentTime();
              var duration = player.getMedia().getDuration();
              if (isValidDuration(currentTime) && isValidDuration(duration)) {
                return currentTime.toMillis() / duration.toMillis();
              }
              return ProgressBar.INDETERMINATE_PROGRESS;
            },
            player.currentTimeProperty(),
            player.getMedia().durationProperty());
    bar.progressProperty().bind(binding);
  }

  private void addSeekBehavior(MediaPlayer player, ProgressBar bar) {
    EventHandler<MouseEvent> onClickAndOnDragHandler =
        e -> {
          var duration = player.getMedia().getDuration();
          if (isValidDuration(duration)) {
            var seekTime = duration.multiply(e.getX() / bar.getWidth());
            player.seek(seekTime);
            e.consume();
          }
        };
    bar.addEventHandler(MouseEvent.MOUSE_CLICKED, onClickAndOnDragHandler);
    bar.addEventHandler(MouseEvent.MOUSE_DRAGGED, onClickAndOnDragHandler);
  }

  private boolean isValidDuration(Duration d) {
    return d != null && !d.isIndefinite() && !d.isUnknown();
  }

  private Optional<String> chooseMediaFile(Stage owner) {
    var chooser = new FileChooser();
    chooser
        .getExtensionFilters()
        .add(new FileChooser.ExtensionFilter("Media Files", "*.mp4", "*.mp3", "*.wav"));
    var file = chooser.showOpenDialog(owner);
    return Optional.ofNullable(file).map(f -> f.toPath().toUri().toString());
  }
}
 类似资料:
  • 这可能不是一个可以接受的问题,但我现在非常绝望。 我需要一个同步java媒体播放器与快速寻找和平衡修改。 脚本: 我有一个javaFX项目,我必须在循环中播放一个非常短(50-100毫秒)的媒体文件。问题是,在重新启动之前,我需要等待一些要求。 简而言之:播放声音- javafx提供了一个我修改过的媒体播放器。 如果有人能为我指出正确的方向(图书馆/我错过的东西),我将不胜感激 ps允许的java

  • 我正在开发一个包含一些音频播放器的RecyclerView的应用程序。应用程序将下载。3gp文件(如果尚未下载)。 当我单击playAudio按钮时,音频未被播放。 这是我的适配器代码: 我怎样才能解决这个问题?

  • 我目前在一个项目中使用Javafx 2,我可能需要长时间无限循环播放一个视频。在windows上,当视频播放时,我的proifiler工具显示非常正常的图片,cpu负载不是很重(在2个内核上运行时约为2x40-50%),内存使用峰值约为250 MB,这是正常的。但是,当我在Ubuntu机器上部署应用程序时,每个内核的cpu负载达到70%左右(尽管它是一个双核atom处理器,所以假设这是正常的),内

  • 1.1.1. 多媒体播放 1.1.1. 多媒体播放 我们事实上对上游芯片厂商自带的播放器方式做了调整。 Amlogic 芯片 BaseCode 我们禁用了芯片厂商的原生代码的 libplayer 包,原因是芯片厂商的播放器是直接使用 ALSA 框架来调用音频播放功能的。 这对我们 RokidOS 平台让多个进程使用音频设备造成阻碍。基于这个因素,我们使用了 RokidOS 开发的媒体播放库 lib

  • 当我使用MediaPlayer播放mp3文件时,系统会报告错误日志:。但是RealPlayer是正常的。 我发现它的错误只发生在更高的ROM版本。像4.0版本一样,它有错误。在2.3版中,它没有这个错误。 代码: 日志猫错误:

  • 我已经成功地能够从我的服务器流MP3,现在我想显示一个媒体播放器通知与控制时,歌曲开始播放。我已经遵循了一些教程如何做到这一点,但我仍然得到错误时,试图在我的应用程序中做同样的事情。 这是我尝试在音乐开始播放时显示通知的方式 这是完整的 但是,当我运行代码并单击播放按钮时,应用程序崩溃,logcat返回此错误,但没有指向特定的代码行。

  • 我的问题是关于媒体播放器直播流从我的应用程序的url? 我正在尝试通过媒体播放器播放实时流mp3音频。