javaandroidandroid-mediaplayerwindows-media-player

MediaPlayer problem: all songs playing at the same time


So I'm trying to play a certain mix of songs that user chooses. I'm making an array of strings that are filenames that should be played in MediaPlayer. The problem is that all of the songs play at the same time. I've tried everything but still don't know how to make sure player waits for a song to end before it starts another one.

Here's what I've tried:

public void play(View v){

        if(player==null)
        {
            while(true) {
                if(i==brojac) break; //checking if the arraylist has ended
                if(player.isPlaying()==false) {
                    i++;
                    String s = lista.get(i).toString();
                    player = MediaPlayer.create(this, (this.getResources().getIdentifier(s, "raw", this.getPackageName())));
                    player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                        @Override
                        public void onCompletion(MediaPlayer mediaPlayer) {
                            stopPlayer();
                        }
                    });
                    player.start();
                }
            }
        }

    }
private void stopPlayer()
    {
        if(player!=null)
        {
            player.release();
            player=null;
        }
    }

EDIT

With the answer below everything works,but the player is having noticable gap. I've solved it with setNextPlayer() function, but the app crashes due to recreating the player while it is playing.

void playSong(int currentSong) {
        player = MediaPlayer.create(this, currentSong);
        player1 = MediaPlayer.create(this,this.getResources().getIdentifier(lista.get(i+1).toString(),"raw",getPackageName()));
        player.setNextMediaPlayer(player1);
        player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                player.release();
                i++;
                if(i==brojac) return;
                player1.start();
                playSong(MainActivity.this.getResources().getIdentifier(lista.get(i).toString(),"raw",getPackageName()));
            }
        });
        if(i==0) {
            player.start();
        }
    }

Solution

  • I believe you want this :

    ArrayList<Integer> songs = new ArrayList<>();
        private MediaPlayer mediaPlayer;
        private int currentIndex = 0;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Field[] fields = R.raw.class.getFields();
            for (Field field : fields)
                songs.add(getResources().getIdentifier(field.getName(), "raw", getPackageName()));
            playSong(songs.get(currentIndex));
    
        }
    
    
        void playSong(int currentSong) {
            mediaPlayer = MediaPlayer.create(this, currentSong);
            mediaPlayer.setOnCompletionListener(completeListener);
            mediaPlayer.start();
        }
    
        MediaPlayer.OnCompletionListener completeListener = mp -> {
            mp.release();
            currentIndex++;
            playSong(songs.get(currentIndex));
        };
    

    Explication :

    The below code, will get all the audio files from raw folder and store them in the ArrayList called songs :

     Field[] fields = R.raw.class.getFields();
     for (Field field : fields)
                songs.add(getResources().getIdentifier(field.getName(), "raw", getPackageName()));
    

    To play song :

    void playSong(int currentSong) {
            mediaPlayer = MediaPlayer.create(this, currentSong);
            mediaPlayer.setOnCompletionListener(completeListener);
            mediaPlayer.start();
        }
    

    the OnCompletionListener listener, when the song ends, you need to increment the currentIndex so the songs.get(currentIndex) will give you the next song

    MediaPlayer.OnCompletionListener completeListener = mp -> {
            mp.release();
            currentIndex++;
            playSong(songs.get(currentIndex));
        };