Android关于VideoView的一些思考和总结

标签: android视频VideoView
4992人阅读 评论(2) 收藏 举报
分类:

最近在做一期有关于视频的项目开发。因为项目周期比较紧,而且自己以前也没有对于视频相关的经验积累。所以在开发的时候遇到了问题,自己尝试解决并记录下来。(PS:视频都是下载完再进行播放类似于微信朋友圈的视频功能,播放组件用的是分装的原生的VideoView)

  • 一、视频播放时会有短暂的黑屏时间:

    • 产生原因:视频文件加载到内存中是需要时间,这个时间可能导入VideoView全黑。
    • 解决方法(1):给VideoView添加MediaPlayer.OnPreparedListener 监听事件,在其onPrepared(MediaPlayer mp) 方法回调中播放视频这个时候视频已经完成了加载。(PS:此方法在有些情况下使用有些问题,因为播放视频的时候MediaPlayer.OnPreparedListener 监听不到回调,具体为什么自己也没有做相关的调研,如果有谁知道希望能分享一下)。
    • 解决方法(2):笨方法,同时也是最管用的方法。在VideoView执行start() 方法时视频的预览图不是立即消失而是延迟几百毫秒之后消失,这是视频已经加载完成,当然体验上有些不好。
  • 二、在进入有VideoView界面的Activity时会出现闪黑屏的情况(如论视频是否播放):

    • 产生原因:不祥(自己没有找到认为正确的答案)

    • 解决方法:在整个界面创建之前添加这行代码getWindow().setFormat(PixelFormat.TRANSLUCENT);

  • 三、当前界面有视频播放时进入其他界面,然后跳转回来后VideoView展示全黑(按home键再次进入app也会有同样的问题):

    • 产生原因:VideoView被回收掉,而自己没做VideoView的状态保存处理

    • 解决方法:在VideoView所在的Activity或者Fragment的生命周期中处理VideoView视频播放和暂停。

  • 四、在类似微信列表页视频播放点击大图播放时列表的VideoView回出现在大图的VideoView之上(PS:如果列表的VideoView和大图播放的VideoView不是同一个):

    • 产生原因:SurfaceView默认会出现在最顶部的。
    • 解决方法: 小图播放时要隐藏掉(GONE而不是INVISIBLE)。
  • 五、VideoView嵌套ViewPager使用时,在滑动ViewPager过程中视VideoView会出现透明(此时VideoView是自动播放)(PS:此时Activity的主题为android:theme="@style/Transparent")。

    • 产生原因:ViewPager在执行public void onPageSelected(int position) 方法时当前界面还是展示两个View。即下一个View并没有完全漏出来。

    • 解决方法:定义ViewPager的ViewPager.OnPageChangeListener接口,覆盖public void onPageScrolled(int postion, float v, int i)方法,监听让下一个界面完全展现出来之后在执行public void onPageSelected(int position)方法。然后再在方法里处理下一个视频的播放以及上一个的停止。

  • 六、使用VideoView造成界面其他组价焦点产生“遗失”:

    • 现象:在ViewTreeObserver.addOnPreDrawListener添加新的OnPreDrawListener的onPreDraw多次执行。

    • 解决办法(1):使用SurfaceView+MediaPlayer自定义播放器

    • 解决办法(2):对VideoView的构造函数中的焦点处理的方法进行反处理,即在VideoView子类(这里应该就是自己写的自定义VideoView其继承与VideoView)的构造方法中进行反处理。

//VideoView源码
public class VideoView extends SurfaceView
        implements MediaPlayerControl, SubtitleController.Anchor {
    private String TAG = "VideoView";
    /*其他代码省略*/
    //每个构造函数中都执行initVideoView
    public VideoView(Context context) {
        super(context);
        initVideoView();
    }
    public VideoView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
        initVideoView();
    }
    public VideoView(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }
    public VideoView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initVideoView();
    }
    /*其他代码省略*/
    private void initVideoView() {
        mVideoWidth = 0;
        mVideoHeight = 0;
        getHolder().addCallback(mSHCallback);
        getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        //start     下边3行代码是对焦点进行的处理,以及自己所谓的反处理
        setFocusable(true);  //子类setFocusable(false);
        setFocusableInTouchMode(true);   //子类setFocusableInTouchMode(false);
        requestFocus();   //子类clearFocus();
        //end
        mPendingSubtitleTracks = new Vector<Pair<InputStream, MediaFormat>>();
        mCurrentState = STATE_IDLE;
        mTargetState  = STATE_IDLE;
    }
    /*其他代码省略*/
 }
  • 七、在VideoView的MediaPlayer.OnCompletionListener 回调监听public void onCompletion(MediaPlayer mp) 方法里进行视频的播放(PS:这个指的是视频的循环播放),在有些手机上不能正常重新播放。

    • 产生原因:在部分手机上VideoView的MediaPlayer.OnCompletionListener 回调监听public void onCompletion(MediaPlayer mp) 方法里此时`VideoView.isPlaying() 的值还是为true。

    • 解决办法:在VideoView的 MediaPlayer.OnCompletionListener 回调监听 public void onCompletion(MediaPlayer mp) 方法里对`VideoView.start() 方法进行延迟播放。一般这个时间不会太长,几百毫秒就可以。视觉感官上也还好。

以上是自己在仅仅两周开发使用VideoView开发视频有关项目中遇到的问题,和一些不是很成熟的解决方案。

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:244026次
    • 积分:3470
    • 等级:
    • 排名:第10625名
    • 原创:324篇
    • 转载:17篇
    • 译文:10篇
    • 评论:34条
    博客专栏
    最新评论