下一个 MediaPlayer 上的 JavaFX setOnEndOfMedia

JavaFX setOnEndOfMedia on next MediaPlayer

我有 List<MediaPlayer> 正在填充

private List<MediaPlayer> players() {

    for (String file : path.list((dir1, name) -> {
        if (name.endsWith(SUPPORTED_VIDEO_FILE_EXTENSIONS)){
            return true;
        }
        return false;
    })) {
        players.add(createPlayer(Paths.get(path + "/" + file).toUri().toString()));
        System.out.println(Paths.get(path + "/" + file).toUri().toString());
    }
    return players;
}

在我的情况下 List<MediaPlayer> 的大小是 3。比我在那里使用它

if (currentNumOfVideo == -1) {
    currentNumOfVideo = 0;
}
mv = new MediaView();
MediaPlayer currentPlayer = players.get(currentNumOfVideo);
mv.setMediaPlayer(currentPlayer);
currentPlayer.play();

players.get(currentNumOfVideo).setOnEndOfMedia(() -> {
    players.get(currentNumOfVideo).stop();
    if (currentNumOfVideo < players.size()) {
        currentNumOfVideo += 1;
        mv.setMediaPlayer(players.get(currentNumOfVideo));
        players.get(currentNumOfVideo).play();
    } else {
        currentNumOfVideo = 0;
        mv.setMediaPlayer(players.get(currentNumOfVideo));
        players.get(currentNumOfVideo).play();
    }
});

播放第一个视频,播放结束后第二个视频开始播放。在第二个视频之后 MediaPlayer 停止并且没有播放第三个视频。

我明白这是因为我的 setOnEndOfMedia 只在第一个 MediaPlayer 上。当第二个视频开始时,它没有 setOnEndOfMedia。我如何 setOnEndOfMedia 我的 List<MediaPlayer>.

中的每个视频

就个人而言,我不会提前创建所有 MediaPlayer 实例。相反,获取 Media 对象的列表或至少指向媒体的 URI。然后创建一个方法,负责在当前视频结束时播放下一个视频。该方法将处理旧的 MediaPlayer,创建下一个 MediaPlayer,并将其配置为在完成时调用相同的方法。例如:

import java.util.List;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.stage.Stage;

public class Main extends Application {

  private MediaView mediaView;

  private List<Media> media;
  private int curIndex;

  @Override
  public void start(Stage primaryStage) throws Exception {
    media = ...; // get media from somewhere

    mediaView = new MediaView();
    primaryStage.setScene(new Scene(new StackPane(mediaView), 720, 480));
    primaryStage.show();

    playNextVideo();
  }

  private void playNextVideo() {
    disposePlayer();
    if (curIndex == media.size()) {
      return; // no more videos to play
    }

    MediaPlayer player = new MediaPlayer(media.get(curIndex++));
    player.setAutoPlay(true); // play ASAP
    player.setOnEndOfMedia(this::playNextVideo); // play next video when this one ends
    mediaView.setMediaPlayer(player);
  }

  private void disposePlayer() {
    MediaPlayer player = mediaView.getMediaPlayer();
    if (player != null) {
      player.dispose(); // release resources
    }
  }
}

这可能会导致视频之间出现停顿。如果这不可接受,您可以提前创建 next MediaPlayer,或者与当前 MediaPlayer 同时创建,或者当当前玩家达到某些时间戳(例如结束前 10 秒)。但我仍然不会提前创建 all MediaPlayer 个实例。