Android MediaPlayer 需要很长时间来准备和缓冲
Posted
技术标签:
【中文标题】Android MediaPlayer 需要很长时间来准备和缓冲【英文标题】:Android MediaPlayer takes long time to prepare and buffer 【发布时间】:2012-10-01 00:50:09 【问题描述】:我的应用程序需要很长时间来准备和缓冲音频流。我已经阅读了这个问题Why does it take so long for android's MediaPlayer to prepare some live streams for playback?,但是它只是说人们遇到了这个问题,并没有说明如何改进这个问题。
我在从 2.2 到 4.1.2 测试的所有 Android 版本中都遇到了这种情况。
流的比特率适合移动和 3G 连接。相同的流在等效的 ios 应用中开始缓冲需要不到一秒的时间。
有没有办法指定应该缓冲的时间量?我知道 Tune In 收音机应用程序提供此功能 (https://play.google.com/store/apps/details?id=tunein.player)。
谢谢。
编辑:我再次测试,发现它只发生在运行 Gingerbread 及更高版本 (>=2.3) 的设备上。我知道 Android 将底层框架从 OpenCore 更改为 StageFright。那么如何优化媒体框架呢?旧的 HTC Wildfire 可以准备、流式传输和播放,这似乎是错误的,比全新的 HTC One X 和 Nexus 7 快 10 倍。
【问题讨论】:
我对此没有真正的答案,但这将帮助您的应用减少对用户的挫败感 (***.com/questions/6582908/…) 【参考方案1】:几个月来,我一直在为这个问题苦苦挣扎。终于找到了解决办法。
真正的问题在于 MediaPlayer 类的实现。特别是 MediaPlayer 缓冲数据的方式。这就是为什么解决方案是创建自己的缓冲,将其保存到临时文件并将其提供给 MediaPlayer。
本教程和源代码详细说明了如何操作。 http://androidstreamingtut.blogspot.nl/2012/08/custom-progressive-audio-streaming-with.html
通过修改此代码,可以轻松创建更好的流媒体播放器。
Google Developers 真的搞砸了。
编辑:这个答案相当陈旧。现在我建议不要使用MediaPlayer
,而是使用ExoPlayer
。它可扩展、稳定,可以播放多种不同类型的媒体。你可以在这里找到它:https://github.com/google/ExoPlayer/
【讨论】:
注意:此解决方案并不适用于所有场景,因为有时 MediaPlayer 在暂停、加载新缓冲区和重新启动时会“卡顿”。 MediaPlayer 只是一个写得很糟糕的类。 谢谢,这听起来可能是一个合适的替代方案,但是,我现在已经开始在我的应用程序中使用 FFMpeg。 您好 SteveEdson,您使用的是 William Seemann 的 ServeStream 中的代码吗?为什么不选择流代理解决方案? 是的,我是。我的应用程序需要能够播放多种不同的编解码器和格式,并且能够高效地进行流式传输,因此 Williams 的示例似乎是一种明智的做法。【参考方案2】:您确实无能为力,因为 Android MediaPlayer 类不提供对缓冲区大小等较低级别设置的访问。唯一的选择是使用 AudioTrack 和 FFmpeg 之类的库来制作自己的播放器来进行解码。
【讨论】:
谢谢,自从提出这个问题后,我得出的结论是我需要使用 FFMpeg 库。但是,我还没有听说过 AudioTrack,所以我会调查一下。我正在努力弄清楚如何在我的应用程序中实现 FFMpeg,但我想这是另一个问题。 Steve,我开发了一个开源 Android 应用程序,它可能会完成您想要完成的工作。我还刚刚添加了 FFmpeg 支持,因此我可以流式传输诸如 mms:// 之类的协议。请参阅此处的代码:sourceforge.net/projects/servestream。如果您有任何问题,您可以随时通过 SourceForge 与我联系。我希望这会有所帮助。 需要注意的一件事是,如果您使用 FFMPEG,您可能需要开源您的项目(取决于您使用 GPL 或 LGPL 许可证的编解码器)。阅读此处了解更多信息:ffmpeg.org/legal.html 嗨,William,我在 Note 3(Android 版本 4.3)上尝试了您的媒体播放器,但仍然得到相同的行为,播放音乐大约一秒钟,然后等待长达 7*8 秒并恢复...这与普通 MediaPlayer 实现的行为相同。如何通过修改缓冲区大小来修复它?在DownloadTask 类(DownloadPlayer.java) 我得到了和 burakk 完全相同的东西。越用安卓越失望。【参考方案3】:我推荐的一件事是玩转编码。例如,对于 MP4,确保 MOOV Atom 位于文件的开头(关于如何使用 ffmpeg 执行此操作的 S/O 上有足够多的问题等)。例如,使用 MP3,您可以查看不同的编解码器或比特率。
例如,您可以尝试一些在网上找到的音频文件,如果您看到一个不需要很长时间缓冲的音频文件,请尝试以相同的方式对您的文件进行编码。
【讨论】:
感谢您的建议,不幸的是,在这种情况下,这不是一个合适的选择,因为提供了流并且不受我的控制。如果我可以控制流,这可能会起作用。 是的,我正在尝试按照 NDK 食谱作为指南来完成这项工作。如果您有任何真正让您进行设置的好教程,请链接到它们。我不敢相信 Android 平台对于这样一个看似微不足道的任务来说是不够的,以至于你必须不遗余力地从不同的平台移植代码。以上是关于Android MediaPlayer 需要很长时间来准备和缓冲的主要内容,如果未能解决你的问题,请参考以下文章
Android:MediaPlayer setVolume 函数
ContentResolver.openAssetFileDescriptor() 在 Android 12 中需要很长时间