2009-12-27 18 views
79

He intentado transmitir mp3's sobre http usando la clase MediaPlayer de Android. La documentación me sugiere que esto debería ser tan fácil como:Transmitir audio desde una URL en Android usando MediaPlayer?

MediaPlayer mp = new MediaPlayer(); 
mp.setDataSource(URL_OF_FILE); 
mp.prepare(); 
mp.start(); 

Sin embargo, estoy recibiendo lo siguiente varias veces. He intentado diferentes URL también. Por favor, no me digas que la transmisión no funciona en mp3.

E/PlayerDriver( 31): Command PLAYER_SET_DATA_SOURCE completed with an error or info PVMFErrNotSupported 
W/PlayerDriver( 31): PVMFInfoErrorHandlingComplete 
E/MediaPlayer( 198): error (1, -4) 
E/MediaPlayer( 198): start called in state 0 
E/MediaPlayer( 198): error (-38, 0) 
E/MediaPlayer( 198): Error (1,-4) 
E/MediaPlayer( 198): Error (-38,0) 

Cualquier ayuda muy apreciada, gracias S

+0

Algunas preguntas: (1) la versión del SDK está usando? (2) ¿Qué dispositivo (s) está probando? Esto funciona bien en SDK 2.0.1, probando en un Droid. –

+0

Hola, Román, gracias por tomarte el tiempo. Estoy intentando esto contra 1.6 y estoy usando un HTC Hero. Lo probaré en 2.01 a la luz de tus comentarios, pero sería un resultado ridículo si esto solo funcionara en los dispositivos 2.x y superiores fuera de la caja. – Pandalover

+0

Acabo de probarlo en un emulador 2.01. No funciona desafortunadamente Estoy intrigado de probar esto contra un dispositivo real 1.6 y un dispositivo real 2.01. Estoy en las pruebas de Google el día 4. Tal vez tendré que esperar hasta entonces. Preferiría no tener que hacerlo. – Pandalover

Respuesta

2

he tenido el mismo error que tiene y resultó que no había nada malo con el código. El problema era que el servidor web estaba enviando un encabezado de tipo de contenido incorrecto.

Pruebe wireshark o algo similar para ver qué tipo de contenido está enviando el servidor web.

+0

en este caso, ¿cuál es el tipo de contenido correcto? –

+0

para archivos mp3 debería ser Content-Type: audio/mpeg Eso resolvió mi problema :) – doep

+1

¿Cómo transmitiste ese archivo? –

1

Sin mp.start llamada con un OnPreparedListener para evitar el estado cero el registro de i ..

+0

Todavía obtengo la línea de registro 05-22 20: 26: 13.625: E/MediaPlayer (23818): stop llamado en estado 0 aunque inicie mi Reproductor de Medios en la función preparada(). También tengo una función onError donde reinicio el objeto Media Player. Todavía demora hasta 2 minutos para que mi transmisión comience a reproducirse. Ver mi pregunta aquí: http://stackoverflow.com/questions/16672568/mediaplayer-error-1-1004-aka-media-error-io-trying-to-stream-music-on-samsun – marienke

35

Android MediaPlayer no soporta el streaming de MP3 de forma nativa hasta 2,2. En versiones anteriores del sistema operativo, parece solo transmitir 3GP de forma nativa. Puedes probar el código de bolsillo, aunque es viejo (hay un new version here) y tuve problemas para hacerlo pegajoso, ya que tartamudeaba cada vez que recargaba el búfer.

La aplicación NPR News para Android es de código abierto y utiliza un servidor proxy local para gestionar la transmisión de MP3 en versiones del sistema operativo anteriores a la 2.2. Se puede ver el código correspondiente en las líneas 199-216 (R94) aquí: http://code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/PlaybackService.java?r=7cf2352b5c3c0fbcdc18a5a8c67d836577e7e8e3

y esta es la clase StreamProxy: http://code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/StreamProxy.java?r=e4984187f45c39a54ea6c88f71197762dbe10e72

La aplicación NPR también está siendo cada vez más el "error (-38, 0)" a veces durante la transmisión. Esto puede ser un problema de subprocesamiento o un problema de cambio de red. Compruebe el issue tracker for updates.

+0

¿Estás absolutamente seguro de ¿esta? Según entiendo, tenía que ver con el tipo de mimo. ¿Podría verificar si t funciona con el tipo MIME correcto pre 2.1? Estoy trabajando en otra cosa ahora y no pude verificar por un tiempo. – Pandalover

+1

De acuerdo con las notas de la versión 2.2 (http://developer.android.com/sdk/android-2.2-highlights.html), incluye una "Nueva estructura de medios (Stagefright) que admite la reproducción local de archivos y la transmisión progresiva HTTP". En todas mis pruebas, no pude obtener un dispositivo 2.1 para transmitir desde un servidor de shoutcast directamente. Creo que el problema es que los servidores de shoutcast devuelven un protocolo de ICY/1.1 en lugar de HTTP/1.1 y el reproductor de medios se dispara en esto ya que no sabe cómo responder a ese contenido. – jwadsack

+0

Soy capaz de transmitir bien mp3 en mi viejo héroe htc con MediaPlayer ... – Mars

9

Supongo que estás tratando de reproducir un .pls directamente o algo similar.

probar esto:

1: el código

mediaPlayer = MediaPlayer.create(this, Uri.parse("http://vprbbc.streamguys.net:80/vprbbc24.mp3")); 
mediaPlayer.start(); 

2: el .pls

Esta URL es de la BBC sólo como un ejemplo. Fue un archivo .pls que en Linux he descargado con

wget http://foo.bar/file.pls 

y luego me abrió con vim (use su editor favorito;) y he visto las direcciones URL real dentro de este archivo. Lamentablemente, no todos los .pls son texto simple como ese.

He leído que 1.6 no sería compatible con la transmisión de mp3 a través de http, pero, acabo de probar el código obove con Android 1.6 y 2.2 y no tuve ningún problema.

buena suerte!

+0

¿Funcionaría esto con los archivos AAC? –

+6

Recuerde que si desea transmitir música, debe usar mediaplayer.prepareAsync y no mediaplayer.prepare. Por lo tanto, no puede usar mediaplayer.create() porque cualquiera de las funciones .create() lleva su objeto Media Player directamente al estado Preparado, desde el que no puede llamar a prepareAsync, lo cual debe hacer para transmitir. http://developer.android.com/reference/android/media/MediaPlayer.html – marienke

69

simple Reproductor multimedia con ejemplo de transmisión.Para la parte xml necesita un botón con el botón id1 y dos imágenes en su carpeta dibujable con el nombre button_pause y button_play y no olvide agregar el permiso de internet en su manifiesto.

public class MainActivity extends Activity { 
private Button btn; 
/** 
* help to toggle between play and pause. 
*/ 
private boolean playPause; 
private MediaPlayer mediaPlayer; 
/** 
* remain false till media is not completed, inside OnCompletionListener make it true. 
*/ 
private boolean intialStage = true; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    btn = (Button) findViewById(R.id.button1); 
    mediaPlayer = new MediaPlayer(); 
    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 
    btn.setOnClickListener(pausePlay); 

} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.activity_main, menu); 
    return true; 
} 

private OnClickListener pausePlay = new OnClickListener() { 

    @Override 
    public void onClick(View v) { 
     // TODO Auto-generated method stub 
     // TODO Auto-generated method stub 

     if (!playPause) { 
      btn.setBackgroundResource(R.drawable.button_pause); 
      if (intialStage) 
       new Player() 
         .execute("http://www.virginmegastore.me/Library/Music/CD_001214/Tracks/Track1.mp3"); 
      else { 
       if (!mediaPlayer.isPlaying()) 
        mediaPlayer.start(); 
      } 
      playPause = true; 
     } else { 
      btn.setBackgroundResource(R.drawable.button_play); 
      if (mediaPlayer.isPlaying()) 
       mediaPlayer.pause(); 
      playPause = false; 
     } 
    } 
}; 
/** 
* preparing mediaplayer will take sometime to buffer the content so prepare it inside the background thread and starting it on UI thread. 
* @author piyush 
* 
*/ 

class Player extends AsyncTask<String, Void, Boolean> { 
    private ProgressDialog progress; 

    @Override 
    protected Boolean doInBackground(String... params) { 
     // TODO Auto-generated method stub 
     Boolean prepared; 
     try { 

      mediaPlayer.setDataSource(params[0]); 

      mediaPlayer.setOnCompletionListener(new OnCompletionListener() { 

       @Override 
       public void onCompletion(MediaPlayer mp) { 
        // TODO Auto-generated method stub 
        intialStage = true; 
        playPause=false; 
        btn.setBackgroundResource(R.drawable.button_play); 
        mediaPlayer.stop(); 
        mediaPlayer.reset(); 
       } 
      }); 
      mediaPlayer.prepare(); 
      prepared = true; 
     } catch (IllegalArgumentException e) { 
      // TODO Auto-generated catch block 
      Log.d("IllegarArgument", e.getMessage()); 
      prepared = false; 
      e.printStackTrace(); 
     } catch (SecurityException e) { 
      // TODO Auto-generated catch block 
      prepared = false; 
      e.printStackTrace(); 
     } catch (IllegalStateException e) { 
      // TODO Auto-generated catch block 
      prepared = false; 
      e.printStackTrace(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      prepared = false; 
      e.printStackTrace(); 
     } 
     return prepared; 
    } 

    @Override 
    protected void onPostExecute(Boolean result) { 
     // TODO Auto-generated method stub 
     super.onPostExecute(result); 
     if (progress.isShowing()) { 
      progress.cancel(); 
     } 
     Log.d("Prepared", "//" + result); 
     mediaPlayer.start(); 

     intialStage = false; 
    } 

    public Player() { 
     progress = new ProgressDialog(MainActivity.this); 
    } 

    @Override 
    protected void onPreExecute() { 
     // TODO Auto-generated method stub 
     super.onPreExecute(); 
     this.progress.setMessage("Buffering..."); 
     this.progress.show(); 

    } 
} 

@Override 
protected void onPause() { 
    // TODO Auto-generated method stub 
    super.onPause(); 
    if (mediaPlayer != null) { 
     mediaPlayer.reset(); 
     mediaPlayer.release(); 
     mediaPlayer = null; 
    } 
} 
+0

AsyncTask funciona para mí, gracias. – Amit

+0

Funciona bien :) – vijay

+0

Hay un pequeño problema con esto, si bloqueo mi teléfono mientras se reproduce el MediaPlayer, mi aplicación se bloquea cuando lo desbloqueo. – CiaranC94

2

Uso

mediaplayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 
mediaplayer.prepareAsync(); 
mediaplayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { 
     @Override 
     public void onPrepared(MediaPlayer mp) { 
      mediaplayer.start(); 
     } 
}); 
Cuestiones relacionadas