【问题标题】:How to avoid 15 second delay/caching in Android Media Player when playing stream播放流时如何避免 Android 媒体播放器中的 15 秒延迟/缓存
【发布时间】:2011-10-04 05:16:24
【问题描述】:

我正在实现一个播放来自远程机器的流的媒体播放器。通过我的应用程序,我可以控制远程机器(例如寻求第二个)。像魅力一样工作,但是:Android 媒体播放器缓冲了一些疯狂的 10-15 秒(!!),这意味着每次点击('seek')需要 10-15 秒才能生效,即使它距离新的不到一秒数据到达。

我的问题:有没有办法控制(限制)缓存?还是我只是做错了什么?只有我有这个问题吗?

我的代码很简单:

player = new MediaPlayer()
player.setDataSource(url);
player.setOnPreparedListener(new OnPreparedListener() {

    public void onPrepared(MediaPlayer mp) {
        mp.start();
    }
});
player.prepareAsync();

我正在使用本地自建的迷你 HTTP 服务器将我的字节流连接到 Android 媒体播放器。在这种情况下,Android DRM 似乎正在延迟/缓存。仍然不太清楚为什么(如果我连接到托管文件的 IIS,为什么不这样做)。也不知道如何解决这个问题。

【问题讨论】:

    标签: android caching android-mediaplayer


    【解决方案1】:

    好的,与此同时,我离解决方案更近了。原来我的问题的根源是Android DRM! (不,我不是在播放受保护的文件。它的标准 mp3)。

    DRM 似乎已在 Android 3.1 中引入(我在 Galaxy Tab 10.1 上进行测试)。它在模拟器上运行良好(也许 DRM 没有在那里实现?)

    知道如何禁用或加速它吗?在 Android DRM impl 的某个深处似乎有一个 10 秒的计时器等待 - 无论如何,不​​知道。我的错误日志:

    10-06 17:38:19.020: ERROR/MediaExtractor(226): **********MediaExtractor::Create
    10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(226): add uniqueid
    10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(225): Entering BnDrmManagerService::onTransact with code 1
    10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(225): BnDrmManagerService::onTransact :ADD_UNIQUEID
    10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(225): Entering BnDrmManagerService::onTransact with code 3
    10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(225): BnDrmManagerService::onTransact :ADD_CLIENT
    10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(226): Entering BpDrmManagerService::openDecryptSession
    10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(225): Entering BnDrmManagerService::onTransact with code 27
    10-06 17:38:19.020: ERROR/IDrmManagerService(Native)(225): BnDrmManagerService::onTransact :OPEN_DECRYPT_SESSION_FROM_URI
    10-06 17:38:19.020: ERROR/DrmManagerService(Native)(225): Entering DrmManagerService::openDecryptSession with uri
    
    10 seconds wait
    
    10-06 17:38:29.040: ERROR/DrmManager(Native)(225): DrmManager::openDecryptSession: no capable plug-in found
    10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(225): NULL decryptHandle is returned
    10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(226): no decryptHandle is generated in service side
    10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(226): remove uniqueid
    10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(225): Entering BnDrmManagerService::onTransact with code 2
    10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(225): BnDrmManagerService::onTransact :REMOVE_UNIQUEID
    10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(225): Entering BnDrmManagerService::onTransact with code 4
    10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(225): BnDrmManagerService::onTransact :REMOVE_CLIENT
    10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(226): setDrmServiceListener
    10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(225): Entering BnDrmManagerService::onTransact with code 5
    10-06 17:38:29.040: ERROR/IDrmManagerService(Native)(225): BnDrmManagerService::onTransact :SET_DRM_SERVICE_LISTENER
    10-06 17:38:29.040: ERROR/DrmManagerService(Native)(225): Entering setDrmServiceListener
    

    【讨论】:

    • 你找到解决方案了吗?
    • 我不敢分享 :) 在一些较旧的 3.0 Android 版本上,我可以通过将我的 HTTP 响应换行符从 \r\n 替换为 \n\r 来解决它。是的,当时正在考虑返回我的 CS 学位:)。也许我在那里利用了一些错误。不幸的是,没有设备来测试这个,所以我无法重现。
    【解决方案2】:

    我在较新的 Android 版本中意识到的一件事是 VBR MP3 文件似乎存在问题。它播放它们,但在开始之前缓冲了太多数据。 (3+ MB,我的大部分测试文件)。

    一个(不好的)解决方法是从 MP3 文件中删除 XING 标头(这是存储 VBR 信息的位置)。这似乎使播放器回退到更简单的算法,并在仅缓冲 100kb 后成功开始播放我的所有文件...

    【讨论】:

      【解决方案3】:

      试试这个。这肯定会对你有所帮助::

       private class TouchandshowTask extends AsyncTask<Void, Void, Void> {
      
          @Override
          protected Void doInBackground(Void... arg0) {
              try {
              player.setAudioStreamType(AudioManager.STREAM_MUSIC);
              player.setDataSource("URL");
              player.prepare();
          } catch (Exception e) {
              // TODO: handle exception
          }
      
              return null;
          }
          protected void onPostExecute(final Void unused) {
      
          }
      }
      

      OnCreate()

      new TouchandshowTask().execute();
      

      【讨论】:

      • 不幸的是,这没有帮助。更糟糕的是,我在开始时尝试加速传输以最大限度地减少延迟:我在一秒钟内传输了第一个兆字节(3 个字节),但它仍然需要超过 10 秒才能开始播放!不知道里面发生了什么,但感觉不像是缓存问题。
      • 我从来没有遇到过这个问题,我也从服务器收到声音,但没有延迟。我收到 50 个声音,但从不提出问题
      • 当我简单地从服务器流式传输文件时,它也非常适合我。但是,一旦我调到流中,就会出现延迟......
      • android 媒体播放器让我难过 :(
      【解决方案4】:

      问题可能不仅仅出在 Android 媒体播放器上。 流媒体的服务器应该支持需要的格式。

      如果是 mp4,则需要安装 h264-pseudo-streaming 模块(HLS 相同) 如果是 MSS(微软平滑流式传输)- 有用于 IIS 的特殊模块。

      另外,在用户“进行搜索”后,这意味着 Native Player 将发送范围请求,这应该得到服务器的支持。 Nginx 默认支持它们,ISS 和 Apache 对此有一些问题。虽然很容易配置。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-08
        • 2015-12-25
        • 1970-01-01
        • 2012-03-19
        • 1970-01-01
        相关资源
        最近更新 更多