Search code examples
javaaudiojavafxmedia-player

How to play multiple consecutive sound files with javaFX?


I want to play 5 sound files one after the other using javaFX. I'm struggling to play more than two in a row. This code only plays the first two sound files, then doesn't play the third one. I want to be able to play up to 5 sound files, but not having a limit would be ideal. Any help is appreciated. Thanks! I'm trying to make a talking clock that tells you the time, and I'm stuck on the part where you get it to talk.

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;

public class MediaFX extends Application{


    MediaPlayer mediaplayer; 

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

    @Override
    public void start(Stage stage){
        Media hello = new Media("file:///C:/Users/Good/Desktop/TimeFiles/one.wav");
        Media meow = new Media("file:///C:/Users/Good/Desktop/TimeFiles/oh.wav");
        Media neww = new Media("file:///C:/Users/Good/Desktop/TimeFiles/six.wav");

        mediaplayer = new MediaPlayer(hello);
        mediaplayer.play();
        mediaplayer.setOnEndOfMedia(new Runnable(){
            @Override
            public void run(){
                mediaplayer.stop();
                mediaplayer = new MediaPlayer(meow);
                mediaplayer.setAutoPlay(false);
                mediaplayer.play();
            }
        });
        mediaplayer.setOnEndOfMedia(new Runnable(){
            @Override
            public void run(){
                mediaplayer.stop();
                mediaplayer = new MediaPlayer(neww);
                mediaplayer.setAutoPlay(false);
                mediaplayer.play();
            }
        });

        VBox root = new VBox();
        root.getChildren().addAll();

        Scene scene = new Scene(root,500,500);
        stage.setScene(scene);
        stage.show();
    }

}

Solution

  • You have to find a way to create loop of certain actions in order to be able to achieve what you want. You need to :

    1. Find if there is still available songs to be played
    2. Create a new Instance of MediaPlayer and set the next song
    3. Set to check again for new song after the end of the current one.
    4. Goto to Number 1

    A nice way of doing that is by recursive calls of a init functions like below :

    import javafx.application.Application;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.scene.Scene;
    import javafx.scene.layout.VBox;
    import javafx.scene.media.Media;
    import javafx.scene.media.MediaPlayer;
    import javafx.stage.Stage;
    
    public class MediaFX extends Application {
    
        MediaPlayer mediaplayer;
    
        public static void main(String[] args) {
            launch(args);
        }
    
        @Override
        public void start(Stage stage) {
            Media hello = new Media(this.getClass().getResource("one.wav").toExternalForm());
            Media meow = new Media(this.getClass().getResource("two.wav").toExternalForm());
            Media neww = new Media(this.getClass().getResource("three.wav").toExternalForm());
    
            ObservableList<Media> mediaList = FXCollections.observableArrayList();
            mediaList.addAll(hello, meow, neww);
    
            playMediaTracks(mediaList);
    
            VBox root = new VBox();
    
            stage.setScene(new Scene(root,300,300));
            stage.show();
        }
    
        private void playMediaTracks(ObservableList<Media> mediaList) {
            if (mediaList.size() == 0)
                return;
    
            MediaPlayer mediaplayer = new MediaPlayer(mediaList.remove(0));
            mediaplayer.play();
    
            mediaplayer.setOnEndOfMedia(new Runnable() {
                @Override
                public void run() {
                    playMediaTracks(mediaList);
                }
            });
        }
    
    }