【问题标题】:Detecting buffering error (or timeout) Android MediaPlayer - Use a Timer for timeout?检测缓冲错误(或超时)Android MediaPlayer - 使用定时器超时?
【发布时间】:2015-01-28 10:41:44
【问题描述】:

显然没有抛出异常,因此我可以在缓冲流式音频内容时识别错误。例如,我已断开路由器的连接,应用程序将继续尝试缓冲整个时间。当我重新连接时,它会完成缓冲并在断开连接超过一分钟后继续!

所以问题是我不能让我的用户坐那么久而不考虑这个问题。检测 Android 媒体播放器缓冲问题的正确方法是什么?

我正在考虑使用Timer 进行超时。我可能会从 15 秒开始(使用代理我测试了 5kbps 连接,这是最坏的情况,能够在 6-10 秒内开始播放,所以我认为 15 秒是一个合理的超时时间)。这听起来像是一个好计划吗?如果是这样,我应该在每次缓冲区尝试时创建一个新的 Timer,还是应该在播放服务的整个生命周期内保持相同的 Timer?

所以基本上我要问两个问题:

1) 检测缓冲区是否有问题的正确方法是什么?有没有我忽略的听众?我已经尝试过 MediaPlayer.OnErrorListener 当然在我的测试中没有触发。我的结论是我必须有一个超时来检测缓冲错误。

2) 如果我在第一点上是正确的,那么使用计时器的正确方法是什么?每次尝试缓冲区时创建一个或重复使用相同的缓冲区? 编辑 我还应该重新启动(或取消并创建一个新的)Timer onBufferUpdate 吗?使用 onBufferUpdate 侦听器,我应该知道一些数据正在返回,因此可能应该用它重置计时器。

【问题讨论】:

    标签: android timer android-mediaplayer


    【解决方案1】:

    根据您的问题,我了解主要目标是检测您的播放器因缓冲而停滞的情况并采取一些措施。为了处理这种情况,我觉得以下 2 个听众可能有助于识别相同的情况。

    MediaPlayer.onBufferingUpdate 将提供缓冲的及时进度。因此,如果有 2 个回调具有相同的 percent 值,这可能表明潜在的缓冲。

    还有另一个听众MediaPlayer.onInfoListener,其中有一些您可能感兴趣的特定事件。在这个监听器上,如果whatMEDIA_INFO_BUFFERING_START,这将表明播放器正在暂停播放以进行缓冲,即触发您的逻辑。同样MEDIA_INFO_BUFFERING_END表示填充缓冲区后重新开始播放。

    【讨论】:

      【解决方案2】:

      你应该看看这篇文章。媒体播放器有一个 ErrorListener 来获取任何错误。

      http://developer.android.com/reference/android/media/MediaPlayer.OnErrorListener.html

      【讨论】:

      • 我现在检查一下,问题是 OnError 永远不会被触发,即使它只是坐在那里一分钟。
      • 那不是文章,那是文档,我当然读过!这不是 RTFM 情况!大声笑:-)
      • 对我来说发生的事情与 Anthony 完全一样,超时需要很长时间才能调用错误侦听器。不知道怎么解决。
      【解决方案3】:
      int count=40;//for 40 seconds to wait for buffering after it will finish the activity
      //boolean timeoutflag=false;
      
      timeout = new Handler(Looper.getMainLooper()) {
                  @Override
                  public void handleMessage(Message msg) {
                      System.out.println("value of count="+msg.getData().getLong("count"));
                      if (msg.getData().getBoolean("valid")) {
                          if (msg.getData().getLong("count") == 0 && !timeoutflag) 
                          {
      
                              if (pDialog != null && pDialog.isShowing()) 
                                      {   
                                      try
                                      {
                                      pDialog.dismiss();
                                      }catch(Exception e)
                                      {
                                          e.printStackTrace();
                                      }
                                      }
                                  Toast.makeText(getApplicationContext(),
                                          "Unable To Load This Video", Toast.LENGTH_LONG).show();
                              finish();
      
                          } else {
                          }
      
                      }
      
                  }
              };
              timeout.postDelayed(null, 0);
              new Thread(new Runnable() {
      
                  @Override
                  public void run() {
                      while (count > 0) {
                          try {
                              Thread.sleep(1020);
                          } catch (Exception e) {
                          }
      
                          Message msg = new Message();
                          Bundle b = new Bundle();
                          b.putBoolean("valid", true);
                          b.putLong("count", --count);
                          msg.setData(b);
                          timeout.sendMessage(msg);
      
                      }
      
                  }
              }).start();
              // set timeoutflag=true; in setOnPreparedListener of video view
      

      【讨论】:

        【解决方案4】:

        为了在准备期间进行缓冲,您必须设置自己的计时器,该计时器会在一段时间后调用 player.reset()。这会使播放器回到初始状态。

        对于准备后的缓冲(在播放过程中),您必须监控 getPosition()。如果它落后于某个最大值,请调用 reset()。这允许您为播放设置经验阈值。不仅可以处理失败的连接,还可以处理断断续续的连接。

        最好的解决方案是不使用 MediaPlayer。请改用公共 VLC 衍生产品。 MP 有太多内部化的私有设计限制,需要可怕的变通方法(例如,不能添加编解码器)。在这种情况下,RTFM 给了你错误的希望。

        除非你正在做一个非常直接的 android 应用程序,否则不要依赖任何 android api。一些开源替代品得到了更好的支持,而且有充分的理由。

        (真的很开心,很满足编辑的咆哮已删除)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-08-05
          • 2022-07-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-10-03
          • 2016-06-18
          相关资源
          最近更新 更多