JavaFX setOnEndOfMedia on next MediaPlayer

断了今生、忘了曾经 提交于 2021-02-11 15:37:32

问题


I have List<MediaPlayer> that is populating by

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;
}

In my case size of List<MediaPlayer> is 3. Than i use it there

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();
    }
});

First video playing, when it ends second video starts. After second video MediaPlayer stops and didn't play third video.

I understand that because of my setOnEndOfMedia that is only on first MediaPlayer. When the second video starts it doesn't have setOnEndOfMedia. How can I setOnEndOfMedia on every video in my List<MediaPlayer>.


回答1:


Personally, I would not create all the MediaPlayer instances ahead-of-time. Instead, get a list of Media objects or at least the URIs pointing to the media. Then create a method which is responsible for playing the next video when the current video ends. That method will dispose the old MediaPlayer, create the next MediaPlayer, and configure it to call the same method upon completion. For example:

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
    }
  }
}

This may cause a pause between videos. If that's not acceptable you could create the next MediaPlayer ahead-of-time, either at the same time as the current MediaPlayer or when the current player reaches a certain timestamp (e.g. 10 seconds before the end). But I still wouldn't create all the MediaPlayer instances ahead-of-time.



来源:https://stackoverflow.com/questions/61296959/javafx-setonendofmedia-on-next-mediaplayer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!