A production-grade, type-safe, and fluent Java wrapper for FFmpeg and FFprobe. Designed for modern high-performance media applications, it leverages Java 25 Records, Sealed Classes, and Project Panama for native efficiency and developer ergonomics.
Published on Maven Central (Sonatype).
Add the following dependency to your pom.xml:
<dependency>
<groupId>io.github.kinsleykajiva</groupId>
<artifactId>ffmpeg-with-java</artifactId>
<version>0.0.1</version>
</dependency>- Records: Immutable data carriers for
AudioMetadataandEncodingResult. No more parsing raw strings or maps. - Sealed Exceptions: A structured hierarchy (
FFmpegException) that allows granular error handling for missing binaries, network congestion, or execution timeouts. - Enums: Type-safe constants for
AudioCodec(Opus, AAC, MP3),SampleRate, andChannelLayout.
This library is built with high-performance media requirements in mind, utilizing Project Panama (JEP 454) for ultra-efficient native interactions.
Unlike traditional JNI-based wrappers, we use Java's Foreign Function & Memory API to handle native memory:
- Deterministic Resource Management: We use
Arena.ofConfined()for all native calls. This ensures that memory used during metadata probing is released immediately after the call, preventing the "memory creep" common in media processing. - Zero-Copy Probing: When extracting metadata, we map native FFmpeg structs directly to Java
MemorySegmentobjects, avoiding expensive byte-array copying. - Off-heap Efficiency: Sensitive data or large buffers are maintained off-heap, keeping the JVM Garbage Collector (GC) lean and responsive for your application logic.
While metadata probing happens in-process via Panama for speed, heavy transcoding is handled via Process Isolation:
- Stability: Crashing FFmpeg binaries (e.g., due to corrupt input) won't crash your JVM.
- Memory Capping: Native memory used by the
ffmpegprocess is separate from the Java heap, making it easier to manage resource limits in containerized environments (Docker/K8s).
Construct complex media jobs using a clean, chained interface that eliminates configuration errors.
FFmpeg.input("song.mp3")
.output("processed.opus")
.withCodec(AudioCodec.LIBOPUS)
.withBitrate("128k")
.addFilter(AudioFilters.volume(1.2))
.executeAsync();Go beyond file processing with dedicated low-latency streaming support:
- Protocols: Native support for
RTP,SRT,UDP, andRTSP. - Low-Latency Tuning:
.asLiveSource()enables-reandnobufferflags. - Instant Startup:
.withInstantStartup()setsprobesizeandanalyzedurationto near-zero. - SDP Auto-Generation: Automatically export
.sdpfiles for RTP receivers.
- Throughput Stats: Track
bitrateand processingspeedin real-time. - Congestion Detection: Easily identify when network speed falls below 1.0x (real-time).
- Progress Tracking: Visual feedback on processed frames and bitrate.
Catch errors before they reach FFmpeg:
- Path Validation: Ensures input files exist and are readable.
- Bitrate Regex: Validates formats like
128kor1M. - Volume Range: Prevents audio clipping by enforcing the 0.0 to 10.0 range.
AudioMetadata metadata = FFmpeg.input("input.mp3").probe();
System.out.println("Format: " + metadata.format());
System.out.println("Duration: " + metadata.durationSeconds() + "s");FFmpeg.input("live_input.wav")
.asLiveSource()
.withCodec(AudioCodec.LIBOPUS)
.toStream(StreamDestination.rtp("192.168.1.50", 5004))
.saveSdpTo(Path.of("stream.sdp"))
.onStreamStats((br, speed, dropped) -> {
System.out.printf("Health: %d bps | Speed %.2fx\n", br, speed);
})
.executeAsync();- Type Safety: Drastically reduces "magic string" errors common in other wrappers.
- Virtual Thread Architecture: All callbacks (
onProgress,onStreamStats) are executed on Virtual Threads (JEP 444). This ensures that slow listener logic (e.g., database writes or network calls) never blocks the FFmpeg output reader or impacts the process monitoring performance. - Modern Concurrency: Full support for
CompletableFuture(async) and decoupled event publishing. - Deterministic Memory: Project Panama
Arenausage ensures zero memory leaks in native space. - Low Latency: Highly tuned for real-time media engines (Project Panama overhead is negligible).
- GC Efficiency: Off-heap data handling keeps Java heap usage low and stable.
- No Boilerplate: Binary resolution, error parsing, progress monitoring, and automatic log cleaning (
-hide_banner) are handled out-of-the-box. - Robustness: Sealed exceptions force developers to handle specific failure modes.
- RTP Monitoring: FFmpeg streaming via RTP over UDP is a "fire-and-forget" broadcast protocol. It does not provide feedback on connected clients. You cannot detect how many clients are listening or when they drop using standard FFmpeg and RTP.
- Feature Scope: Currently focused on Audio. Video support is scheduled for a future release.
- Native Dependency: Requires
ffmpeg.exeandffprobe.exeto be present (though it can auto-locate them). - Preview Feature: Uses Java's Project Panama (Foreign Function API), which requires
--enable-native-access=ALL-UNNAMEDand--enable-previewflags.
FFmpeg.java: Unified entry point.AudioJobBuilder.java: Fluent configuration engine.FFmpegExecutor.java: Low-level process and stream management.FFmpegBinary.java: Smart executable resolver.exception/: Sealed exception hierarchy.model/: Type-safe records and enums.
We provide modular demo classes in the demo package for easy exploration:
MetadataDemo: Shows Project Panama-based probing of MP3/WAV info.ComprehensiveMetadataDemo: Demonstrates reading and setting (writing) audio tags like Title, Artist, and Album.TranscodingDemo: Demonstrates the fluent builder with filters and async execution.StreamingDemo: Showcases RTP streaming with real-time stats monitoring.ValidationDemo: Highlights the safety checks for paths, bitrates, and volume.ConfigDemo: Demonstrates programmatic configuration of FFmpeg binary paths.OSSupportDemo: Verifies cross-platform detection and path mapping.
- Java 22+ (Java 25 recommended)
- Maven
By default, the library looks for FFmpeg in the system PATH or the correct OS-specific bundled directory in ffmpeg-builds/ (supports Windows, Linux, and macOS).
FFmpeg.setBinPath("C:/Custom/FFmpeg/bin");
// Validates presence of ffmpeg.exe, ffprobe.exe, and required DLLs immediately.Ensure you use the following JVM flags for native access:
java --enable-native-access=ALL-UNNAMED --enable-preview -classpath ... demo.AudioTest