Android - 播放仍在下载的歌曲

时间:2017-03-30 08:01:38

标签: java android streaming android-mediaplayer exoplayer

我创建了一个应用,其中多个设备可以在局域网中相互连接,并可以播放彼此设备中的歌曲。

现在,当设备A从设备B请求歌曲时,B通过套接字将歌曲文件发送回A.歌曲完成下载后,A开始使用MediaPlayer播放。

现在问题在于,即使在高速局域网上,完成取出歌曲也需要几秒钟,因此在选择歌曲和实际播放之间会有明显的延迟开始。

我想找到一种播放歌曲的方法,同时还在下载。以下是我找到的一些可能的解决方案,但由于某些原因无法进行探索:

  1. MediaPlayer文档中,我注意到一个构造函数采用MediaDataSource实现,允许我在MediaPlayer需要时手动返回部分媒体文件,这样我就可以推迟返回字节,直到它完成下载(如果它还没有完成下载),有效地表现为"缓冲"行动。这似乎是一个解决方案,但不幸的是,我的应用程序的minSdk设置为16而MediaDataSource仅为23及以上,所以我无法尝试。

  2. 一种选择是使用MediaPlayer' setDataSource(FileDescriptor fd, long offset, long length)方法。这将允许我告诉MediaPlayer只播放歌曲的某个字节。这样,我可以等待文件的更多部分(或整个文件)变得可用,然后使用setNextMediaPlayer()并传入一个新的MediaPlayer对象,该对象准备整首歌曲并且可以寻找前一个媒体播放器对象将停止播放的点,以便进行无缝转换。 但是这还存在另一个问题。我需要能够计算在第一个未完成的媒体播放器对象的最后指定字节处达到的毫秒位置。否则,我不知道寻找下一个媒体播放器对象的位置,以便获得无缝过渡。对于有损格式,这种计算似乎是不可能的。

  3. 我真的不知道这个选项是否有效,我只是做出假设。我注意到setDataSource()需要一个Uri。如果该Uri指向手机上的文件,则媒体播放器只会加载整个文件。但是,如果Uri指向需要流式传输的互联网上的音频文件,它会自动识别它并处理下载和缓冲的所有细节。所以我想知道的是,是否有可能将设备B上的歌曲作为Uri暴露给设备A,以便媒体播放器只是把它视为互联网上的一首歌?这一次我一直在使用套接字并手动将文件从一个设备复制到另一个设备,所以我不知道这是如何工作的。有谁可以解释这是否可能?

    这实际上是我没有探索过" stream"从一台设备到另一台设备的歌曲。这是因为我希望将歌曲缓存在设备B上,以便稍后如果我切换到另一首歌然后从设备A返回之前播放的歌曲,它就不应该再次播放它。它应该只播放缓存的副本。

  4. 最后,我遇到了ExoPlayer。它似乎提供了大量的自定义。看起来我可以自定义它的类来处理所有的缓冲。但是文档和示例很少,对我来说太复杂了。我不知道怎么把它拉下来。这个解决方案对我想达到的目标来说太复杂了吗?

  5. 希望有人能在这里指出我正确的方向。

1 个答案:

答案 0 :(得分:0)

使用此处的答案结束:

MediaPlayer stutters at start of mp3 playback

此解决方案设置MediaPlayer可用于流式传输文件的本地服务器。当这些字节可用时,服务器仅向MediaPlayer发送字节。否则,它会阻塞,直到有更多字节可用。因此,MediaPlayer将其缓冲,就好像它是来自Web服务器的文件一样。

我接受了该答案中提供的同一课程,并根据我的情况进行了调整。