Java获取视频时长及截取帧截图详解
作者:happyJared 发布时间:2022-03-28 20:52:53
标签:java,视频,截取,帧,截图
前言
只是最近碰到有这方面的项目需求,所以简单 Mark 下本文。下面的示例是参考过他人分享的文章,之后本人再自行实践、调整和测试过的,希望对有这方面需求的人有所帮助。
示例
添加依赖
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.4.4</version>
</dependency>
上述这段 maven 依赖包含了完整的 javacv 功能 (非常多,依赖Jar就占大概有500MB),由于这里只使用到了其中 ffmpeg 这块的特性,因此也可以像下面这样排除掉无关的部分
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.4.4</version>
<exclusions>
<exclusion>
<groupId>org.bytedeco</groupId>
<artifactId>javacpp</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>flycapture</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>libdc1394</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>libfreenect</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>libfreenect2</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>librealsense</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>videoinput</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>opencv</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>tesseract</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>leptonica</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>flandmark</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>artoolkitplus</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.4.4</version>
<exclusions>
<exclusion>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>flycapture-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>libdc1394-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>libfreenect-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>libfreenect2-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>librealsense-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>videoinput-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>opencv-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>tesseract-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>leptonica-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>flandmark-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>artoolkitplus-platform</artifactId>
</exclusion>
</exclusions>
</dependency>
核心代码
获取视频时长
/**
* 获取视频时长,单位为秒
*
* @param video 源视频文件
* @return 时长(s)
*/
public static long getVideoDuration(File video) {
long duration = 0L;
FFmpegFrameGrabber ff = new FFmpegFrameGrabber(video);
try {
ff.start();
duration = ff.getLengthInTime() / (1000 * 1000);
ff.stop();
} catch (FrameGrabber.Exception e) {
e.printStackTrace();
}
return duration;
}
截取视频指定帧为图片
/**
* 截取视频获得指定帧的图片
*
* @param video 源视频文件
* @param picPath 截图存放路径
*/
public static void getVideoPic(File video, String picPath) {
FFmpegFrameGrabber ff = new FFmpegFrameGrabber(video);
try {
ff.start();
// 截取中间帧图片(具体依实际情况而定)
int i = 0;
int length = ff.getLengthInFrames();
int middleFrame = length / 2;
Frame frame = null;
while (i < length) {
frame = ff.grabFrame();
if ((i > middleFrame) && (frame.image != null)) {
break;
}
i++;
}
// 截取的帧图片
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage srcImage = converter.getBufferedImage(frame);
int srcImageWidth = srcImage.getWidth();
int srcImageHeight = srcImage.getHeight();
// 对截图进行等比例缩放(缩略图)
int width = 480;
int height = (int) (((double) width / srcImageWidth) * srcImageHeight);
BufferedImage thumbnailImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
thumbnailImage.getGraphics().drawImage(srcImage.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
File picFile = new File(picPath);
ImageIO.write(thumbnailImage, "jpg", picFile);
ff.stop();
} catch (IOException e) {
e.printStackTrace();
}
}
测试用例
public static void main(String[] args) {
String videoPath = ResourceUtils.CLASSPATH_URL_PREFIX + "video.mp4";
File video = null;
try {
video = ResourceUtils.getFile(videoPath);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String picPath = "video.jpg";
getVideoPic(video, picPath);
long duration = getVideoDuration(video);
System.out.println("videoDuration = " + duration);
}
示例源码
来源:https://www.jianshu.com/p/3a9f889712ab


猜你喜欢
- 一、前言 验证码可以说在我们生活中已经非常普遍了,任何一个网站,任何一个App都
- 前言最近被问到了这个问题,第一次回答的也是很不好,在此参考网上答案进行整理记录。供大家学习参考。Synchronized修饰非静态方法Syn
- 目录一、复习二、两者对比三、在什么情况下才会使用volatile四、Java中的原子性操作五、Java中的CAS操作六、ABA问题七、Uns
- 什么是线程线程被称为轻量级进程,是程序执行的最小单位,它是指在程序执行过程中,能够执行代码的一个执行单位。每个程序程序都至少有一个线程,也即
- 前言本文是精讲RestTemplate第8篇,前篇的blog访问地址如下:RestTemplate在Spring或非Spring环境下使用精
- 不得已重新配置,这里记下详细步骤,分享给大家。一、安装jdk,具体步骤如下:1、将jdk-7u4-linux-i586.tar拷贝到linu
- 0引言随着万维网的发展和大数据时代的到来,每天都有大量的数字化信息在生产、存储、传递和转化,如何从大量的信息中以一定的方式找到满足自己需求的
- 创建类的对象 = 类的实例化 = 实例化类类和对象的使用(面向对象思想落地的实现):1.创建类,设计类的成员2.创建类的对象3.通过“对象.
- 本文实例为大家分享了C#实现简易点餐功能的具体代码,供大家参考,具体内容如下图示效果实现过程1.设计界面2.设计控件及其属性3.实现点击事件
- 概述 ScrollView也是一个容器,它是FrameLayout的子类,它的主要作用就是将超出物理屏幕的内容显示
- 关于startService的基本使用概述及其生命周期可参见《Android中startService基本使用方法概述》。本文通过批量下载文
- 目录1、数组本质2、指针3、字符数组4、char * 与 char a[ ]5、char ** 和char *a[]6、C语言中char s
- 这里使用Spring Boot 2.7.4版本,对应Spring Security 5.7.3版本本文样例代码地址: spring-secu
- 本文参考借鉴:https://www.jb51.net/article/102983.htm先上效果图:自定义控件:AttendancePr
- 摘要:本文演示如何构建起一个优秀的后端接口体系,体系构建好了自然就有了规范,同时再构建新的后端接口也会十分轻松。一个后端接口大致分为四个部分
- 当前比较成熟一点的应用基本上都会在进入应用之显示一个启动界面.这个启动界面或简单,或复杂,或简陋,或华丽,用意不同,风格也不同.下面来观摩几
- 一般情况下每个spring boot工程启动都有固定的端口,但是固定端口不利用服务的动态扩容,如果在一台服务器上需要对同一个服务进行多实例部
- 主要用的是org.apache.tools.zip.ZipOutputStream 这个zip流,这里以Execl为例子。思路首
- Spring提供的工具类,主要用于框架内部使用,这个类提供了一些简单的方法,并且提供了易于使用的方法在分割字符串,如CSV字符串,以及集合和
- 做项目的时候需要对拿到的数据进行“清洗”,比如剔除一些不可能存在的身份证号码。查阅了网上的身份证号码验证算法,自己也总结一下。(一)18身份