JavaFX setOnEndOfMedia на следующем MediaPlayer - PullRequest
0 голосов
/ 19 апреля 2020

У меня есть 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 Ответ

0 голосов
/ 19 апреля 2020

Лично я бы не создавал все экземпляры 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 секунд до конец). Но я все равно не буду создавать все экземпляры MediaPlayer с опережением времени.

...