Overview
So in my recent project, I need to manage video uploads and I think having a default placeholder for videos is quite boring. The right way would be having thumbnails for the videos.
It’s quite simple to create a thumbnail from a video with java.
There are a few choices when it comes to libraries. You can use javacv (huge) or use ffmpeg with net.bramp.ffmpeg.
I’ll go with the second option since it does the job without occupying 500MB to my final jar.
How to create thumbnail for video (jpg/base64)
<dependency> <groupId>net.bramp.ffmpeg</groupId> <artifactId>ffmpeg</artifactId> <version>0.8.0</version> </dependency>
public static String convertToBase64(String videoPath, FFmpeg ffmpeg) throws IOException {
var tempFile = File.createTempFile("temp_image",".jpg");
var tempImagePath = tempFile.getAbsolutePath();
try {
// Build FFmpeg command to extract a frame
FFmpegBuilder builder = new FFmpegBuilder()
.setInput(videoPath)
.overrideOutputFiles(true)
.addOutput(tempImagePath)
.setFrames(1) // Extract only 1 frame
.done();
// Execute the FFmpeg command
FFmpegExecutor executor = new FFmpegExecutor(ffmpeg);
executor.createJob(builder).run();
return convertToBase64(tempImagePath, 80);
} catch (IOException e) {
log.error("error rendering image ", e);
} finally {
tempFile.delete();
}
return Constants.StaticImages.DEFAULT_VIDEO_PLACEHOLDER;
}
public static String convertToBase64(String imagePath, double scalePercent) throws IOException {
// Read the original image from the file
BufferedImage originalImage = ImageIO.read(new File(imagePath));
// Calculate the new dimensions based on the scaling percentage
int targetWidth = (int) (originalImage.getWidth() * scalePercent / 100);
int targetHeight = (int) (originalImage.getHeight() * scalePercent / 100);
// Resize the image
BufferedImage resizedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = resizedImage.createGraphics();
graphics.drawImage(originalImage, 0, 0, targetWidth, targetHeight, null);
graphics.dispose();
// Convert the resized image to a ByteArrayOutputStream in JPEG format
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(resizedImage, "jpeg", outputStream);
// Encode to Base64
String base64Image = Base64.getEncoder().encodeToString(outputStream.toByteArray());
// Close the stream
outputStream.close();
return "data:image/jpeg;base64," + base64Image;
}With this two methods, you can create a base64 text that represents the video quite efficiently.
Here is what I have on my project:

Conclusion
With the code above, you can create thumbnail for your videos. I’ve only tested the code with mp4 h264 codec.

I build softwares that solve problems. I also love writing/documenting things I learn/want to learn.