Ich habe meine MP3-Datei in Byte [] (von einem Dienst heruntergeladen) und möchte sie auf meinem Gerät ähnlich wie Sie Dateien abspielen können:
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(PATH_TO_FILE);
mp.prepare();
mp.start();
Aber ich finde keinen Weg, es zu tun. Ich hätte nichts dagegen, Dateien auf dem Telefon zu speichern und sie dann abzuspielen. Wie kann ich die Datei abspielen oder herunterladen und abspielen?
OK, danke an alle, aber ich musste mp3 von Byte [] abspielen, da ich das vom .NET-Webservice bekomme (ich möchte keine dynamisch generierten MP3-Dateien auf dem Server speichern).
Am Ende gibt es eine Reihe von "Gotchas", um einfache MP3s abzuspielen. Hier ist der Code für jeden, der es braucht:
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: Ich habe diese Antwort vor mehr als 4 Jahren geschrieben - offensichtlich haben sich seitdem viele Dinge geändert. Siehe Justins Kommentar zur Wiederverwendung der MediaPlayer-Instanz. Ich weiß auch nicht, ob .deleteOnExit () jetzt für Sie funktionieren wird - schlagen Sie Verbesserungsvorschläge vor, damit sich temporäre Dateien nicht stauen.
Ich habe eine einfache Lösung gefunden, indem ich meine MP3-Datei als Base64 codierte (ich empfange bereits die von einem Restful-API-Dienst codierten Daten) und dann ein URL-Objekt erstellt. Ich habe es in Android 4.1 getestet.
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());
}
}
Mit Android MarshMellow (Versionscode 23) gibt es eine neue API, die dies ermöglicht.
MediaPlayer.setDataSource (Android.media.MediaDataSource)
Sie können eine benutzerdefinierte Implementierung von MediaDataSource bereitstellen und ein Byte [] umschließen. Eine grundlegende Implementierung wird unten gegeben.
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
}
}
Über Bytearrays/bytestreams sind Sie nicht sicher. Wenn Sie jedoch eine URL des Dienstes haben, können Sie versuchen, die Datenquelle durch Aufrufen als Netzwerk-URI festzulegen
setDataSource(Context context, Uri uri)
Siehe die API-Dokumente .
falscher Code:
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(PATH_TO_FILE);
mp.prepare();
mp.start();
RICHTIGER CODE:
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(PATH_TO_FILE);
mp.setOnpreparedListener(this);
mp.prepare();
//Implement OnPreparedListener
OnPrepared() {
mp.start();
}
siehe API Demos ..
Wenn Sie auf API 23 und höher abzielen, erstellen Sie eine solche Klasse
class MyMediaDataSource(val data: ByteArray) : MediaDataSource() {
override fun readAt(position: Long, buffer: ByteArray, offset: Int, size: Int): Int {
if (position >= data.size) return -1 // -1 indicates EOF
val endPosition: Int = (position + size).toInt()
var size2: Int = size
if (endPosition > data.size)
size2 -= endPosition - data.size
System.arraycopy(data, position.toInt(), buffer, offset, size2)
return size2
}
override fun getSize(): Long {
return data.size.toLong()
}
override fun close() {}
}
und so verwenden
val mediaSource = MyMediaDataSource(byteArray)
MediaPlayer().apply {
setAudioStreamType(AudioManager.STREAM_MUSIC)
setDataSource(mediaSource)
setOnCompletionListener { release() }
prepareAsync()
setOnPreparedListener { start() }
}
kredite an die Antwort von krishnakumarp und an diesen Artikel