Search code examples
javaandroidaudiomedia-player

Android: Sound overlaps when playing multiple audio files in a row


I'm trying to play multiple audio files in a row. I use the MediaPlayer class in order to play multiple audio files. However, I can't figure out why the sounds are overlapping when I test it on the emulator or my phone. The relevant parts of my code are below:

    private MediaPlayer mPlayer1 = new MediaPlayer();   
    private MediaPlayer mPlayer2 = new MediaPlayer();   
    private AudioManager audioManager;


     public void permissionGrantedActions() {

    Uri uri1=Uri.parse("android.resource://com.android.packageName/" + mFile1);
    try{mPlayer1.setDataSource(getActivity(), uri1);
    }catch (IOException e) {
        e.printStackTrace();
    }

    mPlayer1.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
    mPlayer1.prepareAsync();


    mPlayer1.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        public void onPrepared(MediaPlayer mp) {
            AppLog.logString("Start Playing Sound1");
            mPlayer1.start();
        }
    });

    mPlayer1.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            // TODO Auto-generated method stub
            mPlayer1.stop();

            try {
                mPlayer1.reset();
            } catch (Exception e) {
                e.printStackTrace();
            }

            mPlayer1.release();
            AppLog.logString("Stop Playing Sound1");
        }
    });

    mPlayer2.reset();

    Uri uri2=Uri.parse("android.resource://com.android.packageName/" + mFile2);
    try {
        mPlayer2.setDataSource(getActivity(), uri2);
    }catch (IOException e) {
        e.printStackTrace();
    }

    mPlayer2.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
    mPlayer2.prepareAsync();

    mPlayer2.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        public void onPrepared(MediaPlayer mp) {
            AppLog.logString("Start Playing Sound2");
            mPlayer2.start();
        }
    });

    mPlayer2.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            // TODO Auto-generated method stub
            mPlayer2.stop();

            try {
                mPlayer2.reset();
            } catch (Exception e) {
                e.printStackTrace();
            }

            mPlayer2.release();
            AppLog.logString("Stop Playing Sound2");
        }
    });
...
}

Using the above approach, sounds are overlapping (each audio file is about 1 second long, and all 4 audio files are played in 1 second when using this code...). Any idea why it's behaving this way?


Solution

  • Well MediaPlayer is asynchron as you can see here mPlayer1.prepareAsync();
    What you need to do is to start them from the setOnCompletionListener of the previous MediaPlayer. Like this:

    //init here
    mPlayer1.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            // TODO Auto-generated method stub
            mPlayer1.stop();
    
            try {
                mPlayer1.reset();
                mPlayer2.setOnPreparedListener(new 
                MediaPlayer.OnPreparedListener() {
                    public void onPrepared(MediaPlayer mp) {
                        AppLog.logString("Start Playing Sound2");
                        mPlayer2.start();
                     }
                 }
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            mPlayer1.release();
            AppLog.logString("Stop Playing Sound1");
        }
    });