2018.9.25更新
mediaCodec的做法是正解
https://www.jianshu.com/p/567d7ce47f52
最近有个需求, 需要仿照抖音, 对视频(MP4)进行裁剪, 裁剪时, 需要显示视频的帧列表, 效果图如下:
我们产品使用的是腾讯提供的视频编辑sdk, 对视频进行解析, 按照时间分割生成对应时间点的帧图片. 具体怎么做没什么可说的. 它也是在ffmpeg基础上实现的.
我想的是如果不使用第三方工具, 如何对一个视频(更具体的是mp4)文件进行帧画面的截取.
方法一
想到的第一个方法, 就是在视频播放过程中, 对view控件进行截屏, 这样好像是最简单的办法, 不用关注播放的视频格式, 只要能播放, 就能截取.
因为用的是exoplayer作为播放器, 这个播放器支持surfaceView和TextureView 两种视图模式的展示,
对于surfaceView好像做不到转换成bitmap 但是TextureView 就很简单了.
先设置为TextureView :
<com.google.android.exoplayer2.ui.PlayerView
android:id="@+id/player_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:surface_type="texture_view">
</com.google.android.exoplayer2.ui.PlayerView>
在代码中直接截图就可以了:
val videoSurfaceView = player_view.videoSurfaceView as TextureView
val bitmap = videoSurfaceView.bitmap
好简单.
缺点是, 要想对视频每一秒都截图, 那么需要把视频从头到尾播放一遍. 很耗时. 其实也有对策, 可以设置播放速度为快速播放, 比如16倍速, 然后对应调整截屏的间隔. 另外可以把播放器设置为静音播放, 还可以在用户看不到的地方进行播放, 这样给用户的感觉就是正在加载视频文件.
方法二
另一种方法是通过系统的MediaExtractor 和 MediaCodec 对数据进行读取和解码, 从而解析出每帧图片. 实现上麻烦的多, 就不在此列出了, 有兴趣的查看源码吧:
https://github.com/shaopx/VideoClipEditViewTest