How to use FFmpeg in Android

How to integrate FFmpeg library in Android studio to make Android FFmpeg video editing application

Follow these steps to integrate ffmpeg library in Android

Android version requirement

  • For versions 4.4 and 4.4.LTS, add mavenCentral() to your build.gradle and make sure that it is listed before jcenter()
  • For 4.3.2 and older releases, add jcenter()
repositories {
    mavenCentral()
}
  • Add MobileFFmpeg dependency to your build.gradle in mobile-ffmpeg-<package name> pattern
dependencies {
    implementation 'com.arthenica:mobile-ffmpeg-full:4.4'
}

Execute synchronous FFmpeg commands

import com.arthenica.mobileffmpeg.Config;
import com.arthenica.mobileffmpeg.FFmpeg;

int rc = FFmpeg.execute("-i file1.mp4 -c:v mpeg4 file2.mp4");

if (rc == RETURN_CODE_SUCCESS) {
    Log.i(Config.TAG, "Command execution completed successfully.");
} else if (rc == RETURN_CODE_CANCEL) {
    Log.i(Config.TAG, "Command execution cancelled by user.");
} else {
    Log.i(Config.TAG, String.format("Command execution failed with rc=%d and the output below.", rc));
    Config.printLastCommandOutput(Log.INFO);
}

Execute asynchronous FFmpeg commands

import com.arthenica.mobileffmpeg.Config;
import com.arthenica.mobileffmpeg.FFmpeg;

long executionId = FFmpeg.executeAsync("-i file1.mp4 -c:v mpeg4 file2.mp4", new ExecuteCallback() {

    @Override
    public void apply(final long executionId, final int returnCode) {
        if (returnCode == RETURN_CODE_SUCCESS) {
            Log.i(Config.TAG, "Async command execution completed successfully.");
        } else if (returnCode == RETURN_CODE_CANCEL) {
            Log.i(Config.TAG, "Async command execution cancelled by user.");
        } else {
            Log.i(Config.TAG, String.format("Async command execution failed with returnCode=%d.", returnCode));
        }
    }
});

Execute FFprobe commands

import com.arthenica.mobileffmpeg.Config;
import com.arthenica.mobileffmpeg.FFprobe;

int rc = FFprobe.execute("-i file1.mp4");

if (rc == RETURN_CODE_SUCCESS) {
    Log.i(Config.TAG, "Command execution completed successfully.");
} else {
    Log.i(Config.TAG, String.format("Command execution failed with rc=%d and the output below.", rc));
    Config.printLastCommandOutput(Log.INFO);
}

Check execution output later

int rc = Config.getLastReturnCode();

if (rc == RETURN_CODE_SUCCESS) {
    Log.i(Config.TAG, "Command execution completed successfully.");
} else if (rc == RETURN_CODE_CANCEL) {
    Log.i(Config.TAG, "Command execution cancelled by user.");
} else {
    Log.i(Config.TAG, String.format("Command execution failed with rc=%d and the output below.", rc));
    Config.printLastCommandOutput(Log.INFO);
}

Stop ongoing FFmpeg operations

  • Stop all executions
FFmpeg.cancel();
  • Stop a specific execution
FFmpeg.cancel(executionId);

Get media information for a file

MediaInformation info = FFprobe.getMediaInformation("<file path or uri>");

Record video using Android camera

FFmpeg.execute("-f android_camera -i 0:0 -r 30 -pixel_format bgr0 -t 00:00:05 <record file path>");

Enable log callback

Config.enableLogCallback(new LogCallback() {
    public void apply(LogMessage message) {
        Log.d(Config.TAG, message.getText());
    }
});

Enable statistics callback

Config.enableStatisticsCallback(new StatisticsCallback() {
    public void apply(Statistics newStatistics) {
        Log.d(Config.TAG, String.format("frame: %d, time: %d", newStatistics.getVideoFrameNumber(), newStatistics.getTime()));
    }
});

Ignore the handling of a signal

Config.ignoreSignal(Signal.SIGXCPU);

List ongoing executions

final List<FFmpegExecution> ffmpegExecutions = FFmpeg.listExecutions();
for (int i = 0; i < ffmpegExecutions.size(); i++) {
    FFmpegExecution execution = ffmpegExecutions.get(i);
    Log.d(TAG, String.format("Execution %d = id:%d, startTime:%s, command:%s.", i, execution.getExecutionId(), execution.getStartTime(), execution.getCommand()));
}

Set default log level

Config.setLogLevel(Level.AV_LOG_FATAL);

Register custom fonts directory

Config.setFontDirectory(this, "<folder with fonts>", Collections.EMPTY_MAP);

Leave a Comment