Decoding videos
Regarding the problem # 1 , there is no magic solution for reading images from any video format.
Each video format needs a specific algorithm to interpret it and hardly a single implementation will cover all formats.
Even though some libraries (or group libraries) can read several common formats, there are always some proprietary formats or variations that end up causing problems.
Approaches
Two basic solutions for thumbnails would be:
Pre-store thumbnails
Store the thumbnails together with the video files.
If you have some control over how video files are generated or included in the directory, this would be the best solution.
Use any command line tool to generate the thumbnail and make your Java program simple and fast.
Generate thumbnail on demand
This is the approach possible when you have no control over the videos.
Decoding the video from your program may be convenient on the one hand, but keep in mind that it will greatly increase the complexity of the program and potentially affect performance in a very negative way. Consider rendering 500 videos from any folder.
It may be necessary to create a queue to process the videos and work with different threads to not lock the program and allow the cancellation in case the user does not want to wait for the operation to finish.
Xuggler
I did not understand the problem with keeping the libraries used by xuggler . Many programs and tools come with different libraries.
The argument of "having to control this later" does not make sense because any dependencies added to your project will have to be managed.
What exactly is the difficulty in controlling this if you put the libraries together with your program when you distribute?
From what I read in documentation , xuggler is a wrapper for native FFMPEG libraries, used in several projects. The advantage of using these libraries is that they are mature and trusted.
JCodec
Another alternative would be JCodec , a purely Java implementation.
The first page already shows an example of how to extract a frame from the video to an image:
int frameNumber = 150;
BufferedImage frame = FrameGrab.getFrame(new File("arquivo.mp4"), frameNumber);
ImageIO.write(frame, "png", new File("frame_150.png"));
However, as one would expect from a less-used library, it supports few formats: AVC, H.264 in MP4, ISO BMF, and Quicktime. I suppose it also has less adherence to variations of these formats.
Although there are recent updates to this library, updates to new or even existing formats are likely to be few or more time-consuming, as there does not seem to be much involvement in the project.
Problem with listFiles()
The problem with listFiles
can be caused if the Java process does not have permissions to read from the folder.
It may also be that the directory you have passed is invalid. For example, I did a test passing ~
(user directory) and did not work. However, passing the absolute path did work.
I would also use the newer Java API. Example:
//extensões aceitas
PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:*.{txt,log}");
//diretório de busca
Path diretorio = Paths.get("/my/dir");
//permite links simbólicos
EnumSet<FileVisitOption> options = EnumSet.of(FileVisitOption.FOLLOW_LINKS);
//navega no diretório
Files.walkFileTree(diretorio, options, 1,
new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
//verifica se não é um diretório e se tem uma das extensões esperadas
if (!attrs.isDirectory() && matcher.matches(file.getFileName())) {
System.out.println(file.toString());
}
return super.visitFile(file, attrs);
}
});
See the relevant documentation on walkFileTree
and < a href="https://docs.oracle.com/javase/tutorial/essential/io/find.html"> PathMatcher
.
Considerations
Define the best approach for your case and remember that any of them will have their strengths and weaknesses.