我有我的 mp3 文件在 byte 2,我想在我的设备上播放它类似于你如何播放文件:
MediaPlayer mp = new MediaPlayer(); mp.setDataSource(PATH_TO_FILE); mp.prepare(); mp.start();
但我似乎无法找到办法。我不介意将文件保存到手机然后播放。我该如何播放文件,或下载然后播放?
好的,多亏你们所有人,但我需要从 byte [1]播放 mp3,因为我从.NET webservice 那里得到了它(不希望在服务器上存储动态生成的 mp3)。
最后 - 有很多“陷阱”可以播放简单的 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(); } }
**编辑:**我在 4 年多前写过这个答案 - 显然很多事情从那时起就发生了变化。请参阅 Justin 关于如何重用 MediaPlayer 实例的评论。此外,我不知道.deleteOnExit()现在是否适合你 - 随意建议改进,以便临时文件不会堆积。
我通过将我的 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()); } }
启动 Android MarshMellow(版本代码 23),有新的 API 可以实现这一点。
MediaPlayer.setDataSource(android.media.MediaDataSource)
您可以提供 MediaDataSource 的自定义实现并包装一个字节[8]。下面给出的基本实现。
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 } }
不确定 bytearrays/bytestreams,但是如果你有来自服务的 URL,你可以尝试通过调用将数据源设置为网络 URI
setDataSource(Context context, Uri uri)
见API 文档。
错误的代码:
正确的代码:
MediaPlayer mp = new MediaPlayer(); mp.setDataSource(PATH_TO_FILE); mp.setOnpreparedListener(this); mp.prepare(); //Implement OnPreparedListener OnPrepared() { mp.start(); }
看 API 演示..
如果您的目标是 API 23 及更高版本,请创建一个这样的类
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() {} }
并使用这样
val mediaSource = MyMediaDataSource(byteArray) MediaPlayer().apply { setAudioStreamType(AudioManager.STREAM_MUSIC) setDataSource(mediaSource) setOnCompletionListener { release() } prepareAsync() setOnPreparedListener { start() } }
归功于 krishnakumarp 上面的回答和本文
6 回答
好的,多亏你们所有人,但我需要从 byte [1]播放 mp3,因为我从.NET webservice 那里得到了它(不希望在服务器上存储动态生成的 mp3)。
最后 - 有很多“陷阱”可以播放简单的 mp3 ...这里是需要它的人的代码:
**编辑:**我在 4 年多前写过这个答案 - 显然很多事情从那时起就发生了变化。请参阅 Justin 关于如何重用 MediaPlayer 实例的评论。此外,我不知道.deleteOnExit()现在是否适合你 - 随意建议改进,以便临时文件不会堆积。
我通过将我的 MP3 文件编码为 Base64(我已经收到 Restful API 服务编码的数据),然后创建一个 URL 对象,找到了一个简单的解决方案。我在 Android 4.1 中测试过它。
启动 Android MarshMellow(版本代码 23),有新的 API 可以实现这一点。
MediaPlayer.setDataSource(android.media.MediaDataSource)
您可以提供 MediaDataSource 的自定义实现并包装一个字节[8]。下面给出的基本实现。
不确定 bytearrays/bytestreams,但是如果你有来自服务的 URL,你可以尝试通过调用将数据源设置为网络 URI
见API 文档。
错误的代码:
正确的代码:
看 API 演示..
如果您的目标是 API 23 及更高版本,请创建一个这样的类
并使用这样
归功于 krishnakumarp 上面的回答和本文