Skip to content

Using FFmpegKitNext on Linux

Taner Sener edited this page Jul 28, 2026 · 2 revisions

This page shows how to use FFmpegKitNext from a Linux C++ application after the Linux headers and shared libraries have already been added to the application.

1. Include the API

Use the headers for the features you need:

#include <FFmpegKit.h>
#include <FFmpegKitConfig.h>
#include <FFprobeKit.h>

using namespace ffmpegkit;

2. Run FFmpeg

Use execute for synchronous execution. It returns an FFmpegSession with the result, logs, statistics and failure details.

auto session = FFmpegKit::execute("-y -i input.mp4 -c:v mpeg4 output.mp4");
auto returnCode = session->getReturnCode();

if (ReturnCode::isSuccess(returnCode)) {
    std::cout << "FFmpeg completed successfully." << std::endl;
} else if (ReturnCode::isCancel(returnCode)) {
    std::cout << "FFmpeg command was cancelled." << std::endl;
} else {
    std::cout << "FFmpeg failed with state "
              << FFmpegKitConfig::sessionStateToString(session->getState())
              << " and rc " << returnCode << "."
              << session->getFailStackTrace() << std::endl;
}

Use executeWithArguments when paths, filter expressions, or user-provided values may contain spaces or shell-sensitive characters.

std::list<std::string> arguments = {
    "-y",
    "-i", "/tmp/input with spaces.mp4",
    "-vf", "scale=1280:-2",
    "-c:v", "mpeg4",
    "/tmp/output.mp4"
};

auto session = FFmpegKit::executeWithArguments(arguments);

executeAsync starts the command and returns immediately. Use the session callback for the final result, the log callback for FFmpeg log lines and the statistics callback for progress information.

auto asyncSession = FFmpegKit::executeAsync(
    "-y -i input.mp4 -c:v mpeg4 output.mp4",
    [](const std::shared_ptr<FFmpegSession> session) {
        auto returnCode = session->getReturnCode();
        std::cout << "FFmpeg ended with state "
                  << FFmpegKitConfig::sessionStateToString(session->getState())
                  << " and rc " << returnCode << "." << std::endl;
    },
    [](const std::shared_ptr<Log> log) {
        std::cout << log->getMessage();
    },
    [](const std::shared_ptr<Statistics> statistics) {
        std::cout << "frame=" << statistics->getVideoFrameNumber()
                  << " time=" << statistics->getTime()
                  << " speed=" << statistics->getSpeed() << std::endl;
    });

3. Inspect Sessions

Each execution creates a session. Use it to inspect the command, state, output, logs, statistics and timing.

auto session = FFmpegKit::execute("-y -i input.mp4 -f null -");

long sessionId = session->getSessionId();
std::string command = session->getCommand();
auto arguments = session->getArguments();
SessionState state = session->getState();
auto returnCode = session->getReturnCode();

auto startTime = session->getStartTime();
auto endTime = session->getEndTime();
long durationMs = session->getDuration();

std::string output = session->getOutput();
std::string failStackTrace = session->getFailStackTrace();

auto logs = session->getAllLogs();
auto statistics = session->getAllStatistics();
auto lastStatistics = session->getLastReceivedStatistics();

For asynchronous sessions, getAllLogs() and getAllStatistics() wait for pending asynchronous messages. getLogs() and getStatistics() return only the messages already delivered.

Session history is managed by FFmpegKitConfig.

FFmpegKitConfig::setSessionHistorySize(100);

auto sessions = FFmpegKitConfig::getSessions();
int index = 0;

for (const auto &session : *sessions) {
    std::cout << "Session " << index++
              << " id=" << session->getSessionId()
              << " state=" << FFmpegKitConfig::sessionStateToString(session->getState())
              << " durationMs=" << session->getDuration()
              << " rc=" << session->getReturnCode()
              << std::endl;
}

auto runningSessions = FFmpegKitConfig::getSessionsByState(SessionStateRunning);
auto ffmpegSessions = FFmpegKitConfig::getFFmpegSessions();
auto ffprobeSessions = FFmpegKitConfig::getFFprobeSessions();
auto mediaInformationSessions = FFmpegKitConfig::getMediaInformationSessions();

You can also retrieve FFmpegKitConfig::getLastSession(), FFmpegKitConfig::getLastCompletedSession(), or FFmpegKitConfig::getSession(sessionId). Use deleteSession(sessionId) or clearSessions() only when you no longer need the session history; callbacks cannot be triggered for deleted sessions.

4. Run FFprobe

Use FFprobeKit for direct ffprobe commands.

auto probeSession = FFprobeKit::execute(
    "-v error -show_entries format=duration "
    "-of default=noprint_wrappers=1:nokey=1 input.mp4");

if (!ReturnCode::isSuccess(probeSession->getReturnCode())) {
    std::cout << "FFprobe failed. Output: "
              << probeSession->getAllLogsAsString() << std::endl;
}

The same command can run asynchronously:

auto asyncProbeSession = FFprobeKit::executeAsync(
    "-v error -show_streams -of json input.mp4",
    [](const std::shared_ptr<FFprobeSession> session) {
        std::cout << "FFprobe rc=" << session->getReturnCode() << std::endl;
    });

For parsed media metadata, use getMediaInformation.

auto mediaSession = FFprobeKit::getMediaInformation("input.mp4");
auto mediaInformation = mediaSession->getMediaInformation();

if (mediaInformation != nullptr) {
    auto duration = mediaInformation->getDuration();
    auto format = mediaInformation->getFormat();
    auto streams = mediaInformation->getStreams();

    if (duration != nullptr) {
        std::cout << "duration=" << *duration << std::endl;
    }
    if (format != nullptr) {
        std::cout << "format=" << *format << std::endl;
    }
    if (streams != nullptr) {
        std::cout << "stream count=" << streams->size() << std::endl;
    }
}

Keep log redirection enabled when using getMediaInformation; disabling redirection prevents media information parsing from receiving the JSON output it needs.

5. Cancel Sessions

Cancellation returns immediately. Check the complete callback or session state later to observe the final result.

auto session = FFmpegKit::executeAsync(
    "-i input.mp4 -c:v mpeg4 output.mp4",
    [](const std::shared_ptr<FFmpegSession> completedSession) {
        if (ReturnCode::isCancel(completedSession->getReturnCode())) {
            std::cout << "Cancelled." << std::endl;
        }
    });

FFmpegKit::cancel(session->getSessionId());

// Or cancel every running FFmpeg session.
FFmpegKit::cancel();

6. Configure Logs and Callbacks

Redirection is enabled by default. With redirection enabled, sessions collect logs and statistics, global/session callbacks receive messages and media information parsing works.

FFmpegKitConfig::setLogLevel(LevelAVLogInfo);

FFmpegKitConfig::enableLogCallback(
    [](const std::shared_ptr<Log> log) {
        std::cout << FFmpegKitConfig::logLevelToString(log->getLevel())
                  << ": " << log->getMessage();
    });

FFmpegKitConfig::enableStatisticsCallback(
    [](const std::shared_ptr<Statistics> statistics) {
        std::cout << "session=" << statistics->getSessionId()
                  << " frame=" << statistics->getVideoFrameNumber()
                  << " bitrate=" << statistics->getBitrate()
                  << std::endl;
    });

FFmpegKitConfig::enableFFmpegSessionCompleteCallback(
    [](const std::shared_ptr<FFmpegSession> session) {
        std::cout << "FFmpeg session " << session->getSessionId()
                  << " completed." << std::endl;
    });

FFmpegKitConfig::enableFFprobeSessionCompleteCallback(
    [](const std::shared_ptr<FFprobeSession> session) {
        std::cout << "FFprobe session " << session->getSessionId()
                  << " completed." << std::endl;
    });

FFmpegKitConfig::enableMediaInformationSessionCompleteCallback(
    [](const std::shared_ptr<MediaInformationSession> session) {
        std::cout << "Media information session " << session->getSessionId()
                  << " completed." << std::endl;
    });

Disable a previously registered global callback by passing nullptr.

FFmpegKitConfig::enableLogCallback(nullptr);
FFmpegKitConfig::enableStatisticsCallback(nullptr);
FFmpegKitConfig::enableFFmpegSessionCompleteCallback(nullptr);

Use the log redirection strategy when you need to control whether logs are printed to stderr in addition to being collected by the API.

FFmpegKitConfig::setLogRedirectionStrategy(
    LogRedirectionStrategyPrintLogsWhenNoCallbacksDefined);

Use FFmpegKitConfig::disableRedirection() only when you want FFmpeg and FFprobe output to go directly to stderr and you do not need logs, statistics callbacks, or getMediaInformation.

7. Use Fonts with drawtext

The drawtext filter requires a Linux build that includes freetype and harfbuzz. Registering directories and using font family names additionally requires fontconfig.

If the command can use a font file directly, pass fontfile:

auto session = FFmpegKit::execute(
    "-y -i input.mp4 "
    "-vf \"drawtext=fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf:"
    "text='Hello':x=20:y=20:fontsize=32:fontcolor=white\" "
    "output.mp4");

If fontconfig is enabled, register directories and optional friendly names:

FFmpegKitConfig::setFontDirectoryList(
    std::list<std::string>{"/usr/share/fonts", "/usr/local/share/fonts"},
    std::map<std::string, std::string>{{"MyFont", "My Font"}});

auto session = FFmpegKit::execute(
    "-y -i input.mp4 "
    "-vf \"drawtext=font='MyFont':text='Hello':x=20:y=20\" "
    "output.mp4");

If your application ships a custom fonts.conf, point fontconfig to that configuration directory:

int result = FFmpegKitConfig::setFontconfigConfigurationPath("/opt/myapp/fontconfig");

8. Use In-Memory Input and Output

FFmpegKitInputBuffer and FFmpegKitOutputBuffer expose finite, seekable in-memory resources through ffkitmem: URLs. They are useful when you already have bytes in memory or want the encoded output as bytes without writing a temporary file.

std::vector<uint8_t> inputBytes = loadInputBytes();

auto input = FFmpegKitInputBuffer::fromByteArray(inputBytes, "mp4");
auto output = FFmpegKitOutputBuffer::create("mp4");

std::list<std::string> arguments = {
    "-y",
    "-i", input->getUrl(),
    "-c:v", "mpeg4",
    "-f", "mp4",
    output->getUrl()
};

auto session = FFmpegKit::executeWithArguments(arguments);

if (ReturnCode::isSuccess(session->getReturnCode())) {
    auto outputBytes = output->toByteArray();
    std::cout << "encoded bytes=" << outputBytes->size() << std::endl;
}

input->close();
output->close();

fromBytes(data, size, extension) is available when your input is already in a raw byte pointer. create(extension, initialCapacity, maxCapacity) lets you control the output buffer capacity.

9. Use Streaming Input and Output

FFmpegKitStreamInput and FFmpegKitStreamOutput expose non-seekable memory-backed streams through ffkitstream: URLs. Use them for producer/consumer flows. Use ffkitmem: instead when the format needs seeking.

auto streamInput = FFmpegKitStreamInput::create("raw");
auto streamOutput = FFmpegKitStreamOutput::create("wav");

std::list<std::string> arguments = {
    "-f", "s16le",
    "-ar", "48000",
    "-ac", "2",
    "-i", streamInput->getUrl(),
    "-f", "wav",
    streamOutput->getUrl()
};

auto session = FFmpegKit::executeWithArgumentsAsync(
    arguments,
    [](const std::shared_ptr<FFmpegSession> session) {
        std::cout << "streaming session rc=" << session->getReturnCode() << std::endl;
    });

std::vector<uint8_t> pcmChunk = readNextPcmChunk();
streamInput->write(pcmChunk, 1000);
streamInput->closeInput();

auto encodedChunk = streamOutput->read(4096, 1000);
if (encodedChunk != nullptr && !encodedChunk->empty()) {
    consumeEncodedBytes(*encodedChunk);
}

streamInput->close();
streamOutput->close();

A stream read(maxBytes, timeoutMs) returns nullptr on timeout and an empty vector at EOF. Read output while the session runs if the produced data may exceed the stream capacity.

10. Use Named Pipes

Use a named pipe when you need a filesystem path that another part of your application can write to while FFmpeg reads from it.

auto pipePath = FFmpegKitConfig::registerNewFFmpegPipe();

if (pipePath != nullptr) {
    std::list<std::string> arguments = {
        "-y",
        "-i", *pipePath,
        "-c:v", "mpeg4",
        "output.mp4"
    };

    auto session = FFmpegKit::executeWithArgumentsAsync(
        arguments,
        [](const std::shared_ptr<FFmpegSession> session) {
            std::cout << "pipe session rc=" << session->getReturnCode() << std::endl;
        });

    std::ofstream writer(*pipePath, std::ios::binary);
    std::vector<uint8_t> bytes = readBytesForPipe();
    writer.write(reinterpret_cast<const char *>(bytes.data()), bytes.size());
    writer.close();

    FFmpegKitConfig::closeFFmpegPipe(*pipePath);
}

Close every pipe created with registerNewFFmpegPipe() after the command and writer finish.

11. Runtime Diagnostics

Use the configuration and package helpers to inspect the runtime your application loaded.

#include <ArchDetect.h>
#include <Packages.h>

std::cout << "FFmpegKit version: " << FFmpegKitConfig::getVersion() << std::endl;
std::cout << "FFmpeg version: " << FFmpegKitConfig::getFFmpegVersion() << std::endl;
std::cout << "Build date: " << FFmpegKitConfig::getBuildDate() << std::endl;
std::cout << "Package name: " << Packages::getPackageName() << std::endl;
std::cout << "Architecture: " << ArchDetect::getArch() << std::endl;

auto libraries = Packages::getExternalLibraries();
if (libraries->find("freetype") != libraries->end() &&
    libraries->find("harfbuzz") != libraries->end()) {
    std::cout << "drawtext dependencies are available." << std::endl;
}

Packages::getExternalLibraries() returns enabled external library identifiers such as freetype, harfbuzz, fontconfig, x264, x265, or gnutls.

Packages::getPackageName() returns the custom package name configured at build time.

Set process environment variables before running sessions when an FFmpeg library or protocol needs them:

int result = FFmpegKitConfig::setEnvironmentVariable("SSL_CERT_FILE", "/etc/ssl/certs/ca-certificates.crt");

If your application owns signal handling, you can tell FFmpegKit to ignore specific signals:

FFmpegKitConfig::ignoreSignal(SignalPipe);
FFmpegKitConfig::ignoreSignal(SignalXcpu);

12. Test Application

For runnable Linux examples, see the test applications in the ffmpeg-kit-next-test project. It contains C++ examples for command execution, audio/video operations, subtitles, pipes, concurrent execution, HTTPS, ffkitmem:/ffkitstream: protocols, media information parsing and other runtime API features.

Clone this wiki locally