(помощь все еще нужна) Как сделать функцию воспроизведения видео, которая возвращается, когда видео закончилось?

Итак, я использую JavaFX и хочу провести эксперимент, в котором мне нужно воспроизвести много видео и взаимодействовать с пользователем. Для этой настройки я хотел бы написать функцию, которая получает имя файла и воспроизводит видео с этим именем. Но он должен вернуться только тогда, когда видео закончится, а не раньше. Что-то вроде этого:

private void play(URI name){
    MediaPlayer mediaPlayer = new MediaPlayer(new Media(name));
    mediaPlayer.setAutoPlay(true);
    view.setMediaPlayer(mediaPlayer);
}

Однако эта функция возвращается до того, как видео закончится, что делает выполнение программы полным беспорядком. Я знаю, что в MediaPlayer есть функция setOnEndOfMedia(Runnable), но я не уверен, как я мог бы потенциально использовать это для достижения своей цели.

Это код, который у меня есть на данный момент. Но это не работает. Проблема в том, что оба видео воспроизводятся одновременно, вероятно, потому, что функция воспроизведения возвращается, как только она запустила видео. Я также попытался просто добавить цикл while (true) в конце функции воспроизведения, чтобы он застрял там до возврата; in .setOnEndOfMedia вызывается, что вообще предотвращает воспроизведение любого видео.

КОД:

static MediaView view;

@Override
public void start(Stage stage) throws IOException, URISyntaxException, InterruptedException {
    // Create full screen scene
    Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
    stage.setFullScreen(true);
    Scene scene = new Scene(new Group(), dim.getWidth(), dim.getHeight());
    stage.setScene(scene);
    stage.show();

    // Create the view and add it to the Scene.
    view = new MediaView();
    ((Group)scene.getRoot()).getChildren().add(view);

    play("videol");
    play("video2");
}

private static void play(String name) throws InterruptedException {
    Media media = new Media(uri(name));
    MediaPlayer player = new MediaPlayer(media);
    player.setOnReady(() -> {
        player.play();
        player.setOnEndOfMedia(() -> {
            player.dispose();
            return;
        });
    });
    view.setMediaPlayer(player);
}

private static String uri(String name) {
    return Paths.get("clips/" + name + ".mp4").toUri().toString();
}

public static void main(String[] args) {
    launch(args);
}

person Joan    schedule 15.04.2017    source источник


Ответы (1)


Сохраняю свой оригинальный материал, так как он полезен для других.

В любом случае проблема с вашим кодом заключается в том, что вы вызываете метод дважды, сразу после себя. Вам нужно вызвать метод из части EndOfMedia. Если вы хотите, вы можете создать список, а для параметра при использовании рекурсии вы можете использовать list.poll(), чтобы взять и удалить первую строку в списке. Затем, когда список пуст, вы можете просто вернуться к интерфейсу. Просто некоторые идеи.

Я предлагаю вам создать метод для воспроизведения вашей музыки, который принимает String в качестве параметра, затем эта строка будет использоваться для поиска ее эквивалента в хэш-карте, скажем, HashMap<String, MediaPlayer>. Затем к той части, где вам действительно нужна помощь. Я предлагаю вам написать что-то вроде этого:

    mediaPlayer.setOnReady(() -> {
        mediaPlayer.play();
        mediaPlayer.setOnEndOfMedia(() -> {
            mediaPlayer.dispose();
            MusicPlayer();
        });
    });

По сути, вы воспроизводите медиафайл, когда он готов, а затем, в конце, избавляетесь от него и снова вызываете метод, а в том случае, когда мой код использует рекурсию и вызывает метод MusicPlayer, вы можете вместо этого «вернуться». Извините, если это плохо объяснено, если вам нужна дополнительная помощь, просто прокомментируйте ниже.

person Politic Revolutionnaire    schedule 16.04.2017
comment
Я попробовал ваш код, где заменил MusicPlayer() на return;. Однако, когда я пытаюсь воспроизвести несколько видео друг за другом (например, play (video_a); play (video_b); play (video_c);), он воспроизводит только первое видео, а затем остается замороженным. Однако он выполнил весь код, я проверил это с помощью отпечатков. - person Joan; 16.04.2017
comment
КОРРЕКЦИЯ: Он воспроизводит все видео одновременно (то есть не только первое). Итак, как мне предотвратить возврат первого вызова функции до того, как видео закончится? - person Joan; 16.04.2017
comment
Вы уверены, что используете тип мультимедиа, поддерживаемый Javafx, также можете ли вы предоставить больше кода, чтобы я мог лучше вам помочь? - person Politic Revolutionnaire; 17.04.2017
comment
Все видео, которые я играю, в формате mp4. Я добавил код в OP. - person Joan; 17.04.2017