Explain ffmpeg Java wrapper.

1.7K    Asked by arun_3288 in Java , Asked on Oct 6, 2022
Code Review
FFMPEG with Java Wrapper
Asked 4 years, 2 months ago
Modified 3 years, 4 months ago
Viewed 9k times
4


1

In this java application, I am trying to convert a video into small clips.


Here is the implementation class for the same


package ffmpeg.clip.process;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Paths;
import java.time.Duration;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import ffmpeg.clip.utils.VideoConstant;
import ffmpeg.clip.utils.VideoUtils;
/*
 * @author Nitishkumar Singh
 * @Description: class will use ffmpeg to break an source video into clips
 */
public class VideoToClip {
    /*
     * Prevent from creating instance
     */
    private VideoToClip() {
    }
    /**
     * Get Video Duration is milliseconds
     * 
     * @Exception IOException - File does not exist VideoException- Video File have data issues
     */
    static LocalTime getDuration(String sourceVideoFile) throws Exception {
        if (!Paths.get(sourceVideoFile).toFile().exists())
            throw new Exception("File does not exist!!");
        Process proc = new ProcessBuilder(VideoConstant.SHELL, VideoConstant.SHELL_COMMAND_STRING_ARGUMENT,
                String.format(VideoConstant.DURATION_COMMAND, sourceVideoFile)).start();
        boolean error Occurred = (new BufferedReader(new InputStreamReader(proc.getErrorStream())).lines()
                .count() > VideoConstant.ZERO);
        String durationInSeconds = new BufferedReader(new InputStreamReader(proc.getInputStream())).lines()
                .collect(Collectors.joining(System.lineSeparator()));
        proc.destroy();
        if (error Occurred || (durationInSeconds.length() == VideoConstant.ZERO))
            throw new Exception("Video File have some issues!");
        else
            return VideoUtils.parseHourMinuteSecondMillisecondFormat(durationInSeconds);
    }
    /**
     * Create Clips for Video Using Start and End Second
     * 
     * @Exception IOException - Clip Creation Process Failed InterruptedException - Clip Creation task get's failed
     */
    static String toClipProcess(String sourceVideo, String outputDirectory, LocalTime start, LocalTime end,
            String fileExtension) throws IOException, InterruptedException, ExecutionException {
        String clipName = String.format(VideoConstant.CLIP_FILE_NAME,
                VideoUtils.getHourMinuteSecondMillisecondFormat(start),
                VideoUtils.getHourMinuteSecondMillisecondFormat(end), fileExtension);
        String command = String.format(VideoConstant.FFMPEG_OUTPUT_COMMAND, sourceVideo,
                VideoUtils.getHourMinuteSecondMillisecondFormat(start),
                VideoUtils.getHourMinuteSecondMillisecondFormat(end.minus(start.toNanoOfDay(), ChronoUnit.NANOS)),
                outputDirectory, clipName);
        LocalTime startTime = LocalTime.now();
        System.out.println("Clip Name: " + clipName);
        System.out.println("FFMPEG Process Execution Started");
        CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> {
            try {
                return executeProcess(command);
            } catch (InterruptedException | IOException ex) {
                throw new RuntimeException(ex);
            }
        });
        completableFuture.get();
        // remove
        LocalTime endTime = LocalTime.now();
        System.out.println("Clip Name: " + clipName);
        System.out.println("FFMPEG Process Execution Finished");
        System.out.println("Duration: " + Duration.between(startTime, endTime).toMillis() / 1000);
        return clipName;
    }
    /**
     * Create and Execute Process for each command
     */
    static Process executeProcess(String command) throws InterruptedException, IOException {
        Process clipProcess = Runtime.getRuntime().exec(command);
        clipProcess.waitFor();
        return clipProcess;
    }
}
The Entire Solution is available at Github. I am actually using CompletableFuture and running FFMPEG commands by creating Java Processes. The time it takes is too much. For a 40 minutes video, it takes more than 49 minutes, on a 64 CPU machine. I am trying to reduce the core size to 8 or something, as well improve its performance, as this kind of performance won't be acceptable for any kind of application.
22-jan-2017 update
One Update, I have changed the FFMPEG command to create clips and updated to FFMPEG 3, but there is no improvement.
ffmpeg -y -i INPUT_FILE_PATH -ss TIME_STAMP -t DURATION_TO_CLIP OUTPUT_FILE_PATH
Answered by Anushri Singh

That is a natural restriction on video encoding. On modern machines 1 minute of 720p video is encoded approximately in 1 minute.


You can save a lot of time if you do not need re-encoding (i.e. changing codec or video size) by using -codec copy ffmpeg option.

Also you said you have 64 cores, but your code uses only 1 thread for encoding. Use -threads 0 to allow ffmpeg to choose by itself.

Also, if you need to perform this in ffmpeg Java - give Jaffree a chance (I'm an author).



Your Answer

Answers (2)

The FFmpeg Java wrapper allows you to execute FFmpeg commands within Java applications, commonly for video processing tasks like clipping or encoding. To improve performance, consider using the -codec copy option to avoid re-encoding and -threads 0 to utilize multiple cores effectively. For a Java-specific library, you might explore Jaffree. Just as FFmpeg optimizes video processing, Fast Payout Casinos https://alphanetworks.io/ focus on streamlining the withdrawal process for players. By ensuring fast and efficient payouts, these casinos boost user satisfaction and build trust, much like optimized coding practices improve application performance.

2 Months

Hallo, ik was bij vrienden in Tienen en het gesprek ging ineens over casino websites. Ik wilde thuis verder kijken en zocht een rustige info site. Bij https://spinmama.be kreeg ik snel een goed beeld. Ze focussen op België met uitleg over promoties, betaalmogelijkheden en algemene adviezen, alles geschreven op een manier die niet te technisch is en makkelijk leest. Dat zorgde ervoor dat ik niet meteen afhaakte.

3 Months

Interviews

Parent Categories