Skip to content

threos/ffexecutor

Repository files navigation

Ffexecutor

A powerful Kotlin library that provides a type-safe, object-oriented wrapper around FFmpeg command-line operations. Ffexecutor simplifies video and audio processing by offering a fluent API, matrix-based task execution, and comprehensive metrics collection capabilities.

πŸš€ Features

  • πŸ”’ Type-Safe FFmpeg Operations: Object-oriented approach to FFmpeg commands with compile-time safety
  • πŸ“Š Matrix-Based Task Execution: Execute multiple encoding tasks across different input files and configurations
  • πŸ“Ή Camera Streaming Support: Built-in support for hardware-accelerated camera input across platforms
  • πŸ“ˆ Metrics Collection: Comprehensive video quality metrics (PSNR, SSIM, bitrate analysis)
  • 🌐 Cross-Platform Compatibility: Automatic platform detection for camera backends and hardware acceleration
  • πŸ”— Stream Builder Pattern: Fluent API for creating complex multi-stream configurations
  • βš™οΈ Custom Option Support: Extensible option system for advanced FFmpeg parameters
  • βœ… Task Result Processing: Structured result handling with success/failure tracking

πŸ“‹ Table of Contents

🏁 Getting Started

Prerequisites

  • β˜• Java 17 or higher
  • 🎬 FFmpeg installed and available in your system PATH
  • 🎯 Kotlin 1.8+

Installation

Add the following to your build.gradle.kts:

dependencies {
    implementation("co.xreos:ffexecutor:0.0.1-SNAPSHOT")
}

Basic Usage

import co.xreos.ffexecutor.execution.FfmpegExecutor
import co.xreos.ffexecutor.task.FfmpegCommandTask
import co.xreos.ffexecutor.option.*
import co.xreos.ffexecutor.constant.*

// Simple video conversion
val task = FfmpegCommandTask(
    FfmpegFileInputOption(File("input.mp4")),
    FfmpegVideoCodecOption(FfmpegVideoCodec.H264),
    FfmpegVideoBitrateOption("2M"),
    FfmpegAudioCodecOption(FfmpegAudioCodec.AAC),
    File("output.mp4")
)

val result = FfmpegExecutor.run(task)
println("Success: ${result.success}")

🧠 Core Concepts

πŸ“‹ Tasks

Tasks represent FFmpeg operations and are built using the FfmpegCommandTask class. They can be constructed with various options and executed through the FfmpegExecutor.

βš™οΈ Options

Options are type-safe representations of FFmpeg command-line arguments. Each option implements the IFfmpegOption interface and provides a string representation for the FFmpeg command.

πŸ“¦ Contexts

Contexts encapsulate encoding configurations with input/output files and metadata. They're used in matrix operations for batch processing.

πŸ”„ Matrix

The matrix system allows you to execute multiple encoding tasks across different input files and configurations efficiently.

βš™οΈ Available Options

πŸŽ₯ Video Options

Option Description Example
FfmpegVideoCodecOption Video codec selection FfmpegVideoCodecOption(FfmpegVideoCodec.H264)
FfmpegVideoBitrateOption Video bitrate control FfmpegVideoBitrateOption("2M")
FfmpegVideoSizeOption Video resolution FfmpegVideoSizeOption(1920, 1080)
FfmpegFramerateOption Frame rate setting FfmpegFramerateOption(30)
FfmpegGOPLengthOption Group of Pictures length FfmpegGOPLengthOption(30)
FfmpegBFramesOption B-frame configuration FfmpegBFramesOption(2)
FfmpegReferenceFramesOption Reference frame count FfmpegReferenceFramesOption(3)
FfmpegQuantizationParameterOption QP value for quality control FfmpegQuantizationParameterOption(23)
FfmpegVideoScaleFilterOption Video scaling filter FfmpegVideoScaleFilterOption(1280, 720)
FfmpegPixelFormatOption Pixel format specification FfmpegPixelFormatOption(FfmpegPixelFormat.YUV420P)

🎡 Audio Options

Option Description Example
FfmpegAudioCodecOption Audio codec selection FfmpegAudioCodecOption(FfmpegAudioCodec.AAC)
FfmpegAudioBitrateOption Audio bitrate control FfmpegAudioBitrateOption(128)
FfmpegAudioChannelNumberOption Channel configuration FfmpegAudioChannelNumberOption(2)
FfmpegDisableAudioOption Disable audio stream FfmpegDisableAudioOption()

πŸ“ Input/Output Options

Option Description Example
FfmpegFileInputOption File input source FfmpegFileInputOption(File("input.mp4"))
FfmpegHWInputOption Hardware input (camera) FfmpegHWInputOption("0", "default")
FfmpegBackendAPIOption Hardware backend API FfmpegBackendAPIOption("dshow")
FfmpegAutoInputOption Automatic input detection FfmpegAutoInputOption()

πŸ”§ Advanced Options

Option Description Example
FfmpegCustomOption Custom FFmpeg arguments FfmpegCustomOption("-map 0:v:0")
FfmpegSegmentDurationOption Segment duration for streaming FfmpegSegmentDurationOption(2)
FfmpegMotionEstimationMethodOption Motion estimation algorithm FfmpegMotionEstimationMethodOption(FfmpegMotionEstimationMethod.HEX)
FfmpegX265ParamsOption x265 encoder parameters FfmpegX265ParamsOption("crf=23")

Supported Codecs

πŸŽ₯ Video Codecs

  • H.264 (libx264) - Widely compatible, good balance of quality and compression
  • H.265 (libx265) - Better compression efficiency, newer standard
  • VP9 (libvpx-vp9) - Open-source, web-optimized
  • AV1 (libaom-av1) - Next-generation codec, best compression

🎡 Audio Codecs

  • AAC - Standard for most applications
  • MP3 - Legacy compatibility
  • Opus - Low latency, high quality
  • Vorbis - Open-source alternative

πŸ”„ Matrix Capabilities

The matrix system enables batch processing across multiple inputs and configurations:

val matrix = FfmpegTaskMatrix(
    inputs = listOf(File("video1.mp4"), File("video2.mp4")),
    contexts = listOf(
        FfmpegBaseContext(
            id = "high_quality",
            options = listOf(
                FfmpegVideoCodecOption(FfmpegVideoCodec.H264),
                FfmpegVideoBitrateOption("5M")
            )
        ),
        FfmpegBaseContext(
            id = "low_quality", 
            options = listOf(
                FfmpegVideoCodecOption(FfmpegVideoCodec.H264),
                FfmpegVideoBitrateOption("1M")
            )
        )
    ),
    outputProvider = { input, context -> 
        File("output/${input.nameWithoutExtension}_${context.id}.mp4") 
    },
    outputMetadataProvider = { input, context -> 
        File("metadata/${input.nameWithoutExtension}_${context.id}.txt") 
    }
)

// Execute all combinations
FfmpegExecutor.execute(matrix)

πŸ”„ Execution Lifecycle

  1. πŸ“‹ Task Creation: Build FfmpegCommandTask with desired options
  2. βš™οΈ Command Generation: Options are converted to FFmpeg command-line arguments
  3. πŸš€ Process Execution: FFmpeg process is spawned with generated command
  4. πŸ“Š Result Collection: Output streams are captured and processed
  5. βœ… Result Processing: TaskResult object contains success status and output data

TaskResult Structure

data class TaskResult(
    val success: Boolean,           // Process exit code == 0
    val output: String,            // Standard output stream
    val errorOutput: String,       // Standard error stream  
    val exitValue: Int             // Process exit code
)

πŸ“Ή Camera Compatibility

Ffexecutor provides cross-platform camera support with automatic backend detection:

🌐 Platform Support

Platform Backend Input Format Audio Support
πŸͺŸ Windows DirectShow video=0:audio=default PulseAudio
🍎 macOS AVFoundation 0:default Built-in
🐧 Linux V4L2 /dev/video0 PulseAudio

Camera Usage Example

val cameraTask = FfmpegCommandTask(
    FfmpegBackendAPIOption(CameraUtil.getPlatformCameraBackendAPIFormat()),
    FfmpegHWInputOption(camera = "0", audio = "default"),
    FfmpegVideoCodecOption(FfmpegVideoCodec.H264),
    FfmpegVideoSizeOption(1920, 1080),
    FfmpegFramerateOption(30),
    FfmpegAudioCodecOption(FfmpegAudioCodec.AAC),
    File("camera_output.mp4")
)

val result = FfmpegExecutor.run(cameraTask)

Stream Builder for Multi-Stream Output

val streamingTask = FfmpegCommandTask(
    FfmpegHWInputOption("0"),
    FfmpegVideoCodecOption(FfmpegVideoCodec.H264),
    
    // High quality stream
    FfmpegStreamBuilder(index = 0)
        .withVideoBitrate(megaBitPerSecond = 3)
        .build(),
    
    // Low quality stream  
    FfmpegStreamBuilder(index = 1)
        .withVideoBitrate(megaBitPerSecond = 1)
        .withVideoScaleFilter(width = -2, height = 480)
        .build(),
    
    FfmpegSegmentDurationOption(2),
    FfmpegCustomOption("-f dash stream.mpd")
)

πŸ“Š Metrics and Quality Analysis

Ffexecutor includes built-in support for video quality metrics:

πŸ“Š Available Metrics

  • πŸ“ˆ PSNR (Peak Signal-to-Noise Ratio): Objective quality measurement
  • πŸ” SSIM (Structural Similarity Index): Perceptual quality assessment
  • πŸ’Ύ Bitrate Analysis: Compression efficiency metrics
  • 🎬 Motion Estimation: Motion vector analysis
  • πŸ–ΌοΈ GOP Analysis: Group of Pictures efficiency

Metrics Usage

// Process PSNR metrics from FFmpeg output
val psnrProcessor = QpPsnrYProcessor()
val psnrData = psnrProcessor.process(context, ffmpegOutput)

// Process SSIM metrics
val ssimProcessor = QpSsimProcessor() 
val ssimData = ssimProcessor.process(context, ffmpegOutput)

🎯 Examples

🎬 Basic Video Conversion

val conversionTask = FfmpegCommandTask(
    FfmpegFileInputOption(File("input.mov")),
    FfmpegVideoCodecOption(FfmpegVideoCodec.H264),
    FfmpegVideoBitrateOption("2M"),
    FfmpegAudioCodecOption(FfmpegAudioCodec.AAC),
    FfmpegAudioBitrateOption(128),
    File("output.mp4")
)

val result = FfmpegExecutor.run(conversionTask)

πŸ“‘ Live Streaming Setup

val streamingTask = FfmpegCommandTask(
    FfmpegHWInputOption("0"),
    FfmpegVideoCodecOption(FfmpegVideoCodec.H264),
    FfmpegVideoSizeOption(1280, 720),
    FfmpegFramerateOption(30),
    FfmpegAudioCodecOption(FfmpegAudioCodec.AAC),
    FfmpegCustomOption("-f flv rtmp://streaming-server/live/stream")
)

val result = FfmpegExecutor.run(streamingTask)

πŸ“Š Batch Processing with Quality Analysis

val inputs = listOf(File("video1.mp4"), File("video2.mp4"))
val qualityLevels = listOf("high", "medium", "low")

val matrix = FfmpegTaskMatrix(
    inputs = inputs,
    contexts = qualityLevels.map { level ->
        FfmpegBaseContext(
            id = level,
            options = when(level) {
                "high" -> listOf(FfmpegVideoBitrateOption("5M"))
                "medium" -> listOf(FfmpegVideoBitrateOption("2M")) 
                "low" -> listOf(FfmpegVideoBitrateOption("1M"))
                else -> emptyList()
            }
        )
    },
    outputProvider = { input, context -> 
        File("output/${input.nameWithoutExtension}_${context.id}.mp4") 
    },
    outputMetadataProvider = { input, context -> 
        File("metrics/${input.nameWithoutExtension}_${context.id}.json") 
    }
)

FfmpegExecutor.execute(matrix)

πŸ”§ Advanced Usage

For more advanced features and detailed API documentation, see ADVANCED.md.

βš™οΈ Custom Options

// Create custom FFmpeg options
val customOption = FfmpegCustomOption("-preset slow -crf 23")

// Use in task
val task = FfmpegCommandTask(
    FfmpegFileInputOption(File("input.mp4")),
    customOption,
    File("output.mp4")
)

⚠️ Error Handling

val result = FfmpegExecutor.run(task)

if (!result.success) {
    logger.error("FFmpeg execution failed: ${result.errorOutput}")
    // Handle error appropriately
} else {
    logger.info("Encoding completed successfully")
    // Process successful result
}

🀝 Contributing

Contributions are welcome! Please feel free to submit issues and enhancement requests.

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ”— Related Projects

About

Kotlin based Ffmpeg wrapper project

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages