best app android audio streaming music-player

app - Android-Tamaño del búfer de MediaPlayer en ICS 4.0



music player android apk (2)

¿Sería posible ver el código donde está comenzando () el MediaPlayer?

¿Estás usando el tipo de flujo de audio STREAM_MUSIC ?

player.setAudioStreamType(AudioManager.STREAM_MUSIC);

¿Has experimentado también entre player.prepareAsync (); y player.prepare () ;?

Hubo un problema similar el año pasado que recuerdo, donde la solución era: iniciar, pausar y luego encender Preparado para comenzar ():

player.setAudioStreamType(AudioManager.STREAM_MUSIC); player.setDataSource(src); player.prepare(); player.start(); player.pause(); player.setOnPreparedListener(new OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { player.start(); } });

Es poco probable que sea la solución en este caso, pero mientras gira sus ruedas, podría valer la pena intentarlo.

Estoy usando un socket como proxy para MediaPlayer para poder descargar y descifrar el audio mp3 antes de escribirlo en el socket. Esto es similar al ejemplo que se muestra en la aplicación de noticias NPR, sin embargo, estoy usando esto para todas las versiones de Android 2.1 - 4 atm.

Código de NPR StreamProxy - http://code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/StreamProxy.java

Mi problema es que la reproducción es rápida para 2.1 - 2.3, pero en Android 4.0 ICS el MediaPlayer almacena demasiados datos antes de disparar el oyente OnPrepared.

Una cantidad de ejemplo de datos escritos en el socket OutputStream antes de onPrepared ():

En SGS2 con 2.3.4 - onPrepared () después de ~ 133920 bytes

En Nexus S con 4.0.4 - onPrepared () después de ~ 961930 bytes

Esto también ocurre en el Galaxy Nexus.

Curiosamente, el emulador 4.0 no almacena tantos datos como los 4.0 dispositivos. ¿Alguien tiene un problema similar con MediaPlayer en ICS?

EDITAR

Así es como el proxy está escribiendo en el socket. En este ejemplo, proviene de un CipherInputStream cargado desde un archivo, pero lo mismo ocurre cuando se carga desde HttpResponse.

final Socket client = (setup above) // encrypted file input stream final CipherInputStream inputStream = getInputStream(file); // setup the socket output stream final OutputStream output = client.getOutputStream(); // Writing the header final String httpHeader = buildHttpHeader(file.length()); final byte[] buffer = httpHeader.getBytes("UTF-8"); output.write(buffer, 0, buffer.length); int writtenBytes = 0; int readBytes; final byte[] buff = new byte[1024 * 12]; // 12 KB while (mIsRunning && (readBytes = inputStream.read(buff)) != -1) { output.write(buff, 0, readBytes); writtenBytes += readBytes; } output.flush(); output.close();

Los encabezados HTTP que se escriben en MediaPlayer antes del audio ...

private String buildHttpHeader(final int contentLength) { final StringBuilder sb = new StringBuilder(); sb.append("HTTP/1.1 200 OK/r/n"); sb.append("Content-Length: ").append(contentLength).append("/r/n"); sb.append("Accept-Ranges: bytes/r/n" ); sb.append("Content-Type: audio/mpeg/r/n"); sb.append("Connection: close/r/n" ); sb.append("/r/n"); return sb.toString(); }

He buscado implementaciones alternativas, pero como tengo audio cifrado y el MediaPlayer no admite InputStreams como fuente de datos, mi única opción (creo ...) es usar un proxy como este.

Una vez más, esto está funcionando bastante bien Android 2.1 - 2.3, pero en ICS el MediaPlayer está almacenando una gran cantidad de estos datos antes de reproducirlos.

EDICION 2:

Pruebas adicionales muestran que esto también es un problema en el SGS2 una vez que se actualizó a Android 4.0.3. Parece que la implementación del buffering de MediaPlayer ha cambiado significativamente en 4.0. Esto es frustrante ya que la API no proporciona ninguna forma de alterar el comportamiento.

EDIT 3:

Error de Android creado. Agregue comentarios y protagonice también http://code.google.com/p/android/issues/detail?id=29870

EDIT 4:

Mi código de reproducción es bastante estándar. Tengo la llamada de inicio () en el MediaPlayer en mi método onPrepared ().

mCurrentPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mCurrentPlayer.setDataSource(url); mCurrentPlayer.prepareAsync();

Lo he intentado usando solo prepare () y también la manera recomendada de ajacian81 pero fue en vano.

Debo añadir que recientemente, un empleado de Google volvió a hablarme sobre mi pregunta y me confirmó que el tamaño del buffer se aumentó intencionalmente en ICS (para contenido HD). Se ha solicitado a los desarrolladores de API que agreguen la capacidad de establecer un tamaño de búfer en MediaPlayer.

Aunque creo que esta solicitud de cambio de API había existido antes de que yo llegara, entonces no aconsejaría a nadie que contuviera la respiración.