package test; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.TreeSet; import javax.imageio.ImageIO; import org.bytedeco.javacv.FFmpegFrameGrabber; import org.bytedeco.javacv.Frame; import org.bytedeco.javacv.Java2DFrameConverter; public class VideoTest { public static String image_type="jpg"; public static String file_type="mp4"; public static void main(String[] args) { String videofile="C:/xmqtest/test視頻.mp4";//或網絡視頻地址 String framefileDir="C:/xmqtest/"; String targetFilePath=fetchFrame(videofile,framefileDir); } /** * 獲取指定視頻的幀並保存爲圖片至指定目錄 * @param videofile 源視頻文件路徑 * @param framefile 截取幀的圖片存放路徑 * @throws Exception */ public static String fetchFrame(String videofile, String framefileDir){ try{ int startIndex=videofile.lastIndexOf('/'); String fileName; if(startIndex==-1){ fileName=videofile.substring(videofile.lastIndexOf('\\')+1, videofile.lastIndexOf('.')); }else{ fileName=videofile.substring(startIndex+1, videofile.lastIndexOf('.')+1); } String targetFileName=framefileDir+fileName+image_type; File targetFile=createFile(targetFileName); FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videofile); ff.start(); String rotate_old=ff.getVideoMetadata("rotate");//視頻旋轉角度,多是null int length = ff.getLengthInFrames(); int i = 0; Frame f = null; while (i < length) { // 過濾前5幀,避免出現全黑的圖片,依本身狀況而定 f = ff.grabFrame(); if ((i > 5) && (f.image != null)) { break; } i++; } // IplImage img = f.image; int owidth = f.imageWidth; int oheight = f.imageHeight; // 對截取的幀進行等比例縮放 int width = 300;//生成圖片寬度爲300px int height = (int) (((double) width / owidth) * oheight); Java2DFrameConverter converter = new Java2DFrameConverter(); BufferedImage fecthedImage = converter.getBufferedImage(f); BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); bi.getGraphics().drawImage(fecthedImage.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null); ImageIO.write(bi, image_type, targetFile); ff.stop(); //有須要旋轉 if(rotate_old!=null && !rotate_old.isEmpty()){ int rotate=Integer.parseInt(rotate_old); rotatePhonePhoto(targetFileName,rotate); } return targetFileName; }catch(Exception e){ e.printStackTrace(); } return null; }/*** * 建立文件,目錄不存在則先建立目錄在建立文件 * @param destFileName * @return */ public static File createFile(String destFileName) { try { File file = new File(destFileName); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } file.createNewFile(); return file; } catch (IOException e) { e.printStackTrace(); return null; } } /** * 刪除單個文件 */ public static void deleteFile(String sPath) { File file = new File(sPath); if (file.isFile() && file.exists()) { file.delete(); } } /** * 旋轉照片 * * @return */ public static String rotatePhonePhoto(String fullPath, int angel) { BufferedImage src; try { src = ImageIO.read(new File(fullPath)); int src_width = src.getWidth(null); int src_height = src.getHeight(null); int swidth = src_width; int sheight = src_height; if (angel == 90 || angel == 270) { swidth = src_height; sheight = src_width; } Rectangle rect_des = new Rectangle(new Dimension(swidth, sheight)); BufferedImage res = new BufferedImage(rect_des.width, rect_des.height, BufferedImage.TYPE_INT_RGB); Graphics2D g2 = res.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, null, null); ImageIO.write(res,image_type, new File(fullPath)); } catch (Exception e) { e.printStackTrace(); } return fullPath; } }
說明點:java
一、加入依賴,經測試兩個依賴在windows環境,linux環境下正常使用。若是本地windows環境正常可是在linux下失敗,請使用如下依賴。linux
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.4.3</version>
</dependency>
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>ffmpeg-platform</artifactId>
<version>4.0.2-1.4.3</version>
</dependency>
二、針對iphone手機視頻等須要進行首幀圖片旋轉,不然出現首幀圖片橫着的狀況。如代碼部分:
String rotate_old=ff.getVideoMetadata("rotate");//視頻旋轉角度,多是null