轉載請註明出處:https://blog.csdn.net/l1028386804/article/details/79755510
一、建立項目 1、建立Maven項目 2、添加依賴
在pom.xml中添加依賴配置,具體如下:
<dependencies> <dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv-platform</artifactId> <version>1.3.1</version> </dependency></dependencies>
二、具體實現
1、擷取視頻中間的幀作為縮圖,並返回縮圖實際存放地址
package com.lyz.medis.image;import java.awt.image.BufferedImage;import java.io.File;import java.io.IOException;import java.util.ArrayList;import java.util.Collections;import java.util.List;import javax.imageio.ImageIO;import org.bytedeco.javacpp.opencv_core;import org.bytedeco.javacpp.opencv_core.IplImage;import org.bytedeco.javacv.FFmpegFrameGrabber;import org.bytedeco.javacv.Frame;import org.bytedeco.javacv.FrameGrabber.Exception;import org.bytedeco.javacv.Java2DFrameConverter;import org.bytedeco.javacv.OpenCVFrameConverter;/** * 擷取影片縮圖 * @author liuyazhuang * */public class VideoImage {private static final String IMAGEMAT = "png";private static final String ROTATE = "rotate";/** * 預設截取視頻的中間幀為封面 */public static final int MOD = 2;public static void main(String[] args) throws Exception {System.out.println(randomGrabberFFmpegImage("C:/lyz/1522372294724_79583.mov", 2));}/** * 擷取影片縮圖 * @param filePath:視頻路徑 * @param mod:視頻長度/mod擷取第幾幀 * @throws Exception */public static String randomGrabberFFmpegImage(String filePath, int mod) throws Exception {String targetFilePath = "";FFmpegFrameGrabber ff = FFmpegFrameGrabber.createDefault(filePath);ff.start();String rotate = ff.getVideoMetadata(ROTATE);int ffLength = ff.getLengthInFrames();Frame f;int i = 0;int index = ffLength / mod;while (i < ffLength) {f = ff.grabImage();if(i == index){if (null != rotate && rotate.length() > 1) {OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();IplImage src = converter.convert(f);f = converter.convert(rotate(src, Integer.valueOf(rotate)));}targetFilePath = getImagePath(filePath, i);doExecuteFrame(f, targetFilePath);break;}i++;}ff.stop();return targetFilePath;}/** * 根據視頻路徑產生縮圖存放路徑 * @param filePath:視頻路徑 * @param index:第幾幀 * @return:縮圖的存放路徑 */private static String getImagePath(String filePath, int index){if(filePath.contains(".") && filePath.lastIndexOf(".") < filePath.length() - 1){filePath = filePath.substring(0, filePath.lastIndexOf(".")).concat("_").concat(String.valueOf(index)).concat(".").concat(IMAGEMAT);}return filePath;} /** * 旋轉圖片 * @param src * @param angle * @return */public static IplImage rotate(IplImage src, int angle) {IplImage img = IplImage.create(src.height(), src.width(), src.depth(), src.nChannels());opencv_core.cvTranspose(src, img);opencv_core.cvFlip(img, img, angle);return img;}/** * 截取縮圖 * @param f * @param targerFilePath:封面圖片 */public static void doExecuteFrame(Frame f, String targerFilePath) {if (null == f || null == f.image) {return;}Java2DFrameConverter converter = new Java2DFrameConverter();BufferedImage bi = converter.getBufferedImage(f);File output = new File(targerFilePath);try {ImageIO.write(bi, IMAGEMAT, output);} catch (IOException e) {e.printStackTrace();}}/** * 根據視頻長度隨機產生隨機數集合 * @param baseNum:基礎數字,此處為視頻長度 * @param length:隨機數集合長度 * @return:隨機數集合 */public static List<Integer> random(int baseNum, int length) {List<Integer> list = new ArrayList<Integer>(length);while (list.size() < length) {Integer next = (int) (Math.random() * baseNum);if (list.contains(next)) {continue;}list.add(next);}Collections.sort(list);return list;}}
2、隨機產生多張縮圖,不返回縮圖實際存放地址
package com.lyz.medis.image;import java.awt.image.BufferedImage;import java.io.File;import java.io.IOException;import java.util.ArrayList;import java.util.Collections;import java.util.List;import javax.imageio.ImageIO;import org.bytedeco.javacpp.opencv_core;import org.bytedeco.javacpp.opencv_core.IplImage;import org.bytedeco.javacv.FFmpegFrameGrabber;import org.bytedeco.javacv.Frame;import org.bytedeco.javacv.FrameGrabber.Exception;import org.bytedeco.javacv.Java2DFrameConverter;import org.bytedeco.javacv.OpenCVFrameConverter;/** * 擷取圖片縮圖 * @author liuyazhuang * */public abstract class VideoImageFrame {public static void main(String[] args) throws Exception {randomGrabberFFmpegImage("e:/lyz/ffmpeg.mp4", "./target", "screenshot", 5);}/** * 產生圖片縮圖 * @param filePath:視頻完整路徑 * @param targerFilePath:縮圖存放目錄 * @param targetFileName:縮圖檔案名稱 * @param randomSize:產生隨機數的數量 * @throws Exception */public static void randomGrabberFFmpegImage(String filePath, String targerFilePath, String targetFileName, int randomSize) throws Exception {FFmpegFrameGrabber ff = FFmpegFrameGrabber.createDefault(filePath);ff.start();String rotate = ff.getVideoMetadata("rotate");int ffLength = ff.getLengthInFrames();List<Integer> randomGrab = random(ffLength, randomSize);int maxRandomGrab = randomGrab.get(randomGrab.size() - 1);Frame f;int i = 0;while (i < ffLength) {f = ff.grabImage();if (randomGrab.contains(i)) {if (null != rotate && rotate.length() > 1) {OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();IplImage src = converter.convert(f);f = converter.convert(rotate(src, Integer.valueOf(rotate)));}doExecuteFrame(f, targerFilePath, targetFileName, i);}if (i >= maxRandomGrab) {break;}i++;}ff.stop();}/** * 旋轉圖片 * @param src:圖片 * @param angle:旋轉角度 * @return */public static IplImage rotate(IplImage src, int angle) {IplImage img = IplImage.create(src.height(), src.width(), src.depth(), src.nChannels());opencv_core.cvTranspose(src, img);opencv_core.cvFlip(img, img, angle);return img;}/** * 產生縮圖 * @param f Frame對象 * @param targerFilePath * @param targetFileName * @param index */public static void doExecuteFrame(Frame f, String targerFilePath, String targetFileName, int index) {if (null == f || null == f.image) {return;}Java2DFrameConverter converter = new Java2DFrameConverter();String imageMat = "png";String FileName = targerFilePath + File.separator + targetFileName + "_" + index + "." + imageMat;BufferedImage bi = converter.getBufferedImage(f);File output = new File(FileName);try {ImageIO.write(bi, imageMat, output);} catch (IOException e) {e.printStackTrace();}}/** * 隨機產生隨機數集合 * @param baseNum:隨機種子 * @param length:隨機數集合長度 * @return:隨機數集合 */public static List<Integer> random(int baseNum, int length) {List<Integer> list = new ArrayList<>(length);while (list.size() < length) {Integer next = (int) (Math.random() * baseNum);if (list.contains(next)) {continue;}list.add(next);}Collections.sort(list);return list;}}