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);

}

示例源码

以上是 Java获取视频时长及截取帧截图详解 的全部内容, 来源链接: utcz.com/z/359516.html

回到顶部