Omar
Omar

Reputation: 8145

How can I play a series of short mp3 files with no gap between them in Android?

I have a lot of short .mp3 files that I want to play one after the other.. I tried to use onCompletion event and start the next mp3, though this causes a brief gap between the 2 mp3s..

Here is the code:

void StartSound() {
    mediaplayer = MediaPlayer.create(this, Uri.parse(FILE_PATH + counter + ".mp3"));

    try {
        mediaplayer.start();
        mediaplayer.setOnCompletionListener(new OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {

                                     counter++;
                 try {
                  mp.reset();
                  mp.setDataSource(FILE_PATH + counter + ".mp3");
                  mp.prepare();

                 } catch (Exception e) {
                 e.printStackTrace();
                 }
                 mp.start();
            }
        });

    } catch (Exception e) {

    }
}

Is there a work around to this issue?

Upvotes: 3

Views: 640

Answers (2)

Virag Brahme
Virag Brahme

Reputation: 2062

Try this:

public class MainActivity extends Activity 
{
    private int[] tracks = {R.raw.explosion,R.raw.pianothingy_one,R.raw.car_horn_x};
    int mCompleted = 0;

 public void onCreate(Bundle savedInstanceState) 
 {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);

 MediaPlayer mp = MediaPlayer.create(this, tracks[0]);
 mp.setOnCompletionListener(new OnCompletionListener() 
 {
     @Override
     public void onCompletion(MediaPlayer mp)
     {
         mCompleted++;
         mp.reset();
         if (mCompleted < tracks.length) 
         {
             try
             {
                 AssetFileDescriptor afd = getResources().openRawResourceFd(tracks[mCompleted]);
                 if (afd != null) 
                 {
                     mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
                     afd.close();
                     mp.prepare();
                     mp.start();
                 }
             }
             catch (Exception ex) 
             {
                ex.printStackTrace();
             }

         } 
         else if (mCompleted>=tracks.length) 
         {
             mCompleted =0;
             try
             {
                 AssetFileDescriptor afd = getResources().openRawResourceFd(tracks[mCompleted]);
                 if (afd != null) 
                 {
                     mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
                     afd.close();
                     mp.prepare();
                     mp.start();
                 }
             }
             catch (Exception ex) 
             {
                ex.printStackTrace();
             }
         }
         else
         {
             mCompleted=0;
              mp.release();
              mp = null;
         }

     }
 });

 mp.start();

Upvotes: 0

Geobits
Geobits

Reputation: 22342

There's a workaround, but whether it's worth the trouble is up to you.

The basic idea is to decode the MP3 files to a PCM buffer, stitch them together in a byte array, and play with an AudioTrack. Seamless MP3 playback doesn't really exist with MediaPlayer. This could be a pain in the ass, though, and memory problems are likely if you're talking about full songs. For short clips, it may work, but SoundPool might be the better option.

If you're just trying to narrow the gap a bit, you can try preparing the following MediaPlayer objects before onCompletionListener. Instead of waiting to be done, prepare the next two so you can start playback faster. Then when you hit onCompletion, you can just flip which object you're using and start(). Crude double buffering, in a way.

Upvotes: 1

Related Questions