首页 文章

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

提问于
浏览
19

我'm using Android' s MediaPlayer 播放使用 DownloadManager 从互联网同时下载的MP3文件 . 我知道 MediaPlayer 's capability to stream directly, but I don' t想要使用它:

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

  • 这原则上有效 - 即使没有完全下载, MediaPlayer 也会开始播放文件 . (顺便说一下,我的问题不在于我不能玩 MediaPlayer . )

  • 问题是,当 MediaPlayer 到达开始播放时的下载状态时,它会停止并调用 onCompletion . (澄清:假设我开始玩时,我们假设该文件下载了12% . 当玩家以12%的比例到达该位置时,它会停止 . )

  • 快速注释:当通过 DownloadManager 将某些内容附加到MP3文件时,不会调用 OnBufferingUpdateListener.onBufferingUpdate(...) .

所以问题是: How can I simultaneously download an audio file to the file system and play it? (Android 4+ suffices, if that makes a difference.)

3 回答

  • 9

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

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

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

  • 1

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

    播放器下载和播放音乐 .

    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");
    
  • 4

    我也有同样的问题 . 当然,当我同时使用 setDataSource(video_uri)aCustomDownload(video_uri) 时,它可以保存并播放,但它 wasted bandwidth.

    我尝试将 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')

    • 使用一次下载,保存和播放 . 并且它可以使 a singleton server 再生成一个Activity(生命周期),所以我可以在 android.intent.action.SEND 或其他 LAUNCHER 中使用它 .

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

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

相关问题