杰瑞科技汇

Java如何调用FFmpeg?

Of course! Using FFmpeg in a Java application is a common requirement for tasks like video transcoding, audio extraction, image manipulation, and more. There are several ways to achieve this, each with its own pros and cons.

Java如何调用FFmpeg?-图1
(图片来源网络,侵删)

Here’s a comprehensive guide covering the most popular methods.


Summary of Methods

Method Pros Cons Best For
ProcessBuilder (Runtime.exec) - No external libraries needed.
- Full control over FFmpeg's CLI.
- Verbose and error-prone.
- Requires manual parsing of output.
- Platform-specific path management.
Simple, one-off scripts or when you need to run a very specific, complex command.
JavaCV (Wrapper Library) - Highly Recommended.
- Clean, object-oriented Java API.
- Handles platform-specific linking automatically.
- Can access other OpenCV features.
- Adds a dependency (large JAR).
- Abstraction can hide some FFmpeg details.
Most production applications. It's the standard, robust way to integrate FFmpeg.
JAVE (Java Audio Video Encoder) - Very simple API for common tasks.
- Lightweight.
- No longer actively maintained.
- Limited functionality compared to JavaCV.
Quick prototyping or very simple encoding tasks where you don't need the latest FFmpeg features.

Method 1: Using ProcessBuilder (The Direct CLI Approach)

This method involves executing the ffmpeg command-line executable directly from your Java code. You are essentially just running a shell command.

How it Works

You use Java's ProcessBuilder to start a new process, passing the ffmpeg command and its arguments as a list of strings.

Prerequisites

  1. FFmpeg Executable: You must have the ffmpeg executable installed on your system.
    • Windows: Download from the official site and add the bin directory to your system's PATH environment variable.
    • macOS: brew install ffmpeg
    • Linux (Debian/Ubuntu): sudo apt-get install ffmpeg

Example Code

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class FfmpegCliRunner {
    public static void main(String[] args) {
        // Define the FFmpeg command
        // Command: ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a aac -b:a 128k output.mp4
        String[] command = {
            "ffmpeg",
            "-i", "input.mp4",             // Input file
            "-c:v", "libx264",            // Video codec
            "-crf", "23",                 // Constant Rate Factor (quality)
            "-c:a", "aac",                // Audio codec
            "-b:a", "128k",               // Audio bitrate
            "output.mp4"                  // Output file
        };
        try {
            // Start the process
            ProcessBuilder pb = new ProcessBuilder(command);
            pb.redirectErrorStream(true); // Merge stderr into stdout
            Process process = pb.start();
            // Read the output stream (to prevent the process from blocking)
            InputStream inputStream = process.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            // Wait for the process to finish
            int exitCode = process.waitFor();
            if (exitCode == 0) {
                System.out.println("Conversion completed successfully!");
            } else {
                System.err.println("Conversion failed with exit code: " + exitCode);
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Pros & Cons Revisited:

Java如何调用FFmpeg?-图2
(图片来源网络,侵删)
  • Pro: You can use any FFmpeg flag or complex filter chain without learning a new API.
  • Con: You have to handle everything yourself: finding the ffmpeg executable, managing input/output streams, and parsing the text output to check for errors.

Method 2: Using JavaCV (The Recommended Approach)

JavaCV is a set of wrappers for popular computer vision libraries, including FFmpeg, OpenCV, GStreamer, and others. It provides a clean, native Java API that calls the underlying C/C++ libraries efficiently.

How it Works

JavaCV uses JNI (Java Native Interface) to call FFmpeg's functions. It comes pre-packaged with the necessary native libraries for different platforms (Windows, macOS, Linux), so you don't have to compile or install anything yourself.

Prerequisites

  1. Maven/Gradle: You need a build tool to manage dependencies.

Maven Dependency

Add this to your pom.xml:

<dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv-platform</artifactId>
    <version>1.5.9</version> <!-- Check for the latest version -->
</dependency>

Note: javacv-platform is the easiest choice as it automatically downloads the correct native libraries for your OS. If you want to control this, you can use javacv and specify the platform-specific artifacts (e.g., javacv-windows-x86_64).

Example Code: Converting a Video

This example does the same thing as the CLI one, but with a much cleaner API.

import org.bytedeco.ffmpeg.global.ffmpeg;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
public class JavaCVConverter {
    public static void main(String[] args) {
        String inputFile = "input.mp4";
        String outputFile = "output_javacv.mp4";
        try (FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputFile);
             FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputFile, 640, 480)) {
            // Configure the grabber
            grabber.setOption("rtsp_transport", "tcp"); // Example for RTSP
            grabber.start();
            // Configure the recorder
            recorder.setVideoCodec(ffmpeg.AV_CODEC_ID_H264);
            recorder.setFormat("mp4");
            recorder.setFrameRate(30);
            recorder.setVideoBitrate(2000000); // 2 Mbps
            recorder.start();
            Frame frame;
            // Read frames from the input and write to the output
            while ((frame = grabber.grab()) != null) {
                recorder.record(frame);
            }
            System.out.println("Conversion completed successfully!");
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("An error occurred during conversion.");
        }
    }
}

Pros & Cons Revisited:

  • Pro: Robust, feature-rich, and platform-independent. The API is much safer and easier to use than ProcessBuilder.
  • Con: The JAR file is large (tens of MB) because it bundles native libraries. The abstraction might be slightly less performant for extremely fine-grained control, but it's negligible for 99% of use cases.

Method 3: Using JAVE (Java Audio Video Encoder)

JAVE is an older, simpler library that was popular before JavaCV became the standard. It's a wrapper around the ffmpeg executable, similar to Method 1, but provides a Java API to simplify command generation.

Prerequisites

  1. FFmpeg Executable: You still need ffmpeg installed and on the PATH.
  2. Maven/Gradle.

Maven Dependency

<dependency>
    <groupId>it.sauronsoftware</groupId>
    <artifactId>jave</artifactId>
    <version>1.0.2</version> <!-- This is the last known version -->
</dependency>

Example Code

import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.EncoderException;
import it.sauronsoftware.jave.MultimediaObject;
public class JaveConverter {
    public static void main(String[] args) {
        Encoder encoder = new Encoder();
        MultimediaObject source = new MultimediaObject("input.mp4");
        File target = new File("output_jave.mp4");
        try {
            // Encoding options
            it.sauronsoftware.jave.AudioAttributes audio = new it.sauronsoftware.jave.AudioAttributes();
            audio.setCodec("libmp3lame"); // Example: MP3 audio codec
            it.sauronsoftware.jave.VideoAttributes video = new it.sauronsoftware.jave.VideoAttributes();
            video.setCodec("libx264"); // H.264 video codec
            it.sauronsoftware.jave.EncodingAttributes attrs = new it.sauronsoftware.jave.EncodingAttributes();
            attrs.setFormat("mp4");
            attrs.setAudioAttributes(audio);
            attrs.setVideoAttributes(video);
            encoder.encode(source, target, attrs);
            System.out.println("Conversion completed successfully!");
        } catch (EncoderException e) {
            e.printStackTrace();
            System.err.println("An error occurred during conversion.");
        }
    }
}

Pros & Cons Revisited:

  • Pro: Very simple API for basic encoding tasks.
  • Con: No longer maintained. It doesn't support modern FFmpeg features or codecs well. It's a dead-end project.

Final Recommendation

Your Goal Recommended Method
Simple Scripting or Quick Test Method 1: ProcessBuilder. It's straightforward if you just need to run a known command.
Production Application, New Project Method 2: JavaCV. This is the industry standard. It's powerful, actively maintained, and handles all the platform complexity for you.
Very Simple Task (Legacy Code) Method 3: JAVE. Only consider this if you're maintaining old code that already uses it. Do not start a new project with it.

For any serious Java application that needs to process audio or video, JavaCV is the way to go. It provides the best balance of power, ease of use, and maintainability.

分享:
扫描分享到社交APP
上一篇
下一篇