2010-11-15 12 views
5

Hola, Estoy usando MediaPlayer para reproducir una transmisión regular de ShoutCast. El código es sencillo con prepareAsync() y un controlador para iniciar la reproducción. Si bien funciona sin problemas con algunas transmisiones como DI.FM o ETN.FM (http://u10.di.fm:80/di_progressive), con otras (http://mp3.wpsu.org:8000/) ganó ' pasar el estado de preparación. No se llama tampoco a otros oyentes.Android MediaPlayer se está preparando demasiado tiempo

//Uri streamUri = Uri.parse("http://u10.di.fm:80/di_progressive"); /* works */ 
Uri streamUri = Uri.parse("http://mp3.wpsu.org:8000/"); /* stuck on prepare state */ 
MediaPlayer mediaPlayer = new MediaPlayer(); 
mediaPlayer.setOnPreparedListener(new OnPreparedListener() { 
    public void onPrepared(MediaPlayer mp) { 
     mp.start(); 
    } 
}); 
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 
mediaPlayer.setDataSource(this.getBaseContext(), streamUri); 
mediaPlayer.prepareAsync(); 

¡Cualquier comentario es apreciado!

+1

Izvorean: Use 'adb logcat', DDMS o la perspectiva DDMS en Eclipse para examinar LogCat y busque cualquier advertencia que pueda surgir. – CommonsWare

+0

Estoy usando depuración de Eclipse, pero el MediaPlayer no muestra mensajes de registro :( – Sergei

+0

No sé si esto todavía es válido, pero mis 2 centavos: 1. 1. Puede imprimir mensajes en logcat usando Log. Compruebe http : //developer.android.com/reference/android/util/Log.html 2. create() es un método mejor para crear instancias de un objeto de la clase MediaPlayer. Detalles adicionales aquí: http://developer.android.com /reference/android/media/MediaPlayer.html#create(android.content.Context,%20android.net.Uri,%20android.view.SurfaceHolder) – Sriram

Respuesta

2

Creo que hay algunos problemas de compatibilidad con el extremo del servidor. Esto es bastante extraño ya que el emulador lo maneja bien en mi caso, simplemente no en mi Froyo Galaxy S, aunque es la misma versión de API.

Podría ser un problema de códec, problema de transmisión http, no sé. Pero todos los servidores que fallan tienden a ser antiguos, con "Copyright 1998 - 2004" en la parte inferior ... No exactamente reciente o actual, pensaría.

Una posible solución alternativa (que aún no he probado) sería utilizar el StreamProxy, que también haría su código compatible con versiones 2.1 y posiblemente también anteriores. A costa de un trabajo extra, código adicional, y sin duda los errores adicionales ...

En caso de que no son conscientes de ello, hay otro jugador informe de errores para 2.2 que puede ser relevante también: Basic streaming audio works in 2.1 but not in 2.2

2

Estoy enfrentando un problema cuando MP se "bloquea" en el estado de preparación durante demasiado tiempo (transmisión) y estoy tratando de detenerlo mediante el restablecimiento(). Esto hace que MP se bloquee y, por lo tanto, toda mi aplicación se congela. Parece que no hay forma de detener a MP en la preparación del estado. Estoy pensando en usar prepare() envuelto en thread en lugar de prepareAsync(). Entonces podré matar ese hilo. Por ahora lo hice de la siguiente manera:

private void actionCancel(){ 
      try { 
       mp.setDataSource(new String()); 
      } catch (Exception e) { 
       e.printStackTrace(); 
       android.util.Log.d(TAG,"actionCancel(): mp.setDataSource() exception"); 
       mp.reset(); 
      } 
} 

y funciona 4me.
Además Tengo un contador siguiente:

@Override 
    public void onBufferingUpdate(final MediaPlayer mp, final int percent) { 

     if (!mp.isPlaying()){ 
//   android.util.Log.d(TAG,"onBufferingUpdate(): onBufferingUpdateCount = "+onBufferingUpdateCount); 
      if (onBufferingUpdateCount>MAX_BUFFERING_UPDATES_AT_PREPARING_STATE) 
       restartMP(); 
      onBufferingUpdateCount++; 
      return; 
     } 
     } 

que me gustaría descubrir este oyente siempre se dispara al preparar estado. Así que si se dispara más de 10 veces y MP todavía no está jugando sólo estoy reiniciarlo:

private void restartMP(){ 
     if (mp!=null) 
      if (mpState==MediaPlayerState.Preparing) 
       actionCancel(); 
      else 
       mp.reset(); 
    else 
     mp = new MediaPlayer(); 
     mpState = MediaPlayerState.Idle; 
     onBufferingUpdateCount=0; 
     //isRequestCancelled=false; 
     requestTrackInfoStartedAt=0; 
     requestPlay(); 
} 

nota MediaPlayerState es mi enumeración personalizada que tiene "Preparación" de valor. También mpState es una propiedad/campo de clase que contiene el estado actual de MediaPlayerState. Antes de comenzar, prepareAsync() im configurando mpState en MediaPlayerState. Preparando después de que termine, configúrelo en MediaPlayerState.Started u otro valor correspondiente.

+0

hace que este método tome menos tiempo para 'mediaPlayer.prepareAsync() 'y para' mediaPlayer.start() ' – Naz141

+0

En realidad, este método trata sobre" cómo detener MP sin ANR "solamente. Depende de usted cuánto tiempo esperará la aplicación a que MP apruebe el estado de preparación. Y puedes matar la instancia de MP usando mi método después, digamos, 5s pasaron y MP aún se está preparando. – Stan

Cuestiones relacionadas