Java intercepts a frame in video data as a thumbnail
- 2021-11-14 05:44:52
- OfStack
FFmpegFrameGrabber
BufferedImage, ImageIO
MultipartFile
Concrete realization
Introducing dependency
There is one requirement in the recent project, It is to realize the collection function of video data. At that time, after thinking about it, it is not very difficult to collect records, but if you want to show thumbnails of video, you have to think of other ways, so I thought of intercepting a certain frame in video data as a thumbnail. I didn't choose to intercept the first frame, but chose the fifth frame, because the first frame may have no content.
Basic knowledge
JavaCV: It is very powerful and encapsulates a lot of video and picture related content.
JavaCV is a model based on JavaCPP
Calling mode (1 layer encapsulation of JNI), which is composed of a variety of open source computer vision libraries, encapsulates common libraries and utility classes in the field of computer vision including FFmpeg, OpenCV, tensorflow, caffe, tesseract, libdc1394, OpenKinect, videoInput and ARToolKitPlus.
JavaCV is based on Apache License Version 2.0 protocol and GPLv2 protocol,
JavaCV supports Java platforms including Windows, Linux, MacOS, Android and IOS to call these interfaces.
FFmpegFrameGrabber
FFmpegFrameGrabber can be understood as a decoder or a frame collector, which can obtain various detailed information of video data, such as duration, width and height, frame, etc. It is very powerful.
BufferedImage, ImageIO
BufferedImage class is a subclass of Image, is a buffer image class, the main role is to load a picture into memory.
ImageIO provides read () and write () static methods for reading and writing photos
Load pictures into memory
// Need to be 1 Local files
String imgPath = "C:\Users\Administrator\Videos\999.jpg";
BufferedImage image = ImageIO.read(new FileInputStream(imgPath));
Write pictures in memory to local
BufferedImage bi=~ A value
File outputfile = new File("save.png");
// Parameter
// bi: To write RenderedImage
// png: Format type
// outputfile: To write OutputStream
ImageIO.write(bi,"png",outputfile);
MultipartFile
MultipartFile was described in the last article.
Java files upload instances and resolve cross-domain issues
Concrete realization
Introducing dependency
The Jar packages used for this feature are javacv, javacv-platform. Because this package has more than 150 M, many dependencies are not needed, so unwanted removal is taken out.
<!--start: Video acquisition of a 1 Picture of frame -->
<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: Video acquisition of a 1 Picture of frame -->
Java code
/**
* Process the video file frames and use the " jpg "Format for storage.
* Dependency FrameToBufferedImage Method: Set the frame Convert to bufferedImage Object
* Parameters can be strung to local files or network files
* @param videoFileName http://d-godone.dmsd.tech/goDone/M00/00/0A/wKg8O2D2mnqEMg7wAAAAALbl5Ys275.mp4
*/
public String videoFramer(String videoFileName){
// The path of the picture of the last acquired video
String videPicture="";
//Frame Object
Frame frame = null;
// Identification
int flag = 0;
try {
/*
Get a video file
*/
FFmpegFrameGrabber fFmpegFrameGrabber = new FFmpegFrameGrabber( videoFileName);
log.info(" Start intercepting video :");
// av_register_all();// Resolve error reporting avformat_open_input() error -138: Could not open input
// avcodec_register_all();
// When the video can't be opened, an error will be reported
fFmpegFrameGrabber.start();
// Get the total number of video frames
int ftp = fFmpegFrameGrabber.getLengthInFrames();
log.info(" Duration " + ftp / fFmpegFrameGrabber.getFrameRate() / 60);
while (flag <= ftp) {
// Get every 1 Frame
frame = fFmpegFrameGrabber.grabImage();
/*
The first part of the video 5 Frame processing
*/
if (frame != null && flag==5) {
// Convert a file
BufferedImage bufferedImage = FrameToBufferedImage(frame);
// Will bufferedImage Convert to MultipartFile-- Facilitate file uploading
MultipartFile multipartFile = fileCase(bufferedImage);
log.info(" Start file upload :");
// File upload -- Upload to FastDFS And returns the URL
String fileLoad = fileLoad(multipartFile);
videPicture=fileLoad;
log.info(" File uploaded successfully {}",fileLoad);
break;
}
flag++;
}
fFmpegFrameGrabber.stop();
fFmpegFrameGrabber.close();
} catch (Exception E) {
E.printStackTrace();
}
return videPicture;
}
Two methods of file type conversion Frame-
>
BufferedImage-
>
MultipartFile
/**
* File conversion, the Frame Convert to BufferedImage
* @param frame Frame
* @return
*/
public static BufferedImage FrameToBufferedImage(Frame frame) {
// Create BufferedImage Object
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage bufferedImage = converter.getBufferedImage(frame);
return bufferedImage;
}
/**
* File conversion will BufferedImage Convert to MultipartFile For file upload
* @param image
* @return
*/
public static MultipartFile fileCase(BufferedImage image){
// Get BufferedImage Object
// BufferedImage bufferedImage = JoinTwoImage.testEncode(200, 200, url);
MultipartFile multipartFile= null;
try {
// Create 1 A ByteArrayOutputStream
ByteArrayOutputStream os = new ByteArrayOutputStream();
// Put BufferedImage Write ByteArrayOutputStream
ImageIO.write(image, "jpg", os);
//ByteArrayOutputStream Turn into InputStream
InputStream input = new ByteArrayInputStream(os.toByteArray());
//InputStream Turn into MultipartFile
multipartFile =new MockMultipartFile("file", "file.jpg", "text/plain", input);
} catch (IOException e) {
e.printStackTrace();
}
return multipartFile;
}