1引入maven依賴
網上大多引入的是
<!-- https://mvnrepository.com/artifact/org.bytedeco/javacv-platform --> <dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv-platform</artifactId> <version>1.5.2</version> </dependency>
此依賴會下載所有jar 包括了android,linux,macosx、windows等平台,大概有400多M,所以需要對依賴進行精簡
<dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv</artifactId> <version>1.4.2</version> <exclusions> <exclusion> <groupId>org.bytedeco.javacpp-presets</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.bytedeco.javacpp-presets</groupId> <artifactId>opencv</artifactId> <version>3.4.2-1.4.2</version> </dependency> <dependency> <groupId>org.bytedeco.javacpp-presets</groupId> <artifactId>opencv</artifactId> <version>3.4.2-1.4.2</version> <!-- <classifier>windows-x86_64</classifier>--> <classifier>linux-x86_64</classifier> </dependency> <!-- https://mvnrepository.com/artifact/org.bytedeco.javacpp-presets/ffmpeg --> <dependency> <groupId>org.bytedeco.javacpp-presets</groupId> <artifactId>ffmpeg</artifactId> <version>4.0.1-1.4.2</version> </dependency> <dependency> <groupId>org.bytedeco.javacpp-presets</groupId> <artifactId>ffmpeg</artifactId> <version>4.0.1-1.4.2</version> <!--<classifier>windows-x86_64</classifier>--> <classifier>linux-x86_64</classifier> </dependency>
classifier 根據當前系統進行配置,windows 可使用 windows-x86_64。linux可根據實際情況選擇
其他平台需要用可以在classifier里面修改成對應的
<javacpp.platform.android-arm>android-arm</javacpp.platform.android-arm> <javacpp.platform.android-arm64>android-arm64</javacpp.platform.android-arm64> <javacpp.platform.android-x86>android-x86</javacpp.platform.android-x86> <javacpp.platform.android-x86_64>android-x86_64</javacpp.platform.android-x86_64> <javacpp.platform.ios-arm>ios-arm</javacpp.platform.ios-arm> <javacpp.platform.ios-arm64>ios-arm64</javacpp.platform.ios-arm64> <javacpp.platform.ios-x86>ios-x86</javacpp.platform.ios-x86> <javacpp.platform.ios-x86_64>ios-x86_64</javacpp.platform.ios-x86_64> <javacpp.platform.linux-armhf>linux-armhf</javacpp.platform.linux-armhf> <javacpp.platform.linux-arm64>linux-arm64</javacpp.platform.linux-arm64> <javacpp.platform.linux-ppc64le>linux-ppc64le</javacpp.platform.linux-ppc64le> <javacpp.platform.linux-x86>linux-x86</javacpp.platform.linux-x86> <javacpp.platform.linux-x86_64>linux-x86_64</javacpp.platform.linux-x86_64> <javacpp.platform.macosx-x86_64>macosx-x86_64</javacpp.platform.macosx-x86_64> <javacpp.platform.windows-x86>windows-x86</javacpp.platform.windows-x86> <javacpp.platform.windows-x86_64>windows-x86_64</javacpp.platform.windows-x86_64>
Linux查看內核判斷命令 : arch
2、java 實現代碼
package com.util; import org.bytedeco.javacv.FFmpegFrameGrabber; import org.bytedeco.javacv.Frame; import org.bytedeco.javacv.Java2DFrameConverter; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.util.HashMap; import java.util.Map; /** * 視頻處理工具類 * @author admin */ public class VideoUtil { /** * 獲取視頻封面圖 * @param filePath 視頻地址 * @param mod 開始幀數 * @return map * @throws Exception */ public static Map<String, Object> getScreenshot(String filePath,int mod) throws Exception{ filePath = filePath.replaceAll("\\\\","/"); System.out.println("截取視頻截圖開始:"+ System.currentTimeMillis()); Map<String, Object> result = new HashMap<>(); FFmpegFrameGrabber grabber = FFmpegFrameGrabber.createDefault(filePath); // 第一幀圖片存儲位置 String targerFilePath = filePath.substring(0, filePath.lastIndexOf("/")); // 視頻文件名 String fileName = filePath.substring(filePath.lastIndexOf("/") + 1); // 圖片名稱 String targetFileName = fileName.substring(0, fileName.lastIndexOf(".")); grabber.start(); //設置視頻截取幀(建議從5幀開始,防止全是黑屏) Frame frame = null; for (int j = 0; j < mod; j++) { frame = grabber.grabImage(); } //視頻旋轉度 String rotate = grabber.getVideoMetadata("rotate"); Java2DFrameConverter converter = new Java2DFrameConverter(); //繪制圖片 BufferedImage bi = converter.getBufferedImage(frame); if (rotate != null) { // 旋轉圖片 bi = rotate(bi, Integer.parseInt(rotate)); } //圖片的類型 String imageMat = "jpg"; //圖片的完整路徑 String imagePath = targerFilePath + File.separator + targetFileName + "." + imageMat; //創建文件 File output = new File(imagePath); ImageIO.write(bi, imageMat, output); //拼接Map信息 result.put("videoWide", bi.getWidth()); result.put("videoHigh", bi.getHeight()); long duration = grabber.getLengthInTime() / (1000 * 1000); result.put("rotate", StringUtil.isEmpty(rotate)? "0" : rotate); result.put("format", grabber.getFormat()); result.put("imgPath", output.getPath()); System.out.println("視頻的寬:" + bi.getWidth()); System.out.println("視頻的高:" + bi.getHeight()); System.out.println("視頻的旋轉度:" + rotate); System.out.println("視頻的格式:" + grabber.getFormat()); System.out.println("此視頻時長(s/秒):" + duration); grabber.stop(); System.out.println("截取視頻截圖結束:"+ System.currentTimeMillis()); return result; } /** * @Description: 根據視頻旋轉度來調整圖片 * @param src * @param angel 視頻旋轉度 * @return BufferedImage */ public static BufferedImage rotate(BufferedImage src, int angel) { int src_width = src.getWidth(null); int src_height = src.getHeight(null); int type = src.getColorModel().getTransparency(); Rectangle rect_des = calcRotatedSize(new Rectangle(new Dimension(src_width, src_height)), angel); BufferedImage bi = new BufferedImage(rect_des.width, rect_des.height, type); Graphics2D g2 = bi.createGraphics(); g2.translate((rect_des.width - src_width) / 2, (rect_des.height - src_height) / 2); g2.rotate(Math.toRadians(angel), src_width / 2, src_height / 2); g2.drawImage(src, 0, 0, null); g2.dispose(); return bi; } /** * @Description: 計算圖片旋轉大小 * @param src * @param angel * @return Rectangle */ public static Rectangle calcRotatedSize(Rectangle src, int angel) { if (angel >= 90) { if (angel / 90 % 2 == 1) { int temp = src.height; src.height = src.width; src.width = temp; } angel = angel % 90; } double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2; double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r; double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2; double angel_dalta_width = Math.atan((double) src.height / src.width); double angel_dalta_height = Math.atan((double) src.width / src.height); int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_width)); int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_height)); int des_width = src.width + len_dalta_width * 2; int des_height = src.height + len_dalta_height * 2; return new java.awt.Rectangle(new Dimension(des_width, des_height)); } }
3、測試
public static void main(String[] args) throws IOException { String clientTime ="2020-02-20",startTime="2020-04-03 00:00:00"; System.out.println(clientTime.length()); System.out.println(startTime.length()); /*int s1= DateUtil.compareTo(clientTime,startTime,DateUtil.NORM_DATETIME_PATTERN); System.out.println(s1);*/ String filePath="D:/home/ddc761004d.mp4"; try { Map<String, Object> map = VideoUtil.getScreenshot(filePath,25); } catch (Exception e) { e.printStackTrace(); } }
參考地址:
https://blog.csdn.net/lianzhang861/article/details/82014460
https://blog.csdn.net/huangwen123456/article/details/82492375