Android – Воспроизведение mp3 с байта

У меня есть mp3-файл в байте [] (загружен из службы), и я хотел бы воспроизвести его на своем устройстве, аналогичном тому, как вы можете воспроизводить файлы:

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

Но я не могу найти способ сделать это. Я бы не прочь сохранить файл на телефоне, а затем воспроизвести его. Как я могу воспроизвести файл или загрузить его?

Solutions Collecting From Web of "Android – Воспроизведение mp3 с байта"

Хорошо, спасибо всем вам, но мне нужно было играть в mp3 с байта [], так как я получаю это от .NET webservice (не хочу хранить динамически созданные mp3 на сервере).

В конце – есть количество «gotchas», чтобы играть в простые mp3 … вот код для всех, кто в этом нуждается:

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

EDIT: Я написал этот ответ более 4 лет назад – очевидно, с тех пор многое изменилось. См. Комментарий Джастина о том, как повторно использовать экземпляр MediaPlayer. Кроме того, я не знаю, будет ли теперь .deleteOnExit () работать для вас – не стесняйтесь предлагать улучшения, чтобы временные файлы не накапливались.

Не уверен в bytearrays / bytestreams, но если у вас есть URL-адрес службы, вы можете попробовать установить источник данных в сетевой URI, вызвав

 setDataSource(Context context, Uri uri) 

См. Документы API .

Я нашел легкое решение, закодировав свой MP3-файл в качестве Base64 (я уже получил данные, закодированные из службы Restful API), а затем создав объект URL. Я тестировал его на 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()); } } 

Потоковое аудио с URL-адреса в Android с помощью MediaPlayer?

неверный код:

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

ПРАВИЛЬНЫЙ КОД:

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

См. API Demos ..

Начиная с Android MarshMellow (код версии 23), есть новый API, который сделает это возможным.

MediaPlayer.setDataSource (android.media.MediaDataSource)

Вы можете предоставить собственную реализацию MediaDataSource и обернуть байт []. Основная реализация приведена ниже.

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