Android – Reproducción de mp3 desde el byte

Tengo mi archivo mp3 en byte [] (descargado de un servicio) y me gustaría reproducirlo en mi dispositivo de forma similar a cómo se puede reproducir archivos:

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

Pero parece que no puedo encontrar una manera de hacerlo. No me importaría guardar el archivo en el teléfono y luego jugarlo. ¿Cómo puedo reproducir el archivo o descargarlo y reproducirlo?

OK, gracias a todos ustedes, pero necesitaba reproducir mp3 desde el byte [] como lo obtengo del servicio web .NET (no deseo almacenar mp3 generados dinámicamente en el servidor).

Al final, hay una cantidad de “errores” para reproducir un simple mp3 … aquí hay un código para cualquiera que lo necesite:

 private MediaPlayer mediaPlayer = new MediaPlayer(); private void playMp3(byte[] mp3SoundByteArray) { try { // create temp file that will hold byte array File tempMp3 = File.createTempFile("kurchina", "mp3", getCacheDir()); tempMp3.deleteOnExit(); FileOutputStream fos = new FileOutputStream(tempMp3); fos.write(mp3SoundByteArray); fos.close(); // resetting mediaplayer instance to evade problems mediaPlayer.reset(); // In case you run into issues with threading consider new instance like: // MediaPlayer mediaPlayer = new MediaPlayer(); // Tried passing path directly, but kept getting // "Prepare failed.: status=0x1" // so using file descriptor instead FileInputStream fis = new FileInputStream(tempMp3); mediaPlayer.setDataSource(fis.getFD()); mediaPlayer.prepare(); mediaPlayer.start(); } catch (IOException ex) { String s = ex.toString(); ex.printStackTrace(); } } 

EDITAR: He escrito esta respuesta hace más de 4 años; obviamente, muchas cosas han cambiado desde entonces. Vea el comentario de Justin sobre cómo reutilizar la instancia de MediaPlayer. Además, no sé si .deleteOnExit () funcionará para usted ahora; siéntase libre de sugerir mejoras para que los archivos temporales no se acumulen.

Encontré una solución fácil al codificar mi archivo MP3 como Base64 (ya recibo los datos codificados de un servicio Restful API) y luego crear un objeto URL. Lo probé en Android 4.1.

 public void PlayAudio(String base64EncodedString){ try { String url = "data:audio/mp3;base64,"+base64EncodedString; MediaPlayer mediaPlayer = new MediaPlayer(); mediaPlayer.setDataSource(url); mediaPlayer.prepare(); mediaPlayer.start(); } catch(Exception ex){ System.out.print(ex.getMessage()); } } 

No estoy seguro acerca de bytearrays / bytestreams, pero si tiene una URL del servicio, puede intentar configurar el origen de datos en un URI de red llamando

 setDataSource(Context context, Uri uri) 

Ver los documentos API .

A partir de Android MarshMellow (Código de versión 23), hay una nueva API que lo hará posible.

MediaPlayer.setDataSource (android.media.MediaDataSource)

Puede proporcionar una implementación personalizada de MediaDataSource y ajustar un byte []. Una implementación básica dada a continuación.

 import android.annotation.TargetApi; import android.media.MediaDataSource; import android.os.Build; import java.io.IOException; @TargetApi(Build.VERSION_CODES.M) public class ByteArrayMediaDataSource extends MediaDataSource { private final byte[] data; public ByteArrayMediaDataSource(byte []data) { assert data != null; this.data = data; } @Override public int readAt(long position, byte[] buffer, int offset, int size) throws IOException { System.arraycopy(data, (int)position, buffer, offset, size); return size; } @Override public long getSize() throws IOException { return data.length; } @Override public void close() throws IOException { // Nothing to do here } } 

codigo erroneo:

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

CÓDIGO CORRECTO:

  MediaPlayer mp = new MediaPlayer(); mp.setDataSource(PATH_TO_FILE); mp.setOnpreparedListener(this); mp.prepare(); //Implement OnPreparedListener OnPrepared() { mp.start(); } 

ver API Demos ..