Java 截取視頻資料中的某一幀作為縮略圖
最近項目中有一個需求,就是要實現(xiàn)視頻資料的收藏功能,當時想了想,收藏記錄實現(xiàn)并不是很難,但是想展現(xiàn)出視頻的縮略圖,就要想想其他辦法了,所以就想到了截取視頻資料中的某一幀作為縮略圖,我沒有選擇截取第一幀,選擇的是第五幀,因為第一幀可能沒有內(nèi)容。
基礎知識
JavaCV:功能很強大,封裝了很多很視頻、圖片相關的內(nèi)容。
JavaCV 是一款基于JavaCPP
調(diào)用方式(JNI的一層封裝),由多種開源計算機視覺庫組成的包裝庫,封裝了包含F(xiàn)Fmpeg、OpenCV、tensorflow、caffe、tesseract、libdc1394、OpenKinect、videoInput和ARToolKitPlus等在內(nèi)的計算機視覺領域的常用庫和實用程序類。
JavaCV基于Apache License Version 2.0協(xié)議和GPLv2兩種協(xié)議 ,
JavaCV支持Windows、Linux、MacOS,Android、IOS在內(nèi)的Java平臺上調(diào)用這些接口。
FFmpegFrameGrabber
FFmpegFrameGrabber可以理解為解碼器,也可以理解為幀收集器,可以獲取視頻資料的各種詳細信息,時長,寬高,幀等,很強大。
BufferedImage,ImageIO
BufferedImage類是Image的一個子類,是一個帶緩沖區(qū)圖像類,主要作用是將一幅圖片加載到內(nèi)存中。
ImageIO提供read()和write()靜態(tài)方法,讀寫照片
將圖片加載到內(nèi)存中
//需要是一個本地文件 String imgPath = "C:\Users\Administrator\Videos\999.jpg"; BufferedImage image = ImageIO.read(new FileInputStream(imgPath));
將內(nèi)存中的圖片寫到本地
BufferedImage bi=~某個值
File outputfile = new File("save.png");
//參數(shù)
// bi:要寫入的RenderedImage
// png:格式類型
// outputfile:要寫入的OutputStream
ImageIO.write(bi,"png",outputfile);
MultipartFile
MultipartFile在上一篇文章中介紹過了。
具體實現(xiàn)
引入依賴
本功能使用的Jar包是javacv,javacv-platform。因為這個包有150多M,很多依賴項都用不到,所以,將不需要的移除取出。
<!--start:視頻獲取某一幀的圖片-->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.4.4</version>
<exclusions>
<exclusion>
<groupId>org.bytedeco</groupId>
<artifactId>javacpp</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>flycapture</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>libdc1394</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>libfreenect</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>libfreenect2</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>librealsense</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>videoinput</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>opencv</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>tesseract</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>leptonica</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>flandmark</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>artoolkitplus</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.4.4</version>
<exclusions>
<exclusion>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>flycapture-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>libdc1394-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>libfreenect-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>libfreenect2-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>librealsense-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>videoinput-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>opencv-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>tesseract-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>leptonica-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>flandmark-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>artoolkitplus-platform</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--end:視頻獲取某一幀的圖片-->
Java代碼
/**
* 將視頻文件幀處理并以“jpg”格式進行存儲。
* 依賴FrameToBufferedImage方法:將frame轉(zhuǎn)換為bufferedImage對象
* 參數(shù)可串本地文件,或者網(wǎng)絡文件
* @param videoFileName http://d-godone.dmsd.tech/goDone/M00/00/0A/wKg8O2D2mnqEMg7wAAAAALbl5Ys275.mp4
*/
public String videoFramer(String videoFileName){
//最后獲取到的視頻的圖片的路徑
String videPicture="";
//Frame對象
Frame frame = null;
//標識
int flag = 0;
try {
/*
獲取視頻文件
*/
FFmpegFrameGrabber fFmpegFrameGrabber = new FFmpegFrameGrabber( videoFileName);
log.info("開始截取視頻:");
// av_register_all();//解決報錯 avformat_open_input() error -138: Could not open input
// avcodec_register_all();
// 當視頻打不開時,會報錯
fFmpegFrameGrabber.start();
//獲取視頻總幀數(shù)
int ftp = fFmpegFrameGrabber.getLengthInFrames();
log.info("時長 " + ftp / fFmpegFrameGrabber.getFrameRate() / 60);
while (flag <= ftp) {
//獲得每一幀
frame = fFmpegFrameGrabber.grabImage();
/*
對視頻的第五幀進行處理
*/
if (frame != null && flag==5) {
//將文件轉(zhuǎn)換
BufferedImage bufferedImage = FrameToBufferedImage(frame);
//將bufferedImage轉(zhuǎn)換成MultipartFile--方便文件上傳
MultipartFile multipartFile = fileCase(bufferedImage);
log.info("開始文件上傳:");
//文件上傳--上傳到FastDFS中,并返回URL
String fileLoad = fileLoad(multipartFile);
videPicture=fileLoad;
log.info("文件上傳成功{}",fileLoad);
break;
}
flag++;
}
fFmpegFrameGrabber.stop();
fFmpegFrameGrabber.close();
} catch (Exception E) {
E.printStackTrace();
}
return videPicture;
}
兩個文件類型轉(zhuǎn)換的方法Frame->BufferedImage->MultipartFile
/**
* 文件轉(zhuǎn)換,將Frame轉(zhuǎn)換成BufferedImage
* @param frame Frame
* @return
*/
public static BufferedImage FrameToBufferedImage(Frame frame) {
//創(chuàng)建BufferedImage對象
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage bufferedImage = converter.getBufferedImage(frame);
return bufferedImage;
}
/**
* 文件轉(zhuǎn)換將BufferedImage轉(zhuǎn)換成MultipartFile:為了文件上傳
* @param image
* @return
*/
public static MultipartFile fileCase(BufferedImage image){
//得到BufferedImage對象
// BufferedImage bufferedImage = JoinTwoImage.testEncode(200, 200, url);
MultipartFile multipartFile= null;
try {
//創(chuàng)建一個ByteArrayOutputStream
ByteArrayOutputStream os = new ByteArrayOutputStream();
//把BufferedImage寫入ByteArrayOutputStream
ImageIO.write(image, "jpg", os);
//ByteArrayOutputStream轉(zhuǎn)成InputStream
InputStream input = new ByteArrayInputStream(os.toByteArray());
//InputStream轉(zhuǎn)成MultipartFile
multipartFile =new MockMultipartFile("file", "file.jpg", "text/plain", input);
} catch (IOException e) {
e.printStackTrace();
}
return multipartFile;
}
到此這篇關于Java 截取視頻資料中的某一幀作為縮略圖的文章就介紹到這了,更多相關Java 視頻縮略圖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java?Spring框架創(chuàng)建項目與Bean的存儲與讀取詳解
本篇文章將介紹Spring項目的創(chuàng)建,IDEA國內(nèi)源的配置以及Bean的存儲與讀取,所謂的Bean其實就是對象的意思,更詳細地說Spring Bean是被實例的,組裝的及被Spring 容器管理的Java對象2022-07-07
Spring JPA聯(lián)表查詢之OneToOne源碼詳解
這篇文章主要為大家介紹了Spring JPA聯(lián)表查詢之OneToOne源碼詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-04-04
springboot集成sensitive-word實現(xiàn)敏感詞過濾的兩種方案
敏感詞過濾通常是指從文本中檢測并移除或替換掉被認為是不適當、冒犯性或違反特定社區(qū)準則的詞匯,這篇文章主要介紹了springboot集成sensitive-word實現(xiàn)敏感詞過濾,需要的朋友可以參考下2024-08-08
全面匯總SpringBoot和SpringClould常用注解
Java注解是附加在代碼中的一些元信息,用于一些工具在編譯、運行時進行解析和使用,起到說明、配置的功能,這篇文章就帶你來了解一下2021-08-08

