2010-11-15 12 views
5

Ehi, Sto utilizzando MediaPlayer per riprodurre un normale flusso ShoutCast. Il codice è semplice con prepareAsync() e un gestore per avviare la riproduzione. Mentre funziona perfettamente con alcuni flussi come DI.FM o ETN.FM (http://u10.di.fm:80/di_progressive), con altri (http://mp3.wpsu.org:8000/) ha vinto ' andare oltre lo stato di preparazione. Neanche altri ascoltatori vengono chiamati.Android MediaPlayer si sta preparando troppo a lungo

//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(); 

Qualsiasi feedback è apprezzato!

+1

Izvorean: utilizzare 'adb logcat', DDMS o la prospettiva DDMS in Eclipse per esaminare LogCat e cercare eventuali avvisi che potrebbero essere generati. – CommonsWare

+0

Sto usando il debug di Eclipse, ma il MediaPlayer non invia messaggi di log :( – Sergei

+0

Non so se questo è ancora valido, ma i miei 2 centesimi: 1. 1. È possibile stampare messaggi su logcat utilizzando Log. Controllare http : //developer.android.com/reference/android/util/Log.html 2. create() è un metodo migliore per creare un'istanza di un oggetto della classe MediaPlayer. Ulteriori dettagli: http://developer.android.com /reference/android/media/MediaPlayer.html#create(android.content.Context,%20android.net.Uri,%20android.view.SurfaceHolder) – Sriram

risposta

2

Penso che ci siano alcuni problemi di compatibilità con il server. Questo è piuttosto strano poiché l'emulatore lo gestisce bene nel mio caso - non solo sul mio Froyo Galaxy S, anche se è la stessa versione dell'API.

Potrebbe trattarsi di un problema di codec, problema di streaming http, non so. Ma tutti i server che falliscono tendono ad essere vecchi, con "Copyright 1998 - 2004" in basso ... Non esattamente recenti o aggiornati si potrebbe pensare.

Una possibile soluzione alternativa (che non ho ancora provato) sarebbe quella di utilizzare lo StreamProxy, che renderebbe anche il codice compatibile con 2.1 e anche con versioni precedenti. A costo di lavoro extra, codice extra, e senza dubbio bug in più ...

Nel caso in cui non si è a conoscenza di esso, v'è un altro rapporto giocatore bug per il 2.2 che può essere rilevante anche: Basic streaming audio works in 2.1 but not in 2.2

2

Sto affrontando un problema quando MP "si blocca" durante la preparazione dello stato troppo lungo (stream) e sto cercando di fermarlo usando reset(). Questo fa sì che MP si blocchi e quindi la mia intera app si blocca. Sembra che non ci sia modo di fermare MP nello stato di preparazione. Sto pensando di usare prepare() nel thread invece di prepareAsync(). Allora potrò uccidere quel thread. Per ora lo ho fatto in questo modo:

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

e funziona 4me.
Inoltre ho un contatore seguente:

@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; 
     } 
     } 

mi piacerebbe scoprire questo ascoltatore innesca preparare stato sempre. Quindi, se si innesca più di 10 volte e MP non è ancora in gioco sto solo riavviarlo:

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 è il mio enum personalizzato che ha "Preparazione" value. Inoltre mpState è una proprietà/campo di classe che contiene lo stato di MediaPlayerState corrente. Prima di iniziare prepareAsync() im impostando mpState su MediaPlayerState.Preparing dopo averlo completato, impostandolo su MediaPlayerState.Started o su un altro valore corrispondente.

+0

questo metodo richiede meno tempo a 'mediaPlayer.prepareAsync() 'e' 'mediaPlayer.start()' – Naz141

+0

In realtà questo metodo riguarda solo "come fermare MP senza ANR". Dipende da te per quanto tempo l'app attenderà che MP passi lo stato di preparazione. E puoi uccidere l'istanza MP usando il mio metodo dopo, diciamo, 5 secondi passati e MP si sta ancora preparando. – Stan