android —— MediaMetadataRetriever获取媒体元数据信息

android原生态MediaMetadataRetriever

android系统自带的MediaMetadataRetriever类可以获取视频、音频等媒体文件的META DATA即元数据信息。
视频支持的格式有:3gp、mp4、mkv、avi、m4v、ts、swf等
不支持:rmvb、rm。

  /**
     * 提取视频文件的 时长 和 缩略图
     * 如果想要的缩略图的宽和高都小于MICRO_KIND,则类型要使用MICRO_KIND作为kind的值,这样会节省内存。
     */
    public synchronized static void extractDurationAndThumbnail(@NonNull POVideo video) {

        if (Utils.isEmpty(video.fullPath)
                || !new File(video.fullPath).exists())
            return;

        Bitmap bitmap = null;
        MediaMetadataRetriever ffmpegRetriever = null;
        try {
            ffmpegRetriever = new MediaMetadataRetriever();
            ffmpegRetriever.setDataSource(video.fullPath);
            // 取得视频的长度(单位为秒)
            video.duration = ffmpegRetriever.extractMetadata(
                    MediaMetadataRetriever.METADATA_KEY_DURATION);

            if (VideoUtils.isProblemVideo(video.name.substring(video.name.lastIndexOf("."))))
                return;

            long seconds = (Long.parseLong(video.duration) / 1000);
            seconds = ((seconds / 2) + 2) * 1000 * 1000;

            // 取得缩略图
            bitmap = ffmpegRetriever.getFrameAtTime(seconds,
                    MediaMetadataRetriever.OPTION_CLOSEST_SYNC);

            if (bitmap == null) return;

            // 缩放为指定大小
            bitmap = ThumbnailUtils.extractThumbnail(bitmap,
                    UIUtils.dip2px(VideoConfig.THUMB_IMG_WIDTH),
                    UIUtils.dip2px(VideoConfig.THUMB_IMG_HEIGHT),
                    ThumbnailUtils.OPTIONS_RECYCLE_INPUT);

        } catch (Exception e) {
            LogUtils.e(TAG, "=====ffmpegRetriever error");
        } finally {
            try {
                if (ffmpegRetriever != null)
                    ffmpegRetriever.release();
            } catch (RuntimeException e) {
                LogUtils.e(TAG, e);
            }
        }

        if (bitmap == null) {
            LogUtils.e(TAG, "$$$$$$$" + video.name + ", " + "获取缩略图失败$$$$$$$");
            return;
        }

        try {
            // 缓存到SD卡
            if (writeThumbToFile(bitmap, video.name + ".png"))
                video.thumb_identifier = "1";
        } catch (Exception e) {
            LogUtils.e(TAG, e);
        } finally {
            if (bitmap != null)
                bitmap.recycle();
        }
    }

    /**
     * 视频缩略图写入SD卡
     */
    public static boolean writeThumbToFile(Bitmap bitmap, String fileName) {
        FileOutputStream out = null;
        boolean result = false;
        try {
            File thumbFile = new File(VideoConfig.PLAYER_VIDEO_THUMB, fileName);
            if (thumbFile.exists())
                return true;

            out = new FileOutputStream(thumbFile);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
            result = true;
        } catch (FileNotFoundException e) {
            LogUtils.e(TAG, e);
        } finally {
            IOUtils.close(out);
        }
        return result;
    }

Vitamio封装的MediaMetadataRetriever

vitamio是一款全能的多媒体开发框架, 使用vitamio封装的MediaMetadataRetriever可以获取”3gp”, “mp4”, “mkv”, “mov”, “avi”, “wmv”, “ts”,”asf”, “m4v”, “3g2”, “tp”, “mtp”, “m2t”等视频文件的元数据信息。不支持:rmvb、rm、flv。

GitHub:FFmpegMediaMetadataRetriever

项目地址:
https://github.com/wseemann/FFmpegMediaMetadataRetriever

从名字就可以看出是封装了FFmpeg多媒体解码框架,它支持几乎所有主流视频文件。但是速度明显比android原生态和Vitamio的慢。不支持:rmvb、rm。

还有一个重要的问题,就是如果频繁调用FFmpegMediaMetadataRetriever获取视频缩略图,会导致自己写的线程莫名奇妙的停止工作,底层创建线程失败。数据库查询error,如“Could not allocate CursorWindow size due to error -12”的异常。这个问题坑了我好久,最后还是放弃FFmpegMediaMetadataRetriever,使用系统自带的就没问题了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值