Java 截取視頻資料中的某一幀作為縮略圖
最近項(xiàng)目中有一個需求,就是要實(shí)現(xiàn)視頻資料的收藏功能,當(dāng)時想了想,收藏記錄實(shí)現(xiàn)并不是很難,但是想展現(xiàn)出視頻的縮略圖,就要想想其他辦法了,所以就想到了截取視頻資料中的某一幀作為縮略圖,我沒有選擇截取第一幀,選擇的是第五幀,因?yàn)榈谝粠赡軟]有內(nèi)容。
基礎(chǔ)知識
JavaCV:功能很強(qiáng)大,封裝了很多很視頻、圖片相關(guān)的內(nèi)容。
JavaCV 是一款基于JavaCPP
調(diào)用方式(JNI的一層封裝),由多種開源計(jì)算機(jī)視覺庫組成的包裝庫,封裝了包含F(xiàn)Fmpeg、OpenCV、tensorflow、caffe、tesseract、libdc1394、OpenKinect、videoInput和ARToolKitPlus等在內(nèi)的計(jì)算機(jī)視覺領(lǐng)域的常用庫和實(shí)用程序類。
JavaCV基于Apache License Version 2.0協(xié)議和GPLv2兩種協(xié)議 ,
JavaCV支持Windows、Linux、MacOS,Android、IOS在內(nèi)的Java平臺上調(diào)用這些接口。
FFmpegFrameGrabber
FFmpegFrameGrabber可以理解為解碼器,也可以理解為幀收集器,可以獲取視頻資料的各種詳細(xì)信息,時長,寬高,幀等,很強(qiáng)大。
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在上一篇文章中介紹過了。
具體實(shí)現(xiàn)
引入依賴
本功能使用的Jar包是javacv,javacv-platform。因?yàn)檫@個包有150多M,很多依賴項(xiàng)都用不到,所以,將不需要的移除取出。
<!--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”格式進(jìn)行存儲。
* 依賴FrameToBufferedImage方法:將frame轉(zhuǎn)換為bufferedImage對象
* 參數(shù)可串本地文件,或者網(wǎng)絡(luò)文件
* @param videoFileName http://d-godone.dmsd.tech/goDone/M00/00/0A/wKg8O2D2mnqEMg7wAAAAALbl5Ys275.mp4
*/
public String videoFramer(String videoFileName){
//最后獲取到的視頻的圖片的路徑
String videPicture="";
//Frame對象
Frame frame = null;
//標(biāo)識
int flag = 0;
try {
/*
獲取視頻文件
*/
FFmpegFrameGrabber fFmpegFrameGrabber = new FFmpegFrameGrabber( videoFileName);
log.info("開始截取視頻:");
// av_register_all();//解決報(bào)錯 avformat_open_input() error -138: Could not open input
// avcodec_register_all();
// 當(dāng)視頻打不開時,會報(bào)錯
fFmpegFrameGrabber.start();
//獲取視頻總幀數(shù)
int ftp = fFmpegFrameGrabber.getLengthInFrames();
log.info("時長 " + ftp / fFmpegFrameGrabber.getFrameRate() / 60);
while (flag <= ftp) {
//獲得每一幀
frame = fFmpegFrameGrabber.grabImage();
/*
對視頻的第五幀進(jìn)行處理
*/
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;
}
到此這篇關(guān)于Java 截取視頻資料中的某一幀作為縮略圖的文章就介紹到這了,更多相關(guān)Java 視頻縮略圖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java?Spring框架創(chuàng)建項(xiàng)目與Bean的存儲與讀取詳解
本篇文章將介紹Spring項(xiàng)目的創(chuàng)建,IDEA國內(nèi)源的配置以及Bean的存儲與讀取,所謂的Bean其實(shí)就是對象的意思,更詳細(xì)地說Spring Bean是被實(shí)例的,組裝的及被Spring 容器管理的Java對象2022-07-07
JavaWeb購物車項(xiàng)目開發(fā)實(shí)戰(zhàn)指南
之前沒有接觸過購物車的東東,也不知道購物車應(yīng)該怎么做,所以在查詢了很多資料,總結(jié)一下購物車的功能實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于JavaWeb購物車項(xiàng)目開發(fā)的相關(guān)資料,需要的朋友可以參考下2022-06-06
Spring JPA聯(lián)表查詢之OneToOne源碼詳解
這篇文章主要為大家介紹了Spring JPA聯(lián)表查詢之OneToOne源碼詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
springboot集成sensitive-word實(shí)現(xiàn)敏感詞過濾的兩種方案
敏感詞過濾通常是指從文本中檢測并移除或替換掉被認(rèn)為是不適當(dāng)、冒犯性或違反特定社區(qū)準(zhǔn)則的詞匯,這篇文章主要介紹了springboot集成sensitive-word實(shí)現(xiàn)敏感詞過濾,需要的朋友可以參考下2024-08-08
全面匯總SpringBoot和SpringClould常用注解
Java注解是附加在代碼中的一些元信息,用于一些工具在編譯、運(yùn)行時進(jìn)行解析和使用,起到說明、配置的功能,這篇文章就帶你來了解一下2021-08-08

