android提取视频多张图片和视频信息实例

发布时间 - 2026-01-11 01:21:28    点击率:

话说2016年的|直播|比较火,2017年短视频又火了。但对于开发者来说隐藏在这背后的技术才是我们所关心的,毕竟我们是靠技术吃饭的。

现在在安卓中多媒体服务比较强大,而与视频有关的视频基本处理技术有必要学习一下。我前段时间也在做有关视频的一些需求,当然也涉及本文的标题内容。

经测试和研究发现在android中提取视频图片的方法只有MediaMetadataRetriever这个类比较靠谱简单实用。当然OpenGL-也可以做到哈!(后者不展开介绍),

最后会把完整的demo献上。

效果图

技术需求

  1. 需求一:给你一个视频提取第一个关键帧图片作为视频的封面,好处呢!?就是当没有播放的时候显示视频的首帧图片,当点击播放按钮时(或者自动播放)视频和首帧图片能连惯起来,是个很不错的体验。
  2. 需求二:提取多张图片,用户可以滑动这些缩略图来查看视频的大体内容,然后截取指定的视频区域进行编辑,这个需求类似:微信的小视频编辑界面。这个会在第二篇文章中实现。实现高速度提取视频图片。
  3. 需求三:提取视频的基本信息,比如宽高,视频的时长。这个主要用于上传视频文件时的参数提交,然后展示的时候用视频宽高做UI特效,比如不规则之美-瀑布流

调研

先看第3个问题,这个比较简单。主要是MediaMetadataRetriever这个系统API类。

大体意思就是:给定一个媒体文件,它能检索/输出一些元数据和帧。有点意思哈,它加载了动态库media_jni,可见它是一个十分接近底层的一个类。

技术实现-视频基本信息的获取

看一下类结构,有一些常量,作为一线码农,我懂你哦。


//1.初始化
   mMetadataRetriever = new MediaMetadataRetriever();

//2.设置视频源文件mMetadataRetriever.setDataSource(file.getAbsolutePath());
//3.获取视频的宽
String w = mMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
 //获取视频的高
String h = mMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
 //获取视频的时长,ms
mMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);

// 等等...一些其它属性,比如媒体类型(3gp,mp4) ,视频旋转角度
//4.释放资源,防止内存泄漏,养成好习惯
 mMetadataRetrieve.release();

我自己简单了写了一个util类,最后会献上。

技术实现-获取视频关键帧

直接上代码-我懂你

 public Bitmap extractFrame(long timeMs) {
    //第一个参数是传入时间,只能是us(微秒)
    //OPTION_CLOSEST ,在给定的时间,检索最近一个帧,这个帧不一定是关键帧。
    //OPTION_CLOSEST_SYNC  在给定的时间,检索最近一个同步与数据源相关联的的帧(关键帧)
    //OPTION_NEXT_SYNC 在给定时间之后检索一个同步与数据源相关联的关键帧。
    //OPTION_PREVIOUS_SYNC 在给定时间之前检索一个同步与数据源相关联的关键帧。

// Bitmap bitmap = mMetadataRetriever.getFrameAtTime(timeMs * 1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
    Bitmap bitmap = null;
    for (long i = timeMs; i < fileLength; i += 1000) {
      bitmap = mMetadataRetriever.getFrameAtTime(i * 1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
      if (bitmap != null) {
        break;
      }
    }
    return bitmap;
  }

实用的时候直接: Bitmap bitmap = extractFrame(0); fileLength为视频的时长( 毫秒数),返回bitmap ,然后你用可以操作bitmap了,比如保存到sd卡上,看你爱好了。有人问:咿,怎么for循环啊?是这样的,我遇到过有时候你传入的0,它有时候返回的bitmap为null,找不到关键帧,因此你需要多次递增1秒获取。
那么需求一的实现也OK了,但是有一点需要注意就是展示视频的控件的宽和高和盖在上面的图片的控件的宽和高一样才有你播放的时候就连贯了。

技术实现-获取视频多张图片

我相信大家都能想到需求一的for循环一下不就可以了吗,是的,没错。

首先提取图片遇到高清视频可能耗时,我经过测试用vivo-xplay-5a ,1080高清视频,提取一张图片也就是mMetadataRetriever.getFrameAtTime()方法大概90-120ms之间。

  1. 方案:因此你需要一个工作线程+handler,每提取一张保存到sd卡中,然后用handeler发送保存图片的路径展示到UI上。demo中会展示到recycleview上,然后用glide图片加载框架一张一张的显示出来。当然你也可以自己缓存mMetadataRetriever.getFrameAtTime 返回的bitmap,不过不建议这么做。
  2. 怎么循环提取,假设视频文件长度是60s,需要提取10张图片,也就是1张图片代表了6s,60/10,
for (int i = 0; i < thumbnailsCount; i++) {
      if (stop) {
        metadataRetriever.release();
        break;
      }
      long time = startPosition + interval * i;
      if (i == thumbnailsCount - 1) {
        if (interval > 1000) {
          String path = extractFrame(metadataRetriever, endPosition - 800, OutPutFileDirPath);
          sendAPic(path, endPosition - 800);
        } else {
          String path = extractFrame(metadataRetriever, endPosition, OutPutFileDirPath);
          sendAPic(path, endPosition);
        }
      } else {
        String path = extractFrame(metadataRetriever, time, OutPutFileDirPath);
        sendAPic(path, time);
      }
    }

stop是停止提取图片的标志,extractFrame方法就是metadataRetriever.getFrameAtTime()返回bitmap然后 bitmap.compress()返回保存到sd卡上的图片路径,最后sendAPic将提取的图片路径和时间加工为一个对象借助handler更新到UI线程中去,然后展示到recycleview上去,具体代码可以参考demo。这里保存的图片没有进行压缩,第二篇文章会具体讲到。

demo地址:https://github.com/ta893115871/MediaMetadataRetrieverDemo

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# android提取视频图片  # android视频提取图片  # android提取视频信息  # Android开发之多媒体文件获取工具类实例【音频  # 视频  # 图片等】  # Android多媒体之VideoView视频播放器  # Android多媒体教程之播放视频的四种方法  # Android开发之MediaPlayer多媒体(音频  # 视频)播放工具类  # Android开发实现的IntentUtil跳转多功能工具类【包含视频、音频、图片、摄像头等操作功能  # Android中简单调用图片、视频、音频、录音和拍照的方法  # android 获取视频  # 图片缩略图的具体实现  # Android获取SD卡上图片和视频缩略图的小例子  # Android编程获取图片和视频缩略图的方法  # Android如何获取图片或视频略缩图  # Android编程实现获取多媒体库视频、音频、图片的方法  # 相关联  # 时长  # 第一个  # 视频文件  # 多张  # 卡上  # 懂你  # 加载  # 是个  # 好了  # 给你  # 才是  # 在这  # 是这样  # 都能  # 找不到  # 也在  # 会在  # 它是  # 看你 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel怎么实现软删除SoftDeletes_Laravel模型回收站功能与数据恢复【步骤】  如何选择PHP开源工具快速搭建网站?  Python面向对象测试方法_mock解析【教程】  标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?  C语言设计一个闪闪的圣诞树  Laravel如何实现用户注册和登录?(Auth脚手架指南)  Laravel项目如何进行性能优化_Laravel应用性能分析与优化技巧大全  Laravel如何使用Eloquent进行子查询  Laravel怎么实现搜索功能_Laravel使用Eloquent实现模糊查询与多条件搜索【实例】  Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比  个人网站制作流程图片大全,个人网站如何注销?  Laravel Fortify是什么,和Jetstream有什么关系  如何用好域名打造高点击率的自主建站?  jimdo怎样用html5做选项卡_jimdo选项卡html5实现与切换效果【指南】  韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南  Laravel如何优雅地处理服务层_在Laravel中使用Service层和Repository层  Laravel的Blade指令怎么自定义_创建你自己的Laravel Blade Directives  Zeus浏览器网页版官网入口 宙斯浏览器官网在线通道  Laravel怎么配置不同环境的数据库_Laravel本地测试与生产环境动态切换【方法】  Laravel如何配置和使用队列处理异步任务_Laravel队列驱动与任务分发实例  如何将凡科建站内容保存为本地文件?  潮流网站制作头像软件下载,适合母子的网名有哪些?  深入理解Android中的xmlns:tools属性  深圳网站制作的公司有哪些,dido官方网站?  JavaScript中的标签模板是什么_它如何扩展字符串功能  Laravel N+1查询问题如何解决_Eloquent预加载(Eager Loading)优化数据库查询  Android GridView 滑动条设置一直显示状态(推荐)  网站制作大概要多少钱一个,做一个平台网站大概多少钱?  ChatGPT怎么生成Excel公式_ChatGPT公式生成方法【指南】  Windows10电脑怎么查看硬盘通电时间_Win10使用工具检测磁盘健康  Internet Explorer官网直接进入 IE浏览器在线体验版网址  Laravel如何处理JSON字段_Eloquent原生JSON字段类型操作教程  Laravel如何处理文件下载请求?(Response示例)  北京网站制作公司哪家好一点,北京租房网站有哪些?  详解Oracle修改字段类型方法总结  EditPlus中的正则表达式 实战(1)  Laravel怎么调用外部API_Laravel Http Client客户端使用  WordPress 子目录安装中正确处理脚本路径的完整指南  Laravel如何配置.env文件管理环境变量_Laravel环境变量使用与安全管理  Laravel 419 page expired怎么解决_Laravel CSRF令牌过期处理  如何用IIS7快速搭建并优化网站站点?  Laravel中的Facade(门面)到底是什么原理  如何快速搭建安全的FTP站点?  Laravel如何处理跨站请求伪造(CSRF)保护_Laravel表单安全机制与令牌校验  javascript读取文本节点方法小结  如何在Ubuntu系统下快速搭建WordPress个人网站?  Laravel如何编写单元测试和功能测试?(PHPUnit示例)  Bootstrap整体框架之CSS12栅格系统  网站建设保证美观性,需要考虑的几点问题!  Laravel项目结构怎么组织_大型Laravel应用的最佳目录结构实践