Java h265视频抽帧提取照片支持Window,Linux
生活随笔
收集整理的這篇文章主要介紹了
Java h265视频抽帧提取照片支持Window,Linux
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Java H265視頻抽幀提取照片
- 1. Windows下可調用ffmpeg.exe實現,親測可行
- 2. linux下調用FFmpegFrameGrabber
- 3. 源碼
- 4. 效果圖
- 5. pom依賴
- 參考:
1. Windows下可調用ffmpeg.exe實現,親測可行
- 可以直接執行命令行
# 把目錄下視頻——E:\\data\\test.h265抽幀每一幀為圖片,并命名為1.jpg,2.jpg,3.jpg...存儲在E:\\data\\test\\images\\文件夾
ffmpeg.exe -y -i E:\\data\\test.h265 -ss 00:00:00 -f image2 -vsync 2 E:\\data\\test\\images\\%d.jpg
前提需要目錄E:\data\test\images\存在;
- 可以Java ProcessBuilder調用如上命令行實現;
2. linux下調用FFmpegFrameGrabber
- 調用跨平臺的ffmpeg
- python代碼打包成linux平臺可調用的二進制文件
- 推薦優雅的方案:FFmpegFrameGrabber
3. 源碼
包括
- ffmpeg.exe windows支持,linux需要自己配置ffmpeg
- FFmpegFrameGrabber,跨平臺,支持windows,支持linux
倆個的實現源碼如下:
package com.video.extract.test;import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bytedeco.javacv.*;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Arrays;/**************************************Class Name: VideoUtils*Description: <視頻抽幀類>*@author: Seminar*@create: 2021/1/28*@since 1.0.0*************************************/
@Slf4j
public class VideoUtils {/*** 抽幀程序* <p>* ffmpeg.exe -y -i data\test.H265 -ss 00:00:00 -f image2 -vsync 2 data\test\image\%d.jpg** @param videoPath 原始視頻文件路徑* @param imgPath 抽幀圖片存儲路徑* @throws IOException*/public static void ffmpegFrameExtract(String videoPath, String imgPath) throws IOException {if (StringUtils.isEmpty(videoPath)) {return;}File imgPathFolder = new File(imgPath);if (!imgPathFolder.exists()) {imgPathFolder.mkdirs();} else {delDir(imgPathFolder);imgPathFolder.mkdirs();}String path = System.getProperty("user.dir") + File.separator + "frameExtract" + File.separator + "ffmpeg.exe";ProcessBuilder processBuilder = new ProcessBuilder(path, "-y","-i", videoPath,"-ss", "00:00:00","-f", "image2","-vsync", "2",imgPath + "%d.jpg");processBuilder.redirectErrorStream(true);Process process = processBuilder.start();StringBuilder processOutput = new StringBuilder();try (BufferedReader processOutputReader = new BufferedReader(new InputStreamReader(process.getInputStream()));) {String readLine;while ((readLine = processOutputReader.readLine()) != null) {processOutput.append(readLine + System.lineSeparator());}process.waitFor();} catch (IOException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();} finally {if (process != null) {process.destroy();}}// 只返回抽幀的最后3行總覽信息String[] str = processOutput.toString().trim().split("\n");String[] res = new String[3];System.arraycopy(str, str.length - 3, res, 0, 3);log.info("ffmpegFrameExtract res: {}", String.join("\n", Arrays.asList(res)));}/*** 視頻抽幀** @param videoPath 原始視頻文件路徑* @param imagePath 抽幀圖片存儲路徑* @throws FrameGrabber.Exception* @throws FileNotFoundException*/public static void ffmpegFrameGrabber(String videoPath, String imagePath) throws FrameGrabber.Exception, FileNotFoundException {
// FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videoPath);// 此處可為視頻路徑,也可為二進制視頻流FFmpegFrameGrabber ff = new FFmpegFrameGrabber(new FileInputStream(videoPath));// 此處可為視頻路徑,也可為二進制視頻流
// ff.setAudioCodecName("h265");ff.start();int ffLength = ff.getLengthInFrames();double ffFrameRate = ff.getFrameRate();long videoLength = ff.getLengthInTime();log.info("\n");log.info("ffmpegFrameGrabber: 幀數:{}, 幀率:{},視頻長度:", ffLength, ffFrameRate, videoLength);Frame f = ff.grabImage();int k = 0;while (f != null) {Java2DFrameConverter converter = new Java2DFrameConverter();String imageMat = "jpg";String fileName = imagePath + k + "." + imageMat;BufferedImage bi = converter.getBufferedImage(f);File output = new File(fileName);try {ImageIO.write(bi, imageMat, output);} catch (IOException e) {log.error("writeJpgError: {}", e.getMessage());e.printStackTrace();}k++;f = ff.grabImage();}ff.stop();log.info("jpgSize: {}", k);}/*** 遞歸刪除多層目錄** @param file*/public static void delDir(File file) {// 文件直接刪除if (file.isFile()) {file.delete();} else {// 目錄,需要遞歸刪除for (File sonfile : file.listFiles()) {delDir(sonfile);}}file.delete();}public static void main(String[] args) throws IOException {String videoPath = "D:\\project\\frame-extract\\doc\\test.h265";String imagePath = videoPath.substring(0, videoPath.lastIndexOf(".")).concat(File.separator).concat("images").concat(File.separator);// ffmpeg.exe抽幀ffmpegFrameExtract(videoPath, imagePath);// FFmpegFrameGrabber 抽幀ffmpegFrameGrabber(videoPath, imagePath);}
}
4. 效果圖
5. pom依賴
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bytedeco/javacv -->
<dependency><groupId>org.bytedeco</groupId><artifactId>javacv</artifactId><version>1.5</version>
</dependency>
<dependency><groupId>org.bytedeco</groupId><artifactId>javacv-platform</artifactId><version>1.5</version>
</dependency>
<dependency><groupId>org.bytedeco</groupId><artifactId>javacpp</artifactId><version>1.5</version>
</dependency>
<dependency><groupId>org.bytedeco.javacpp-presets</groupId><artifactId>ffmpeg-platform</artifactId><version>4.1-1.4.4</version>
</dependency>
參考:
- https://blog.csdn.net/qq_34928194/article/details/108388653
- https://blog.csdn.net/jl19861101/article/details/94555851
總結
以上是生活随笔為你收集整理的Java h265视频抽帧提取照片支持Window,Linux的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python,OpenCV图像处理超好用
- 下一篇: 使用Java对轨迹进行抽稀,并生成mvt