Android MediaPlayer - позиция пропускается во время буферизации

У меня странное поведение при потоковой передаче музыки на некоторых устройствах. Когда звук начинает воспроизводиться впервые, позиция прыгает и воспроизводится хаотично, пока буферизация не будет полностью завершена.

Я начал с примера кода из Tutorials Point. Я создаю MediaPlayer в OnCreate() как таковой:

// Create Media Player
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.reset();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
prepareMediaPlayer();

prepareMediaPlayer устанавливает данные следующим образом:

private void prepareMediaPlayer() {

    try {
        mediaPlayer.setDataSource(myurl);
        mediaPlayer.prepareAsync();
        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                Toast.makeText(getApplicationContext(), 
                        "Playing sound",Toast.LENGTH_SHORT).show();

                mediaPlayer.start();

            }
        });
    } catch (IOException e) {
        e.printStackTrace();
    }
}

а onBufferingUpdate выводит ход выполнения буфера:

@Override
public void onBufferingUpdate(MediaPlayer mediaPlayer, int bufferingProgress) {
    Log.v(TAG, "onBufferingUpdate() "+bufferingProgress + 
            "\ncurrentposition: "+mediaPlayer.getCurrentPosition());

    seekbar.setSecondaryProgress(bufferingProgress);
}

И вывод журнала, который я получаю, показывает, как позиция прыгает, пока медиаплеер все еще буферизуется. Я тестировал на нескольких устройствах, и это происходит только на Moto G. Это ошибка в прошивке или я что-то не так делаю?

08-29 12:50:17.934 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 4
                                                                              currentposition: 0
08-29 12:50:17.934 277/com.test.mediaplayer D/MediaPlayer: setSubtitleAnchor in MediaPlayer
08-29 12:50:17.976 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 4
                                                                              currentposition: 0
08-29 12:50:18.014 27927-27945/com.test.mediaplayer V/RenderScript: 0xb7912ee8 Launching thread(s), CPUs 4
08-29 12:50:21.414 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 8
                                                                              currentposition: 7
08-29 12:50:34.930 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 11
                                                                              currentposition: 9
08-29 12:50:50.085 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 15
                                                                              currentposition: 4
08-29 12:51:32.991 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 19
                                                                              currentposition: 2
08-29 12:53:25.036 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 22
                                                                              currentposition: 5
08-29 12:53:51.976 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 26
                                                                              currentposition: 1
08-29 12:56:26.004 27927-27946/com.test.mediaplayer I/MediaHTTPConnection: proxyName: 0.0.0.0 0
08-29 12:56:34.651 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 30
                                                                              currentposition: 10
08-29 12:56:35.862 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 33
                                                                              currentposition: 1102
08-29 12:56:38.211 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 37
                                                                              currentposition: 4
08-29 12:56:40.097 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 41
                                                                              currentposition: 9
08-29 12:56:43.034 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 44
                                                                              currentposition: 9
08-29 12:56:45.130 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 48
                                                                              currentposition: 3
08-29 12:56:49.841 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 52
                                                                              currentposition: 8
08-29 12:56:52.500 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 55
                                                                              currentposition: 8
08-29 12:56:55.748 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 63
                                                                              currentposition: 7
08-29 12:56:57.080 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 74
                                                                              currentposition: 1223
08-29 12:56:59.072 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 81
                                                                              currentposition: 979
08-29 12:57:00.073 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 81
                                                                              currentposition: 1979
08-29 12:57:03.596 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 88
                                                                              currentposition: 5
08-29 12:57:05.862 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 92
                                                                              currentposition: 4
08-29 12:57:08.291 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 95
                                                                              currentposition: 8
08-29 12:57:13.903 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 99
                                                                              currentposition: 9
08-29 12:57:14.904 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 100
                                                                              currentposition: 668
08-29 12:57:34.261 277/com.test.mediaplayer V/audio-player: onBufferingUpdate() 100
                                                                              currentposition: 224068

person Evelyn    schedule 29.08.2017    source источник
comment
Почему setOnPreparedListener вызывается два раза для одного и того же экземпляра mediaPlayer? Сначала в методе onCreate(), например mediaPlayer.setOnPreparedListener(this), а затем в методе prepareMediaPlayer() вы создаете и устанавливаете новый mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener().   -  person Stasys Skliutas    schedule 13.09.2017
comment
@StasysSkliutas Вы правы, первое setOnPreparedListener было ошибкой. Я удалил его, но результат не изменился.   -  person Evelyn    schedule 13.09.2017
comment
Некоторая дополнительная информация будет полезна. На какой версии Android код работал успешно? На какой версии Android произошел сбой кода? Каков источник потока, я предполагаю из кода, что это удаленный ресурс? Это происходит для любого файла, например song1.mp3, song2.mp3, ... или только для одного конкретного файла?   -  person Stasys Skliutas    schedule 13.09.2017
comment
В какой момент во всем этом вызывается подготовленный слушатель? Может быть полезно просмотреть журнал этого обратного вызова.   -  person Dave    schedule 14.09.2017
comment
@StasysSkliutas Эта ошибка возникает для всех удаленных исходных файлов, которые я пробовал. Moto G, на котором возникает ошибка, работает под управлением Android 6.0.1. Другие телефоны, включая эмуляторы, которые я пробовал, не испытывают этой проблемы.   -  person Evelyn    schedule 15.09.2017


Ответы (1)


В документах для разработчиков есть примечание по этому поводу:

Существует тонкая, но важная разница между вновь созданным объектом MediaPlayer и объектом MediaPlayer после вызова reset(). Вызов таких методов, как getCurrentPosition() ... в состоянии ожидания в обоих случаях является ошибкой программирования.

Он также добавляет:

Важно отметить, что состояние «Подготовка» является переходным состоянием, и поведение при вызове любого метода с побочным эффектом, когда объект MediaPlayer находится в состоянии «Подготовка», не определено.

Кажется, вам небезопасно вызывать getCurrentPosition() до обратного вызова onPrepared. Решение, вероятно, состоит в том, чтобы приостановить воспроизведение во время буферизации.

person Nick Cardoso    schedule 14.09.2017
comment
Хорошая информация, но даже когда я удаляю строку журнала, которая вызывает getCurrentPosition(), она все равно воспроизводится с ошибками. MediaPlayer не начинает воспроизведение до mediaPlayer.start() в прослушивателе onPrepared, поэтому в состоянии Preparing или Idle ничего не вызывается. - person Evelyn; 15.09.2017
comment
Так ты видишь, как прыгает большой палец, или слышишь звук? У вас есть пример приложения где-нибудь? - person Nick Cardoso; 15.09.2017
comment
И большой палец, и звук прыгают. Ссылка на пример кода находится в вопросе, единственный код, который я добавил, показан выше. - person Evelyn; 16.09.2017