关于Android VideoView seekTo不准确的问题

来源:互联网 发布:众悦学车软件 编辑:程序博客网 时间:2024/05/21 06:49

本文章为原创,转载时请注明出处


Android播放视频

实现Android的视频播放器,通常有以下几种方式:
1、使用自带的播放器,指定Action为ACTION_VIEW,Data为Uri,Type为其MIME类型。

2、使用VideoView来播放,在布局文件中使用VideoView结合MediaController来实现对其控制。

3、使用MediaPlayer类和SurfaceView来实现,这种方式很灵活。

通过VideoView播放视频的步骤:
1、在界面布局文件中定义VideoView组件,或在程序中创建VideoView组件

2、调用VideoView的如下两个方法来加载指定的视频

setVidePath(String path):加载path文件代表的视频
setVideoURI(Uri uri):加载uri所对应的视频

3、调用VideoView的start()、stop()、psuse()方法来控制视频的播放

4、VideoView通过与MediaController类结合使用,开发者可以不用自己控制播放与暂停

下面针对使用VideoView播放视频时seekTo跳转不准的问题进行解析


使用VideoView

当用户从后台恢复播放时,需要跳转到之前退出的时间点继续播放。

整个控制逻辑大致上是:

在暂停时保存CurrantPosition进度
恢复播放时,调用seekTo方法,传入currantPosition作为参数

但是还是遇到了恢复播放时位置不准的问题,而且甚至有重头开始播放的现象。

问题定位

VideoView的seekTo是异步执行的,会有seek未完成但播放已经开始的现象。需要消除seekTo对恢复播放的影响,应该在seek操作完成的seekComplete回调方法中执行start方法。

VideoView是基于MediaPlayer实现的,但没提供setOnSeekCompleteListener方法

//设置videoview的OnPrepared监听videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {            @Override            public void onPrepared(MediaPlayer mp) {            //设置MediaPlayer的OnSeekComplete监听                mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {                    @Override                    public void onSeekComplete(MediaPlayer mp) {                        if(isPause){                            videoView.start();                            isPause = false;                        }                    }                });            }        });

根本原因

其实seekTo跳转的位置其实并不是参数所带的position,而是离position最近的关键帧。关于视频的关键帧建议大家可以去了解一下相关知识,大致上就是视频播放时需要从一个关键帧的位置开始。

当视频在相应的position位置缺少关键帧的情况下,调用seekTo方法是无法在当前位置开始播放。这时会寻找离指定position最近的关键帧位置开始播放。

解决措施

如何确认是视频源造成的问题,可以采取以下解决措施:

1、替换成满足需求的视频源文件(寻找合格的视频文件)。

2、对视频源文件进行处理,增加其关键帧数量,比如可以1s设置一个关键帧(基于目前已有的视频文件进行处理)。

如果选择第二种方式,要增加视频的关键帧数量,可以推荐大家使用FFmpeg进行增加关键帧的处理工作。 http://ffmpeg.org/

FFmpeg工具相关命令行语句:

ffmpeg.exe -i "D:\in.mp4" -c:v libx264 -preset superfast -x264opts keyint=25 -acodec copy -f mp4 "D:\out.mp4"

命令语句大致意思是:在D盘路径下把in.mp4视频文件每隔25帧设置一个关键帧,音轨保持原视频参数,其余使用FFmpeg提供的default值,最后保存为out.mp4文件到D盘。


总结

在深究问题的原因时不可浅尝而止,也不要一味的怀疑是不是代码造成了问题。很多情况下都选择盲目地替换不同的视频组件出实现,而忽略了视频源文件本身的问题。

不积跬步无以至千里,从当下开始就得养成好的习惯,一点一滴的积累经验。厚积薄发,技术由点汇聚成面,总结很重要,后面会开始很多的文章产出。

2 0
原创粉丝点击