¿Por qué le toma tanto tiempo a MediaPlayer de Android preparar algunas transmisiones en vivo para su reproducción?

Estoy encontrando grandes diferencias en el tiempo que tarda el MediaPlayer de Android en prepararse para la reproducción de transmisión en vivo con diferentes transmisiones.

Los datos duros

Agregué el registro entre prepareAsync () y la callback onPrepared (MediaPlayer mp) y probé varias transmisiones varias veces cada una. Los tiempos para cada flujo fueron muy consistentes (+/- un segundo), y aquí están los resultados:

  1. Corriente de noticias MPR: 27 segundos (http://newsstream1.publicradio.org:80/)
  2. Corriente de música clásica MPR: 15 segundos (http://classicalstream1.publicradio.org:80/)
  3. MPR La stream actual: 7 segundos (http://currentstream1.publicradio.org:80/)
  4. Flujo de PRI: 52 segundos (http://pri-ice.streamguys.biz/pri1)

Las pruebas se realizaron en un Nexus S con Android 2.3.4 en una conexión 3G (~ 1100 Kbps).

Reproducir archivos de audio MP3 que no se reproducen no es un problema.

Aquí hay fragmentos de cómo estoy reproduciendo las transmisiones:

Preparar MediaPlayer:

... mediaPlayer.setDataSource(playUrl); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.prepareAsync(); ... 

Luego, en onPrepared (MediaPlayer mp):

 mediaPlayer.start(); 

¿Por qué toma tanto tiempo preparar algunas transmisiones pero no otras? Los datos anteriores parecen sugerir que podría basarse en la cantidad de datos almacenados en búfer y no en la duración del contenido de audio almacenado. ¿Podría ser esto realmente?

Actualización: He probado la transmisión en vivo en dispositivos físicos con Android 1.6, 2.2 y 2.3.4 y emuladores con 1.6, 2.1, 2.2, 2.3.1 y 2.3.3. Solo veo la larga demora en 2.3.3 y 2.3.4. Las versiones anteriores comienzan a reproducirse en 5 segundos.

Parece que está almacenando una cantidad fija de datos en vez de una cantidad fija de tiempo. Para cualquiera que no sepa las velocidades de bit de varios tipos de secuencias de NPR fuera de su cabeza, los datos se ven así:

  1. Flujo de noticias de MPR: 27 segundos ( http://newsstream1.publicradio.org:80/ ), 64 kbps
  2. Corriente de música clásica de MPR: 15 segundos ( http://classicalstream1.publicradio.org:80/ ), 128 kbps
  3. MPR La stream actual: 7 segundos ( http://currentstream1.publicradio.org:80/ ), 128 kbps
  4. Intercambio de PRI: 52 segundos ( http://pri-ice.streamguys.biz/pri1 ), 32 kbps

Además de la discrepancia entre los dos flujos de 128 kbps, existe una muy buena correlación entre la tasa de bits y la duración del almacenamiento en búfer.

En cualquier caso, Android es de código abierto, por lo que siempre puedes ver lo que está haciendo . Desafortunadamente, prepareAsync() y prepare() son métodos nativos, y parece que los eventos relacionados con el búfer también se envían desde un proceso nativo.

¿Has intentado adjuntar un OnBufferingUpdateListener al MediaPlayer para obtener actualizaciones más detalladas sobre el estado del buffer? Puede ser interesante comparar la velocidad a la que se entregan los eventos y el porcentaje que el búfer llena en cada evento en las diferentes secuencias. Puede hacer una referencia cruzada con los bitrates del flujo, y si 4 segundos de almacenamiento en búfer a 32 kbps llenan el búfer el mismo porcentaje que 1 segundo de búfer a 128 kbps, entonces creo que habrá encontrado su respuesta.