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); }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
赞 (0)