Android - 从输入流中直接播放mp3,无需写入临时文件

8
我正在创建一个输入流,用于缓冲和从云中传输mp3。
URL url = new URL("http://xxxx.yyy.com/Demo.mp3");

InputStream inputStream = url.openStream();

现在我该如何在不使用临时文件进行存储和读取的情况下从媒体播放器中回放mp3?我正在开发适用于Android Lollipop的应用程序。


以下是针对Android 6.0及以上版本的答案:(https://dev59.com/QGcs5IYBdhLWcg3wXSuU#52720388) - mahadevan gss
3个回答

1

我非常确定MediaPlayer能够处理远程URL。看看this的示例。同时,也要检查MediaPlayer类中的setDataSource方法。

编辑:既然你真的非常想使用inputstream,我认为你需要降低级别。检查AudioTrack类。这个SO answer可能会有所帮助。还有一些问题herehere,可能与此相关。


1
我不想这样做。MediaPlayer不允许我管理或获取缓冲内容。我需要操作缓冲内容,所以我想到了另一种方法,自己流式传输mp3,将其缓冲,然后将其提供给MediaPlayer。但是我找不到直接的方法来做到这一点,而不必将此缓冲区写入临时文件并从中读取以使用MediaPlayer播放!这就是我想要实现的... - Karthic Rao

1

这个问题甚至今天仍然存在 !!! 查看这些链接https://code.google.com/p/android/issues/detail?id=29870

http://www.piterwilson.com/blog/2014/03/11/android-mediaplayer-not-quite-there-yet/。 没有办法访问和控制MediaPlayer缓冲区,也无法将存储在字节数组中的缓冲mp3内容作为参数提供给MediaPlayer进行播放。因此,人们要么将mp3缓冲区转换为PCM并使用AudioTrack进行播放,要么将输入流的字节数组写入本地套接字,并使用套接字文件描述符让Mediaplayer读取,如下面的链接所述音频流缓冲


我没有看到任何人成功使用“inputstream -> socket文件描述符”方法,Android文档对于MediaPlayer的setDataSource(fd)说:“文件描述符必须是可寻址的(注意:LocalSocket不可寻址)。 ”如果我错了,请纠正我,因为我正在使用本地http服务器解决方案,这很糟糕。 - NeilS

0

我使用的将二进制数据直接传递给MediaPlayer的解决方案是使用ParcelFileDescriptor#createPipe()(API级别9)和MediaPlayer#setDataSource(java.io.FileDescriptor)

这里是示例代码(未经测试):

ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
FileDescriptor fd = pipe[0].getFileDescriptor();
mediaPlayer.setDataSource(fd);
OutputStream out = new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]);

从这一点开始,您在输出流中编写的任何内容都将被MediaPlayer接收。这非常快,因为它使用内核FIFO传输数据(没有套接字,没有TCP),据我所知,完全在RAM中(不使用实际文件)。

2
我无法使其工作,你有使用这种方法的可行示例吗? - rraallvv

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接