javacv 提取視頻封面


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM