android 获取视频帧并保存

android提供了获取视频帧的方法,比如获取第一帧作为视频缩略图,或者获取指定位置的帧快速浏览视频内容。

   MediaMetadataRetriever类提供了获取视频各种信息的方法。

MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource(videoPath);
String rotationStr = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
String width = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
String height = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
String duration = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
...

可获得视频宽高大小、持续时间、比特率等信息。

 

还可获取帧数据:

public static Bitmap getVideoFrame(String path, long time) {
    long timeUs = time * 1000;
    MediaMetadataRetriever mmr = new MediaMetadataRetriever();
    mmr.setDataSource(path);
    return mmr.getFrameAtTime(timeUs, MediaMetadataRetriever.OPTION_CLOSEST);
}

获取指定时间附近的帧,返回Bitmap对象。

需要注意:

       1.要先设置dataSource,再获取帧数据;

       2.getFrameAtTime(long timeUs, int option)方法第一个参数的时间单位为微妙,这个地方很容易误传毫秒时间,导致一直获取第一帧。

 

getFrameAtTime()方法第二个参数设置帧的获取类型选项,可选择如下四种选项:

/**
 * This option is used with {@link #getFrameAtTime(long, int)} to retrieve
 * a sync (or key) frame associated with a data source that is located
 * right before or at the given time.
 */
public static final int OPTION_PREVIOUS_SYNC    = 0x00; //获取当前时间或之前的关键帧
/**
 * This option is used with {@link #getFrameAtTime(long, int)} to retrieve
 * a sync (or key) frame associated with a data source that is located
 * right after or at the given time.
 */
public static final int OPTION_NEXT_SYNC        = 0x01; //获取当前时间或之后的关键帧
/**
 * This option is used with {@link #getFrameAtTime(long, int)} to retrieve
 * a sync (or key) frame associated with a data source that is located
 * closest to (in time) or at the given time.
 */
public static final int OPTION_CLOSEST_SYNC     = 0x02; //获取当前时间最近的关键帧
/**
 * This option is used with {@link #getFrameAtTime(long, int)} to retrieve
 * a frame (not necessarily a key frame) associated with a data source that
 * is located closest to or at the given time.
 */
public static final int OPTION_CLOSEST          = 0x03; //获取当前时间最近的帧,不一定是关键帧

 

getFrameAtTime()方法获取的帧图片大小是和视频大小一样的,那么如果想获取不同宽高大小的图片怎么办呢?我们可以选择自己缩放图片。

其实,MediaMetadataRetriever类也提供了可以获取指定宽高大小的帧数据方法:

public Bitmap getScaledFrameAtTime(long timeUs, @Option int option, int dstWidth, int dstHeight) {
    ...
}

它可以指定要获取帧的宽高。

 

--------------------------------------------------------------------

 

上述方法返回的是Bitmap对象数据,怎么保存成一张图片呢?下面直接给出方法,不再赘述。

public static boolean saveBitmap(Bitmap bitmap, File file) {
    if (bitmap == null)
        return false;
    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(file);
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
        fos.flush();
        return true;
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (fos != null) {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return false;
}

 

============================================

另外,要想获取视频帧图片,也可通过ffmpeg来获取,ffmpeg是一款强大的音视频处理工具。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值