Потоковая передача с помощью Android MediaPlayer – уловки и буферизация

У меня возникли проблемы с тем, чтобы MediaPlayer был устойчивым при потоковой передаче с URL-адреса HTTP.

Если я начну воспроизводить файл, но затем отбросить соединение (например, режим самолета), MediaPlayer#OnErrorListener генерирует значение what=1, extra=-17 а затем вскоре после what=-38, extra=0 .

В API нет документации, о которой это говорит, кроме того, что «обычно зависит от реализации». Я использую HTC Hero (ну, это G2 Touch от T-Mobile UK).

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

Как я могу лучше всего возобновить, когда соединение снова появится? (Сохранить текущий поиск предпочтений и повторить каждые 5 секунд?)

Как узнать, когда устройство решило начать воспроизведение буферизации – есть ли обратный вызов (кроме опроса isPlaying() )?

Кроме того, я не совсем уверен, что обеспечивает onBufferingUpdate . Я использую 40-минутный подкаст MP3 (64kbps bitrate) – буферизация идет 1%, 2%, 3%. Когда я ищу около 30 минут, это показывает 75%, затем, когда я возвращаюсь к началу до 5% – в чем смысл этого обратного вызова, кроме как показывать примерно то, что кэшировано?

Наконец – есть ли способ передать потоки в MP3 ?

    Взято из этого похожего вопроса о переполнении стека

    Я тоже разочарован в перехватах MEDIA_INFO_BUFFERING_START и MEDIA_INFO_BUFFERING_END … bummer.

    Я проверил приложение Pandora, и он не отображает индикатор буферизации. Когда музыка прерывается для буферизации, она просто сидит там, как будто ничего не произошло, и пользовательский интерфейс выглядит так, будто он все еще играет. Поэтому я пришел к выводу, что если вы используете MediaPlayer, просто невозможно определить, временно ли приостановлена ​​трассировка для буферизации.

    Тем не менее, я заметил, что есть несколько констант MediaPlayer, которые могут быть полезны: MEDIA_INFO_BUFFERING_START и MEDIA_INFO_BUFFERING_END. Но они доступны только в уровне API 9+, и в документах ничего не говорится о них. Я предполагаю, что они могут использоваться с OnInfoListener.

    Я разочарован, но, по крайней мере, я могу перестать крутить мои колеса и перейти к чему-то еще.

    Это можно сделать

    MediaPlayer имеет методы регистрации OnPreparedListener и OnBufferingUpdateListener

    OnPrepared будет вызываться, как только игрок забуферирует достаточно, чтобы начать играть.

    http://developer.android.com/reference/android/media/MediaPlayer.OnPreparedListener.html

    OnBufferingUpdate вызывается для обновления информации о буферизации.

    http://developer.android.com/reference/android/media/MediaPlayer.OnBufferingUpdateListener.html

    Вы также должны использовать службу Connectivity для прослушивания сетевого подключения

     public boolean hasConnectivity() { ConnectivityManager connectivityManager = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info = connectivityManager.getActiveNetworkInfo(); int netType = info.getType(); int netSubtype = info.getSubtype(); if (netType == ConnectivityManager.TYPE_WIFI) { return info.isConnected(); } else if (netType == ConnectivityManager.TYPE_MOBILE && netSubtype == TelephonyManager.NETWORK_TYPE_UMTS) { return info.isConnected(); } return false; } 

    Я думаю, вы должны перечислить потери / прирост сети. Посмотрите: Обнаружение восстановления сети 3G или Wifi

    Когда вы ищете или пропускаете или соединение потеряно, и MediaPlayer продолжает переподключиться к прокси-серверу, вы должны отправить этот ответ с Status 206 после того, как вы получите запрос и диапазон (int) от клиента.

     String headers += "HTTP/1.1 206 Partial Content\r\n"; headers += "Content-Type: audio/mpeg\r\n"; headers += "Accept-Ranges: bytes\r\n"; headers += "Content-Length: " + (fileSize-range) + "\r\n"; headers += "Content-Range: bytes "+range + "-" + fileSize + "/*\r\n"; headers += "\r\n"; 

    И когда вы получаете запрос от MediaPlayer, который не содержит Range в заголовке HTTP, тогда он запрашивает новый файл потока, в этом случае ваш заголовок ответа должен выглядеть следующим образом:

     String headers = "HTTP/1.1 200 OK\r\n"; headers += "Content-Type: audio/mpeg\r\n"; headers += "Accept-Ranges: bytes\r\n"; headers += "Content-Length: " + fileSize + "\r\n"; headers += "\r\n"; 

    Наслаждайтесь!