MediaPlayer.seekTo() не работает для небуферизованного положения

Я использую MediaPlayer для воспроизведения одной песни из сети. Источник данных - это URL-адрес HTTP.

Предположим, что мы имеем следующее состояние воспроизведения.

Продолжительность песни: 1:00

Текущий прогресс: 0:10

Текущий прогресс буферизации 0:30

Скажем, я хочу пропустить часть песни и искать вперед. Я делаю это с помощью метода MediaPlayer.seekTo(). Если я ищу буферную позицию (0:20), она выполняется правильно. Но если я ищу позицию, которая еще не буферизована (0:40), MediaPlayer ведет себя нечетно. Он сразу указывает, что он искал правильно, не дожидаясь заполнения буфера. Фактически, он продолжает играть в том же положении, где он был перед поиском. С этого момента метод MediaPlayer.getCurrentPosition() возвращает неправильную позицию. Когда игра заканчивается, и OnCompletionListener.onCompletion callback называется текущей позицией медиаплеера намного выше, чем полная продолжительность песни.

Любые идеи для решения этой проблемы?

Ответ 1

Вероятно, это связано с ошибкой, которая (со ссылкой на один из комментариев) в конечном итоге исправлена ​​в 2.2 http://code.google.com/p/android/issues/detail?id=4124

Ответ 2

Он был исправлен в Android 2.2 на некоторых устройствах, насколько я знаю.

Однако Android 2.2 запутывается в поисках буферизации. Хотя позиция уже буферизована, MediaPlayer отправляет запрос на сервер.

Ответ 3

Я нашел обходной путь для этой проблемы:

Сначала вы создаете OnBufferingUpdateListener:

MediaPlayer.OnBufferingUpdateListener bufferingListener = new MediaPlayer.OnBufferingUpdateListener() {
    public void onBufferingUpdate(MediaPlayer mp, int percent) {
        //code to increase your secondary seekbar
    }
};

Затем в вашем событии onProgressChanged в строке поиска выполните следующие действия:

public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {
    int secondaryPosition = seekBar.getSecondaryProgress();
    if (progress > secondaryPosition)
        seekBar.setProgress(secondaryPosition);
}

При этом вы гарантируете, что пользователь не сможет перетащить индикатор выполнения в небуферизованное положение (а также вы увидите, что забуферировано).