Android笔记之seekTo
来源:互联网 发布:贪心算法的特点 编辑:程序博客网 时间:2024/05/05 12:06
public native void seekTo(int msec) throws IllegalStateException;
可以看出我们只需要传入一个视频对应的毫秒数就可以直接对视频进行seek。
但是实际上通过一个seekBar来进行测试时发现效果和想象中完全不一致,感觉有严重的跳帧,简单说就是只会seek到很少的特定帧数上而不是能seek到视频的每一帧,于是开始各种百度。最后发现了原因。
在每次seekTo方法调用后,MediaCodec必须从关键帧开始解码。因此seekTo方法只会seek到最近的/上一个/下一个关键帧,也
就是I-Frame(key frame = I frame = sync frame)。之所以要从关键帧开始解码,是因为每一帧不一定是单独编码的,只有I frame才是
帧内编码,而P, B frame都是要参考别的帧来进行编码,因此单独拿出来是不完整的一帧。
因为一般视频都是隔几秒存在一个关键帧,而一秒有24以上的帧数,这样就会导致seekTo效果相当不好。
那么问题来了,应该怎么解决呢。
办法一:seekTo到某一个帧而不是关键帧,需要自己解码渲染图片,而且不确定是否有效。执行效率也不稳定,成本高。
办法二:从源头上解决,增加视频的关键帧。但是会增加视频容量大小。
这两个方法显而易见在自己提供资源的情况下,办法二还简单粗暴很多。我在这里采用的就是这种方法。至于增加关键帧的方法有很多现成的软件可以使用,这里推荐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盘。
关于关键帧,我还遇到了另外一种情况。
如果你想从视频中获得到一张缩略图,系统同样提供了现成的API,只需要传入一个对应的毫秒数就可以了,但是和猜想的一样,这个缩略图同样也只能从关键帧中进行获取。以下是对应的工具类。
private static ExecutorService executor = Executors.newFixedThreadPool(1); private static MediaMetadataRetriever retriever; public static void AsyncGetBitmapsFromVideo(final Handler handler, String path, final int position, final ImageView imageView) { retriever = new MediaMetadataRetriever(); retriever.setDataSource(path); /** * OPTION_PREVIOUS_SYNC,在给予的时间戳之前获取同步帧 OPTION_NEXT_SYNC,在给予的时间戳之后获取同步帧 OPTION_CLOSEST_SYNC,在给予的时间戳附近 OPTION_CLOSEST,可能返回一个同步或者不同步的帧,但是是在这个时间戳附近,并且对于系统性能的开销 比较大 */ executor.execute(new Runnable() { @Override public void run() { final Bitmap bitmap = retriever.getFrameAtTime(position * 1000 * 1000, MediaMetadataRetriever.OPTION_NEXT_SYNC); int px40 = PublicUtils.dip2px( 20); final Bitmap newBitmap = ThumbnailUtils.extractThumbnail(bitmap, px40, px40); if (bitmap!=null) handler.post(new Runnable() { @Override public void run() { imageView.setImageBitmap(newBitmap); } }); } }); }
这里使用了多线程是为了提高性能,最主要的是为了不阻塞UI,由于需要截取多张图片,因此图片的顺序很重要,所以这里才用了线程池来进行操作,并且设置最大线程数为1,经过测试如果同时开启多根线程进行操作会导致截出的图片丢失或者顺序错乱。
- Android笔记之seekTo
- android--mediaplayer的seekTo用法
- Android MediaPlayer seekTo不准确问题
- 关于Android seekTo的一点记录
- Android开发——MediaPlayer的seekto分析
- 关于Android VideoView seekTo不准确的问题
- Android中的mediaplayer的seekto()方法用法
- 关于IjkVideoView或Android VideoView seekTo不精确问题
- 音频seekTo的实现
- mediaPlayer的seekto方法
- Android笔记之LoopViewPager笔记
- Android 笔记 之 Button
- Android 笔记 之 AutoCompleteTextView
- Android笔记之handler
- Android之学习笔记
- Android之Handler笔记
- android笔记之helloworld
- android笔记之autoCompleteTextView
- 非阻塞同步算法与CAS(Compare and Swap)无锁算法
- 在生产环境使用Kuberntes一年后,我们总结了这些经验和教训
- 并查集-一笔画优化
- 数据库索引
- 安卓 闹钟demo
- Android笔记之seekTo
- EditText在手机弹出的软键盘中,将回车键变为搜索键和点击搜索键时,执行2次搜索解决
- 好雨云帮一周问答集锦(2017.02.13-2017.02.19)
- 关于android使用ksoap2报Caused by: java.lang.ClassCastException: org.ksoap2.SoapFault cannot be cast to or
- 割点-危险系数
- 2017读书雷达
- Java垃圾回收机制
- 县级山洪灾害监测预警系统预警机制
- 梦行monxin全网通商城系统