2017-02-08 9 views
1

В моем приложении для Android я хочу последовательно воспроизводить звук, который был разделен на части раньше. Каждая часть представляет собой Wave-файл длиной 2-3 секунды.Воспроизведение звука последовательно без задержки между частями [Android]

Я успешно выполняю это, но у меня есть заметная задержка между этими частями.

Мой код теперь выглядит так -

localMediaPlayer = new MediaPlayer[3]; 
localMediaPlayer[0] = MediaPlayer.create(this, R.raw.sound_1); 
localMediaPlayer[1] = MediaPlayer.create(this, R.raw.sound_2); 
localMediaPlayer[2] = MediaPlayer.create(this, R.raw.sound_3); 

public void onClick_localBtn(View v){ 
    Toast.makeText(this, "Play Local Sound", Toast.LENGTH_LONG).show(); 
    localMediaPlayer[0].start(); 
    localMediaPlayer[0].setOnCompletionListener(new MediaPlayer.OnCompletionListener(){ 
     public void onCompletion(MediaPlayer mp) { 
     localMediaPlayer[1].start(); 
     } 
     }); 
    localMediaPlayer[1].setOnCompletionListener(new MediaPlayer.OnCompletionListener(){ 
     public void onCompletion(MediaPlayer mp) { 
      localMediaPlayer[2].start(); 
     } 
    }); 
} 

Как я могу улучшить свой код, что эти части будут играть гладко и без задержек, как если бы это был один звуковой файл?

Спасибо.

+0

это, очевидно, приведет к небольшому периоду загрузки и воспроизведения этого другого клипа. –

ответ

0

Когда вы начинаете играть свою (N) й медиаплеера, вызовите prepareAsync() на вашем (N + 1) -й медиаплеера:

localMediaPlayer[0].start(); 
localMediaPlayer[1].prepareAsync(); 
    localMediaPlayer[0].setOnCompletionListener(new MediaPlayer.OnCompletionListener(){ 
     public void onCompletion(MediaPlayer mp) { 
     localMediaPlayer[1].start(); 
     localMediaPlayer[2].prepareAsync(); 
     } 
     }); 
    localMediaPlayer[1].setOnCompletionListener(new MediaPlayer.OnCompletionListener(){ 
     public void onCompletion(MediaPlayer mp) { 
      localMediaPlayer[2].start(); 
     } 
    }); 

Edit

На основе вашего обновления и ваш комментарий , возможно, лучшим способом было бы время воспроизведения следующего медиаплеера в соответствии с продолжительностью предыдущего игрока минус какая-то дельта:

private static final int DURATION_DELTA = 1000; 

private Handler mHandler = new Handler(); 

public void playMediaPlayer(final int index) { 
    if (index >= localMediaPlayer.length || localMediaPlayer[index] == null) 
     return; 


    localMediaPlayer[index].start(); 
    final int duration = localMediaPlayer[index].getDuration(); 

    mHandler.postDelayed(new Runnable() { 

     @Override 
     public void run() { 
      playMediaPlayer(index + 1); 
     } 
    }, duration - DURATION_DELTA); 
} 

Этот код будет в основном воспроизводить медиаплеер, а затем планировать воспроизведение следующего медиаплеера примерно за 1 секунду до окончания следующего медиаплеера. Это немного «взломанный», но вы можете поиграть с ним (значение DURATION_DELTA), пока не получите лучшие результаты.

+0

Gil, в этом случае я получил ошибку: 'java.lang.IllegalStateException: не удалось выполнить метод для android: onClick' –

+0

попробуйте заменить вызовы prepareAsync() с помощью prepare() –

+0

Поскольку я узнал теперь из [документации MediaPlayer] (https://developer.android.com/reference/android/media/MediaPlayer.html) в моем случае, потому что я использую метод create(), мой localMediaPlayer [] уже находится в подготовленном состоянии. Я обновил вопрос с остальной частью кода. У вас есть другие мысли? Это должно быть каким-то образом решить это, потому что задержка очень заметна прямо сейчас. Спасибо, Гил! –