• 【Android】 修复ijkPlayer进行m3u8 hls流播放时seek进度条拖动不准确的问题


    项目中使用的播放器是ijkPlayer,发现播放切片特点的hls流(m3u8格式的视频)拖动seekBar的时候会莫名的跳转或者seek不到准确的位置,发现网友也遇到了同样的问题,ijk的开发者也说明了是因为UI层的问题导致的,需要自己排查。涉及到该问题的链接:

    既然开发者都说了,那么就老实分析代码吧。因为项目中用到的MediaController继承自Android系统的MediaController,所以还得看看源码,分析得出系统中实现是将seek的listener监听器放在onProgressChanged这个方法中,这也是为什么我们断断续续拖动的时候播放器也会播放,知道这点就够了,把onProgressChanged中的mPlayer.seekTo((int) newposition);放到onStopTrackingTouch方法中。

    执行顺序是:

    onStartTrackingTouch(执行一次) —> onProgressChanged(拖动就会不停的执行) —> onStopTrackingTouch(停止后最后执行一次)

    实现代码如下:

    public class CustomMediaController extends MediaController implements ICustomMediaController {
     	// ....................代码省略.............................
    
      // There are two scenarios that can trigger the seekbar listener to trigger:
      //
      // The first is the user using the touchpad to adjust the posititon of the
      // seekbar's thumb. In this case onStartTrackingTouch is called followed by
      // a number of onProgressChanged notifications, concluded by onStopTrackingTouch.
      // We're setting the field "mDragging" to true for the duration of the dragging
      // session to avoid jumps in the position in case of ongoing playback.
      //
      // The second scenario involves the user operating the scroll ball, in this
      // case there WON'T BE onStartTrackingTouch/onStopTrackingTouch notifications,
      // we will simply apply the updated position without suspending regular updates.
      private OnSeekBarChangeListener mSeekListener=new OnSeekBarChangeListener(){
        long newposition;
    
        public void onStartTrackingTouch(SeekBar bar){
          show(3600000);
          mDragging=true;
          if(seekerBarDraggingListener!=null)
            seekerBarDraggingListener.getCurrentDraggingstatus(mDragging);
    
          // By removing these pending progress messages we make sure
          // that a) we won't update the progress while the user adjusts
          // the seekbar and b) once the user is done dragging the thumb
          // we will post one of these messages to the queue again and
          // this ensures that there will be exactly one message queued up.
          mHandler.removeMessages(SHOW_PROGRESS);
        }
    
        public void onProgressChanged(SeekBar bar,int progress,boolean fromuser){
          if(!fromuser){
            // We're not interested in programmatically generated changes to
            // the progress bar's position.
            return;
          }
          long duration=mPlayer.getDuration();
          newposition=(duration*progress)/1000L;
          // 系统原来的实现是在progress改变的时候时刻都在进行videoplayer的seek
          //这会导致seek m3u8切片文件的时候拖动seek时不准确,所以需要在拖动完成后才进行播放器的seekTo()
          //                mPlayer.seekTo((int) newposition);
          if(mCurrentTime!=null)
            mCurrentTime.setText(stringForTime((int)newposition));
        }
    
        public void onStopTrackingTouch(SeekBar bar){
          mDragging=false;
          mPlayer.seekTo((int)newposition);
          if(seekerBarDraggingListener!=null)
            seekerBarDraggingListener.getCurrentDraggingstatus(mDragging);
          setProgress();
          updatePausePlay();
          if(isntNeedStayShowAfterDrag){
            show(sDefaultTimeout);
            // Ensure that progress is properly updated in the future,
            // the call to show() does not guarantee this because it is a
            // no-op if we are already showing.
            mHandler.sendEmptyMessage(SHOW_PROGRESS);
          }
        }
      };
    
      // ....................代码省略.............................
    }
    
  • 相关阅读:
    jquery 序列化form表单
    nginx for windows 安装
    nodejs idea 创建项目 (一)
    spring 配置 shiro rememberMe
    idea 2018 解决 双击shift 弹出 search everywhere 搜索框的方法
    redis 在windows 集群
    spring IOC控制反转和DI依赖注入
    redis 的安装
    shiro 通过jdbc连接数据库
    handlebars的用法
  • 原文地址:https://www.cnblogs.com/raomengyang/p/6047456.html
Copyright © 2020-2023  润新知