Android快速获取视频帧

2017年短视频应用如雨后春笋般先后上线,现在的短视频App大多支持本地视频的上传以及裁剪。下面讲一讲裁剪视频时预览视频图片的快速获取方法。当选择一个视频之后,底下通常有预览图片,这就是视频帧,比如快手上传本地视频的界面如图所示

获取视频帧的方式的有很多种,比如可以直接使用ffmpeg,也可以使用Android自带的MediaMetadataRetriever来获取指定时间的图片帧,当然,可以自己设置option来指定图片是否是关键帧,也会根据option设置的不同以不同的方式寻找关键帧(我测试的结果感觉返回的都是关键帧)。

    MediaMetadataRetriever object = new MediaMetadataRetriever();
    object.setDataSource(mPath);
    //frameTime的单位为us微秒
    object.getFrameAtTime(frameTime, MediaMetadataRetriever.OPTION_CLOSEST);

OPTION一共有四个,分别是OPTION_CLOSEST、OPTION_CLOSEST_SYNC、OPTION_PREVIOUS_SYNC和OPTION_NEXT_SYNC。这些参数应该是见字识意的,但是个人测试结果即使设置成OPTION_CLOSEST返回的数据仍然是关键帧。

使用此方法很简单,但是此方法的速度比较慢,尤其当视频文件较大时,根本达不到快手这类App点进去之后立马就能将图片显示出来的速度。所以肯定有更快的实现,但是一直没有想到一个特别好的思路,后来在bigflake.com/MediaCodec中看到了一个例子才算是找到一个更快的方法,通过MediaCodec进行解码,然后通过OpenGL渲染,最后通过glReadPixels来获取图片,每一步的时间都是ms级别,整个过程应该也不慢。
下面是官方的demo

//20131122: minor tweaks to saveFrame() I/O
//20131205: add alpha to EGLConfig (huge glReadPixels speedup); pre-allocate pixel buffers;
//          log time to run saveFrame()
//20140123: correct error checks on glGet*Location() and program creation (they don't set error)
//20140212: eliminate byte swap

/**
 * Extract frames from an MP4 using MediaExtractor, MediaCodec, and GLES.  Put a .mp4 file
 * in "/sdcard/source.mp4" and look for output files named "/sdcard/frame-XX.png".
 * <p>
 * This uses various features first available in Android "Jellybean" 4.1 (API 16).
 * <p>
 * (This was derived from bits and pieces of CTS tests, and is packaged as such, but is not
 * currently part of CTS.)
 */
public class ExtractMpegFramesTest extends AndroidTestCase {
   
    private static final String TAG = "ExtractMpegFramesTest";
    private static final boolean VERBOSE = false;           // lots of logging

    // where to find files (note: requires WRITE_EXTERNAL_STORAGE permission)
    private static final File FILES_DIR = Environment.getExternalStorageDirectory();
    private static final String INPUT_FILE = "source.mp4";
    private static final int MAX_FRAMES = 10;       // stop extracting after this many

    /** test entry point */
    public void testExtractMpegFrames() throws Throwable {
        ExtractMpegFramesWrapper.runTest(this);
    }

    
  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值