58

I'm pretty new to Java, and need to write a program that listens to video conversion instructions and convert the video once a new instruction arrives (instructions are stored in Amazon SQS, but it's irrelevant to my question).

I'm facing a choice, either use Java runtime to exec FFmpeg conversion (like from command line), or I can use an FFmpeg wrapper written in Java.

http://fmj-sf.net/ffmpeg-java/getting_started.php

I'd much prefer using Java runtime to exec FFmpeg directly, and avoid using java-ffmpeg wrapper as I have to learn the library.

So my question is this: Are there any benefits using java-ffmpeg wrapper over exec FFmpeg directly using Runtime?

I don't need FFmpeg to play videos, just convert videos.

9 Answers 9

40

If I'm not mistaken, the "ffmpeg-wrapper" project you linked to is out of date and not maintained. FFmpeg is a very active project, lot's of changes and releases all the time.

You should look at the Xuggler project, this provides a Java API for what you want to do, and they have tight integration with FFmpeg.

http://www.xuggle.com/xuggler/

Should you choose to go down the Runtime.exec() path, this Red5 thread should be useful:

http://www.nabble.com/java-call-ffmpeg-ts15886850.html

Sign up to request clarification or add additional context in comments.

6 Comments

just took a brief look at xuggler documentation, exactly what I need. thanks for helping!
Great. Just be aware that it is GPL, you may need a commercial license in production.
Actually Xuggler is now LGPL (although it will be GPL if you use it with libx264)
Looks like this is outdated now
|
27

I too am looking for something to wrap FFMPEG in Java. While searching, I found this: https://github.com/bramp/ffmpeg-cli-wrapper.

As of today, it seems to have been modified a month ago. So, hopefully it will stick around for a while.

A sample from their docs:

FFmpeg ffmpeg = new FFmpeg("/path/to/ffmpeg");
FFprobe ffprobe = new FFprobe("/path/to/ffprobe");

FFmpegBuilder builder = new FFmpegBuilder()
    .setInput(in)
    .overrideOutputFiles(true)
    .addOutput("output.mp4")
        .setFormat("mp4")
        .setTargetSize(250000)

        .disableSubtitle()

        .setAudioChannels(1)
        .setAudioCodec("libfdk_aac")
        .setAudioRate(48000)
        .setAudioBitrate(32768)

        .setVideoCodec("libx264")
        .setVideoFramerate(Fraction.getFraction(24, 1))
        .setVideoResolution(640, 480)

        .setStrict(FFmpegBuilder.Strict.EXPERIMENTAL)
        .done();

FFmpegExecutor executor = new FFmpegExecutor(ffmpeg, ffprobe);
executor.createTwoPassJob(builder).run();

4 Comments

does it has solution to extract the audio or video meta info?
yes using ffprobe go on website on github you will see an example
The library doesn't support termination of the child process (should you wish to capture a video from your screen), nor does it expose the process to the client. Given that ffmpeg is very well documented, you're better off running ffmpeg manually via the java.lang.Process API.
@Bass It does support creating your own Process though via the ProcessFunction interface, see this constructor. This way you can keep track of the process or even destroy it whenever you see fit.
25

There are a lot of Java libraries providing FFMPEG wrappers. However, most of these libraries are unfortunately outdated and use old FFMPEG versions which lack some important codecs (e.g. Xuggler, humble video, JavaAV, JavaAVC, and jave). So be careful when using those projects!

However, there is one FFMPEG wrapper that is still actively developed and supports FFMPEG 4:

Alternatively you can use a wrapper for the command line interface of FFMPEG, such as ffmpeg-cli-wrapper. Then it's in your hand to update ffmpeg manually without having to wait for a new release of the wrapper library.

Comments

15

I wrote my own Java ffmpeg command line wrapper: Jaffree. It works with both ffprobe and ffmpeg and supports programmatic video production and consumption. Also it has in my opinion more convenient fluid API.

Here is an ffprobe usage example:

FFprobeResult result = FFprobe.atPath(BIN)
        .setInputPath(VIDEO_MP4)
        .setShowStreams(true)
        .setShowError(true)
        .execute();

if (result.getError() != null) {
    //TODO handle ffprobe error message
    return;
}

for (Stream stream : probe.getStreams().getStream()) {
    //TODO analyze stream data
}

ProgressListener listener = new ProgressListener() {
    @Override
    public void onProgress(FFmpegProgress progress) {
        //TODO handle progress data
    }
};

And this is for ffmpeg:

FFmpegResult result = FFmpeg.atPath(BIN)
        .addInput(Input.fromPath(VIDEO_MP4))
        .addOutput(Output.toPath(outputPath)
                .addCodec(null, "copy")
        )
        .setProgressListener(listener)
        .execute();

3 Comments

Hi, how can one manage java interface library when ffprobe xsd changes over every ffmpeg version? P.S. My approach was similar to yours, but this issue makes me stick to one specific ffmpeg version.
I tested only on latest ffmpeg version, there is an option "bit exact output".
Do you have examples on how this can be used with input being WebSocket or multiple MP4s?
8

Also, as of Xuggler 3.3, Xuggler is LGPL meaning you don't need a commercial license.

1 Comment

Does it support converting images and mp3 to a video file? thanks
4

you can try jave http://www.sauronsoftware.it/projects/jave

1 Comment

JAVE is only good because it bundles ffmpeg binaries for all mainstream platforms. Their Java API is a mess, however.
3

The benefits of using the wrapper would be mainly that it offers more and fine-grained functionality not accessible via the command line (not relevant to you) and makes error handling and status control easier - you'll have to parse the command line tool's standard output and error streams.

Comments

0

i try several ways, the most simple for me is ffmpeg-cli-wrapper, because it use default ffmpeg or specific one, moreover you can configure lot of configuration like scale, bitrate... get duration... JAVE from sauronsoftware make lot of error, XUGGLE and other i found it too complicated

Comments

0

For a real-world app example, see this project on GitHub.

Here is how to use FFmpeg and FFprobe from the org.bytedeco.ffmpeg library.

Add the dependency for your desired operating system (see here for supported OSes):

// The main artifact
implementation("org.bytedeco:ffmpeg:6.1.1-1.5.10")
// The Jar artifact containing executables for the desired OS
implementation("org.bytedeco:ffmpeg:6.1.1-1.5.10:windows-x86_64-gpl")

// OR using Gradle version catalogs
// implementation(libs.ffmpeg)
// implementation(variantOf(libs.ffmpeg) { classifier("windows-x86_64-gpl") })

Java:

import org.bytedeco.ffmpeg.ffmpeg;
import org.bytedeco.javacpp.Loader;
// ...

public class Test {
    private final String ffmpegPath = Loader.load(ffmpeg.class);
    public void executeFFmpeg() throws IOException {
        var ffmpegProcess = new ProcessBuilder()
                .command(
                        ffmpegPath,
                        // OR any options you would pass to FFmpeg CLI
                        "-i", "/absolute/path/to/video.mp4"
                )
                .start();
        try (var reader = new BufferedReader(new InputStreamReader(ffmpegProcess.getErrorStream()))) {
            reader
                    .lines()
                    .forEach(System.out::println);
        }
    }
}

Kotlin:

import org.bytedeco.ffmpeg.ffmpeg
import org.bytedeco.javacpp.Loader
// ...

class Test() {
    private val ffmpegPath = Loader.load(ffmpeg::class.java)
    fun executeFFmpeg() {
        ProcessBuilder()
            .command(ffmpegPath, "-i", "absolute/path/to/video.mp4")
            .runCatching { start() }
            .onFailure { println("Starting the FFmpeg process for probing failed") }
            .getOrNull()
            ?.errorStream
            ?.reader()
            ?.useLines { lines -> lines.forEach(::println) }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.