FFmpegKit for Flutter

1. Features

  • Includes both FFmpeg and FFprobe

  • Supports

    • Android, iOS and macOS

    • FFmpeg v4.5-dev releases

    • arm-v7a, arm-v7a-neon, arm64-v8a, x86 and x86_64 architectures on Android

    • Android API Level 16 or later

    • armv7, armv7s, arm64, arm64-simulator, i386, x86_64, x86_64-mac-catalyst and arm64-mac-catalyst architectures on iOS

    • iOS SDK 10 or later

    • arm64 and x86_64 architectures on macOS

    • macOS SDK 10.12+ or later

    • Can process Storage Access Framework (SAF) Uris on Android

    • 25 external libraries

      dav1d, fontconfig, freetype, fribidi, gmp, gnutls, kvazaar, lame, libass, libiconv, libilbc , libtheora, libvorbis, libvpx, libwebp, libxml2, opencore-amr, opus, shine, snappy, soxr , speex, twolame, vo-amrwbenc, zimg

    • 4 external libraries with GPL license

      vid.stab, x264, x265, xvidcore

  • Licensed under LGPL 3.0, can be customized to support GPL v3.0

2. Installation

Add ffmpeg_kit_flutter as a dependency in your pubspec.yaml file.

dependencies:
  ffmpeg_kit_flutter: 4.5.1

2.1 Packages

ffmpeg includes built-in encoders for some popular formats. However, there are certain external libraries that needs to be enabled in order to encode specific formats/codecs. For example, to encode an mp3 file you need lame or shine library enabled. You have to install a ffmpeg_kit_flutter package that has at least one of them inside. To encode an h264 video, you need to install a package with x264 inside. To encode vp8 or vp9 videos, you need a ffmpeg_kit_flutter package with libvpx inside.

ffmpeg-kit provides eight packages that include different sets of external libraries. These packages are named according to the external libraries included in them. Refer to Packages section of the project README to see the names of those packages and external libraries included in each of them.

2.2 Installing Packages

Installing ffmpeg_kit_flutter enables the https package by default. It is possible to install the other packages using the following dependency format.

dependencies:
  ffmpeg_kit_flutter_<package name>: 4.5.1

Note that hyphens in the package name must be replaced with underscores. Additionally, do not forget to use the package name in the import statements if you install a package.

2.3 Installing LTS Releases

In order to install the LTS variant, append -LTS to the version you have for the ffmpeg_kit_flutter dependency.

dependencies:
  ffmpeg_kit_flutter: 4.5.1-LTS

2.4 LTS Releases

ffmpeg_kit_flutter is published in two different variants: Main Release and LTS Release. Both releases share the same source code but is built with different settings (Architectures, API Level, iOS Min SDK, etc.). Refer to LTS Releases section of the project README to see how they compare to each other.

2.5 Android and iOS Support

The following table shows the Android API level and iOS deployment target required in ffmpeg_kit_flutter releases.

Main Release LTS Release
Android
API Level
iOS Minimum
Deployment Target
Android
API Level
iOS Minimum
Deployment Target
24 12.1 16 10

3. Using

  1. Execute FFmpeg commands.

    import 'package:ffmpeg_kit_flutter/ffmpeg_kit.dart';
    
    FFmpegKit.execute('-i file1.mp4 -c:v mpeg4 file2.mp4').then((session) async {
      final returnCode = await session.getReturnCode();
    
      if (ReturnCode.isSuccess(returnCode)) {
    
        // SUCCESS
    
      } else if (ReturnCode.isCancel(returnCode)) {
    
        // CANCEL
    
      } else {
    
        // ERROR
    
      }
    });
    
  2. Each execute call creates a new session. Access every detail about your execution from the session created.

    FFmpegKit.execute('-i file1.mp4 -c:v mpeg4 file2.mp4').then((session) async {
    
      // Unique session id created for this execution
      final sessionId = session.getSessionId();
    
      // Command arguments as a single string
      final command = session.getCommand();
    
      // Command arguments
      final commandArguments = session.getArguments();
    
      // State of the execution. Shows whether it is still running or completed
      final state = await session.getState();
    
      // Return code for completed sessions. Will be undefined if session is still running or FFmpegKit fails to run it
      final returnCode = await session.getReturnCode();
    
      final startTime = session.getStartTime();
      final endTime = await session.getEndTime();
      final duration = await session.getDuration();
    
      // Console output generated for this execution
      final output = await session.getOutput();
    
      // The stack trace if FFmpegKit fails to run a command
      final failStackTrace = await session.getFailStackTrace();
    
      // The list of logs generated for this execution
      final logs = await session.getLogs();
    
      // The list of statistics generated for this execution (only available on FFmpegSession)
      final statistics = await (session as FFmpegSession).getStatistics();
    
    });
    
  3. Execute FFmpeg commands by providing session specific execute/log/session callbacks.

    FFmpegKit.executeAsync('-i file1.mp4 -c:v mpeg4 file2.mp4', (Session session) async {
    
      // CALLED WHEN SESSION IS EXECUTED
    
    }, (Log log) {
    
      // CALLED WHEN SESSION PRINTS LOGS
    
    }, (Statistics statistics) {
    
      // CALLED WHEN SESSION GENERATES STATISTICS
    
    });
    
  4. Execute FFprobe commands.

    FFprobeKit.execute(ffprobeCommand).then((session) async {
    
      // CALLED WHEN SESSION IS EXECUTED
    
    });
    
  5. Get media information for a file/url.

    FFprobeKit.getMediaInformation('<file path or url>').then((session) async {
      final information = await session.getMediaInformation();
    
      if (information == null) {
    
        // CHECK THE FOLLOWING ATTRIBUTES ON ERROR
        final state = FFmpegKitConfig.sessionStateToString(await session.getState());
        final returnCode = await session.getReturnCode();
        final failStackTrace = await session.getFailStackTrace();
        final duration = await session.getDuration();
        final output = await session.getOutput();
      }
    });
    
  6. Stop ongoing FFmpeg operations.

  • Stop all sessions
    FFmpegKit.cancel();
    
  • Stop a specific session
    FFmpegKit.cancel(sessionId);
    
  1. (Android) Convert Storage Access Framework (SAF) Uris into paths that can be read or written by FFmpegKit and FFprobeKit.
  • Reading a file:

    FFmpegKitConfig.selectDocumentForRead('*/*').then((uri) {
      FFmpegKitConfig.getSafParameterForRead(uri!).then((safUrl) {
        FFmpegKit.executeAsync("-i ${safUrl!} -c:v mpeg4 file2.mp4");
      });
    });
    
  • Writing to a file:

    FFmpegKitConfig.selectDocumentForWrite('video.mp4', 'video/*').then((uri) {
      FFmpegKitConfig.getSafParameterForWrite(uri!).then((safUrl) {
        FFmpegKit.executeAsync("-i file1.mp4 -c:v mpeg4 ${safUrl}");
      });
    });
    
  1. Get previous FFmpeg, FFprobe and MediaInformation sessions from the session history.

    FFmpegKit.listSessions().then((sessionList) {
      sessionList.forEach((session) {
        final sessionId = session.getSessionId();
      });
    });
    
    FFprobeKit.listFFprobeSessions().then((sessionList) {
      sessionList.forEach((session) {
        final sessionId = session.getSessionId();
      });
    });
    
    FFprobeKit.listMediaInformationSessions().then((sessionList) {
      sessionList.forEach((session) {
        final sessionId = session.getSessionId();
      });
    });
    
  2. Enable global callbacks.

  • Session type specific Complete Callbacks, called when an async session has been completed

    FFmpegKitConfig.enableFFmpegSessionCompleteCallback((session) {
      final sessionId = session.getSessionId();
    });
    
    FFmpegKitConfig.enableFFprobeSessionCompleteCallback((session) {
      final sessionId = session.getSessionId();
    });
    
    FFmpegKitConfig.enableMediaInformationSessionCompleteCallback((session) {
      final sessionId = session.getSessionId();
    });
    
  • Log Callback, called when a session generates logs

    FFmpegKitConfig.enableLogCallback((log) {
      final message = log.getMessage();
    });
    
  • Statistics Callback, called when a session generates statistics

    FFmpegKitConfig.enableStatisticsCallback((statistics) {
      final size = statistics.getSize();
    });
    
  1. Register system fonts and custom font directories.

    FFmpegKitConfig.setFontDirectoryList(["/system/fonts", "/System/Library/Fonts", "<folder with fonts>"]);
    

4. Test Application

You can see how FFmpegKit is used inside an application by running flutter test applications developed under the FFmpegKit Test project.

5. Tips

See Tips wiki page.

6. License

See License wiki page.

7. Patents

See Patents wiki page.