繁体   English   中英

Android Media Player:从文件下载到文件和流

[英]Android Media Player: Download to File and Stream From File

我正在使用Android的MediaPlayer播放使用DownloadManager从互联网同时下载的MP3文件。 我知道MediaPlayer直接流的功能,但我不想使用它:

通过下载和同时从文件流式传输获得的明显优势就是这样,文件被存储并且之后可在本地获得。

  • 这原则上起作用 - 即使没有完全下载, MediaPlayer也会开始播放该文件。 (顺便说一句,我的问题不在于我无法让MediaPlayer播放。)
  • 问题是,当MediaPlayer到达开始播放时的下载状态时,它会停止并调用onCompletion (澄清:假设我开始玩时,我们假设该文件下载了12%。当玩家以12%的比例到达该位置时,它会停止。)
  • 快速注释:当通过DownloadManager将某些内容附加到MP3文件时,不会调用OnBufferingUpdateListener.onBufferingUpdate(...)

所以问题是: 如何同时将音频文件下载到文件系统并播放? (Android 4+就足够了,如果这有所不同。)

我假设您将MediaPlayer指向该文件。 在这种情况下,我不认为它支持流式传输,并且它可能提前检查文件的大小等,因此它不会随着更多文件的进入而自动更新。

您必须将其指向可与流式处理相关的内容源,例如HTTP。 我刚刚检查了“ES文件资源管理器”是如何做到的(使用LogCat) - 当你点击远程文件共享中的视频文件时,它会打开一个本地HTTP服务器,并向MediaPlayer发送一个HTTP Uri到它的本地服务器,还包括远程路径。

当它通过HTTP获取请求时,本地服务器开始从远程位置读取文件,并通过HTTP将其本地提供给MediaPlayer。 您可以这样做,除了通过HTTP提供它还将其保存到磁盘。

它帮助了我,我希望能帮助别人。

播放器下载和播放音乐。

mMediaPlayer.setDataSource(DOWNLOAD_URL);

   File root = Environment.getExternalStorageDirectory();
   File dir = new File(root + "/Folder");
   if (!dir.exists()) {
        dir.mkdirs();

DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
            Uri downloadUri = Uri.parse(DOWNLOAD_URL);
            DownloadManager.Request request = new DownloadManager.Request(downloadUri);
            request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI);
            request.setAllowedOverRoaming(false);
            request.setTitle(TITLE);
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
            request.setDestinationInExternalPublicDir(Environment.DIRECTORY_MUSIC, TITLE);
            request.allowScanningByMediaScanner();

下载文件后:

mMediaPlayer.setDataSource(Environment.getExternalStorageDirectory() + "/Folder/" + TITLE + ".mp3");

我也有同样的问题。 当然,当我同时使用setDataSource(video_uri)aCustomDownload(video_uri)时,它可以保存并播放,但浪费了带宽。

我尝试将伪造的FileDescriptor (FileInputStream,LocalSocket)设置为setDataSource ,以及其他方式,但所有这些都失败了。

所以我找到了这个解决方案, VideoCache

  • 它通过http代理服务器,与@Oren的答案相同。 它构建一个套接字本地http服务器,然后监听一个有效的URL,如http://127.0.0.1:xxxx/url_encode('your video url')

  • 当它获得有效的URL时,它会创建一个套接字请求客户端来下载URL,并将该流发送到服务器127.0.0.1 所以你可以setDataSource('http://127.0.0.1:xxxx/your video's encode url')

  • 使用一次下载,保存和播放。 它可以使单个服务器再生成一个Activity(生命周期),所以我可以从android.intent.action.SEND或其他LAUNCHER使用它。

这是一个完美的解决方案。

注意:您必须关闭缓存限制。 否则,当缓存大小为512MB(默认值)时,VideoCache将清除所有数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM