JavaFX setOnEndOfMedia на следующем 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>.

1 ответ

Решение

Лично я бы не стал создавать все 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
    }
  }
}

Это может вызвать паузу между видео. Если это неприемлемо, вы можете создать следующий MediaPlayer заблаговременно, либо одновременно с текущим MediaPlayerили когда текущий игрок достигает определенной отметки времени (например, за 10 секунд до конца). Но я до сих пор не создал бы всеMediaPlayer экземпляры заблаговременно.

Другие вопросы по тегам