最近項目中有一個需求,就是要實現(xiàn)視頻資料的收藏功能,當(dāng)時想了想,收藏記錄實現(xiàn)并不是很難,但是想展現(xiàn)出視頻的縮略圖,就要想想其他辦法了,所以就想到了截取視頻資料中的某一幀作為縮略圖,我沒有選擇截取第一幀,選擇的是第五幀,因為第一幀可能沒有內(nèi)容。
基礎(chǔ)知識
JavaCV:功能很強大,封裝了很多很視頻、圖片相關(guān)的內(nèi)容。
JavaCV 是一款基于JavaCPP
調(diào)用方式(JNI的一層封裝),由多種開源計算機視覺庫組成的包裝庫,封裝了包含F(xiàn)Fmpeg、OpenCV、tensorflow、caffe、tesseract、libdc1394、OpenKinect、videoInput和ARToolKitPlus等在內(nèi)的計算機視覺領(lǐng)域的常用庫和實用程序類。
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)存中
1
2
3
|
//需要是一個本地文件 String imgPath = "?C:\Users\Administrator\Videos\999.jpg" ; BufferedImage image = ImageIO.read( new FileInputStream(imgPath)); |
將內(nèi)存中的圖片寫到本地
1
2
3
4
5
6
7
|
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,很多依賴項都用不到,所以,將不需要的移除取出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
<!--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代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
/** * 將視頻文件幀處理并以“jpg”格式進行存儲。 * 依賴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();//解決報錯 avformat_open_input() error -138: Could not open input // avcodec_register_all(); // 當(dāng)視頻打不開時,會報錯 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
/** * 文件轉(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)容請搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!
原文鏈接:https://blog.csdn.net/promsing/article/details/120291489