Flutter-ffmpeg - FFmpeg plugin for Flutter. Not maintained anymore. Superseded by FFmpegKit.

Overview

flutter_ffmpeg

GitHub release

FFmpeg plugin for Flutter. Supports iOS and Android.

Not maintained anymore, superseded by FFmpegKit. See FlutterFFmpeg to FFmpegKit Migration Guide.

1. Features

  • Based on MobileFFmpeg

  • Includes both FFmpeg and FFprobe

  • Supports

    • Both Android and iOS

    • Both Android (API Level 16+) and iOS (SDK 9.3+)

    • FFmpeg v4.1, v4.2, v4.3 and v4.4-dev releases

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

    • armv7, armv7s, arm64, arm64e, i386 and x86_64 architectures on iOS

    • 25 external libraries

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

    • 4 external libraries with GPL license

      vid.stab, x264, x265, xvidcore

    • Concurrent execution

    • zlib and MediaCodec Android system libraries

    • bzip2, iconv, libuuid, zlib system libraries and AudioToolbox, VideoToolbox, AVFoundation system frameworks

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

2. Installation

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

dependencies:
  flutter_ffmpeg: ^0.4.2

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 flutter_ffmpeg 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 flutter_ffmpeg package with libvpx inside.

flutter_ffmpeg provides eight packages that include different sets of external libraries. These packages are named according to the external libraries included in them. Below you can see which libraries are enabled in each package.

min min-gpl https https-gpl audio video full full-gpl
external libraries - vid.stab
x264
x265
xvidcore
gmp
gnutls
gmp
gnutls
vid.stab
x264
x265
xvidcore
lame
libilbc
libvorbis
opencore-amr
opus
shine
soxr
speex
twolame
vo-amrwbenc
wavpack
fontconfig
freetype
fribidi
kvazaar
libaom
libass
libiconv
libtheora
libvpx
libwebp
snappy
fontconfig
freetype
fribidi
gmp
gnutls
kvazaar
lame
libaom
libass
libiconv
libilbc
libtheora
libvorbis
libvpx
libwebp
libxml2
opencore-amr
opus
shine
snappy
soxr
speex
twolame
vo-amrwbenc
wavpack
fontconfig
freetype
fribidi
gmp
gnutls
kvazaar
lame
libaom
libass
libiconv
libilbc
libtheora
libvorbis
libvpx
libwebp
libxml2
opencore-amr
opus
shine
snappy
soxr
speex
twolame
vid.stab
vo-amrwbenc
wavpack
x264
x265
xvidcore
android system libraries zlib
MediaCodec
ios system libraries zlib
AudioToolbox
AVFoundation
iconv
VideoToolbox
bzip2

Installation of FlutterFFmpeg using pub enables the default package, which is based on https package. It is possible to enable other flutter_ffmpeg packages using the following steps.

2.1.1 Android
  • Edit android/build.gradle file and specify the package name in ext.flutterFFmpegPackage variable.

    ext {
        flutterFFmpegPackage  = "<flutter ffmpeg package name listed in section 2.1>"
    }
    
    
2.1.2 iOS (Flutter >= 2.x)
  • Edit ios/Podfile, add the following block before target 'Runner do and specify the package name in <package name> section :

    # "fork" of method flutter_install_plugin_pods (in fluttertools podhelpers.rb) to get lts version of ffmpeg
    def flutter_install_plugin_pods(application_path = nil, relative_symlink_dir, platform)
      # defined_in_file is set by CocoaPods and is a Pathname to the Podfile.
      application_path ||= File.dirname(defined_in_file.realpath) if self.respond_to?(:defined_in_file)
      raise 'Could not find application path' unless application_path
    
      # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
      # referring to absolute paths on developers' machines.
    
      symlink_dir = File.expand_path(relative_symlink_dir, application_path)
      system('rm', '-rf', symlink_dir) # Avoid the complication of dependencies like FileUtils.
    
      symlink_plugins_dir = File.expand_path('plugins', symlink_dir)
      system('mkdir', '-p', symlink_plugins_dir)
    
      plugins_file = File.join(application_path, '..', '.flutter-plugins-dependencies')
      plugin_pods = flutter_parse_plugins_file(plugins_file, platform)
      plugin_pods.each do |plugin_hash|
        plugin_name = plugin_hash['name']
        plugin_path = plugin_hash['path']
        if (plugin_name && plugin_path)
          symlink = File.join(symlink_plugins_dir, plugin_name)
          File.symlink(plugin_path, symlink)
    
          if plugin_name == 'flutter_ffmpeg'
            pod 'flutter_ffmpeg/<package name>', :path => File.join(relative_symlink_dir, 'plugins', plugin_name, platform)
          else
            pod plugin_name, :path => File.join(relative_symlink_dir, 'plugins', plugin_name, platform)
          end
        end
      end
    end
    
2.1.3 iOS (Flutter >= 1.20.x) && (Flutter < 2.x)
  • Edit ios/Podfile, add the following block before target 'Runner do and specify the package name in <package name> section :

    # "fork" of method flutter_install_ios_plugin_pods (in fluttertools podhelpers.rb) to get lts version of ffmpeg
    def flutter_install_ios_plugin_pods(ios_application_path = nil)
      # defined_in_file is set by CocoaPods and is a Pathname to the Podfile.
      ios_application_path ||= File.dirname(defined_in_file.realpath) if self.respond_to?(:defined_in_file)
      raise 'Could not find iOS application path' unless ios_application_path
    
      # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
      # referring to absolute paths on developers' machines.
    
      symlink_dir = File.expand_path('.symlinks', ios_application_path)
      system('rm', '-rf', symlink_dir) # Avoid the complication of dependencies like FileUtils.
    
      symlink_plugins_dir = File.expand_path('plugins', symlink_dir)
      system('mkdir', '-p', symlink_plugins_dir)
    
      plugins_file = File.join(ios_application_path, '..', '.flutter-plugins-dependencies')
      plugin_pods = flutter_parse_plugins_file(plugins_file)
      plugin_pods.each do |plugin_hash|
        plugin_name = plugin_hash['name']
        plugin_path = plugin_hash['path']
    
        if (plugin_name && plugin_path)
          symlink = File.join(symlink_plugins_dir, plugin_name)
          File.symlink(plugin_path, symlink)
    
          if plugin_name == 'flutter_ffmpeg'
            pod plugin_name+'/<package name>', :path => File.join('.symlinks', 'plugins', plugin_name, 'ios')
          else
            pod plugin_name, :path => File.join('.symlinks', 'plugins', plugin_name, 'ios')
          end
        end
      end
    end
    
  • Ensure that flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) function is called within target 'Runner' do block. In that case, it is mandatory that the added function is named flutter_install_ios_plugin_pods and that you do not make an explicit call within that block.

2.1.4 iOS (Flutter < 1.20.x)
  • Edit ios/Podfile file and modify the default # Plugin Pods block as follows. Do not forget to specify the package name in <package name> section.

    # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
    # referring to absolute paths on developers' machines.
    system('rm -rf .symlinks')
    system('mkdir -p .symlinks/plugins')
    plugin_pods = parse_KV_file('../.flutter-plugins')
    plugin_pods.each do |name, path|
      symlink = File.join('.symlinks', 'plugins', name)
      File.symlink(path, symlink)
      if name == 'flutter_ffmpeg'
        pod name+'/<package name>', :path => File.join(symlink, 'ios')
      else
        pod name, :path => File.join(symlink, 'ios')
      end
    end
    
2.1.5 Package Names

The following table shows all package names defined for flutter_ffmpeg.

Package Main Release LTS Release
min min min-lts
min-gpl min-gpl min-gpl-lts
https https https-lts
https-gpl https-gpl https-gpl-lts
audio audio audio-lts
video video video-lts
full full full-lts
full-gpl full-gpl full-gpl-lts

2.2 Existing Applications

It is possible to add flutter_ffmpeg to existing applications using Add-to-App guide.

Please execute the following additional steps if you are integrating into an iOS application.

  1. Go to Build Phases of Pods -> FlutterPluginRegistrant target and add all frameworks under the Pods/mobile-ffmpeg-<package name> directory to the Link Binary With Libraries section

  2. Go to Build Phases of Pods -> FlutterPluginRegistrant target and add all system libraries/frameworks listed in Step 4 of Importing-Frameworks guide to the Link Binary With Libraries section

  3. Go to Build Phases of Pods -> FlutterPluginRegistrant target and add AVFoundation system framework to the Link Binary With Libraries section

2.3 LTS Releases

flutter_ffmpeg is published in two different variants: Main Release and LTS Release. Both releases share the same source code but is built with different settings. Below you can see the differences between the two.

In order to install the LTS variant, install the https-lts package using instructions in 2.1 or append -lts to the package name you are using.

Main Release LTS Release
Android API Level 24 16
Android Camera Access Yes -
Android Architectures arm-v7a-neon
arm64-v8a
x86
x86-64
arm-v7a
arm-v7a-neon
arm64-v8a
x86
x86-64
Xcode Support 10.1 7.3.1
iOS SDK 11.0 9.3
iOS AVFoundation Yes -
iOS Architectures arm64
x86-64
x86-64-mac-catalyst
armv7
arm64
i386
x86-64

3. Using

  1. Execute synchronous FFmpeg commands.

    • Use execute() method with a single command line
    import 'package:flutter_ffmpeg/flutter_ffmpeg.dart';
    
    final FlutterFFmpeg _flutterFFmpeg = new FlutterFFmpeg();
    
    _flutterFFmpeg.execute("-i file1.mp4 -c:v mpeg4 file2.mp4").then((rc) => print("FFmpeg process exited with rc $rc"));
    
    • Use executeWithArguments() method with an array of arguments
    import 'package:flutter_ffmpeg/flutter_ffmpeg.dart';
    
    final FlutterFFmpeg _flutterFFmpeg = new FlutterFFmpeg();
    
    var arguments = ["-i", "file1.mp4", "-c:v", "mpeg4", "file2.mp4"];
    _flutterFFmpeg.executeWithArguments(arguments).then((rc) => print("FFmpeg process exited with rc $rc"));
    
  2. Execute asynchronous FFmpeg commands.

    _flutterFFmpeg.executeAsync(ffmpegCommand, (CompletedFFmpegExecution execution) {
      print("FFmpeg process for executionId ${execution.executionId} exited with rc ${execution.returnCode}");
    }).then((executionId) => print("Async FFmpeg process started with executionId $executionId."));
    
  3. Execute FFprobe commands.

    • Use execute() method with a single command line
    import 'package:flutter_ffmpeg/flutter_ffmpeg.dart';
    
    final FlutterFFprobe _flutterFFprobe = new FlutterFFprobe();
    
    _flutterFFprobe.execute("-i file1.mp4").then((rc) => print("FFprobe process exited with rc $rc"));
    
    • Use executeWithArguments() method with an array of arguments
    import 'package:flutter_ffmpeg/flutter_ffmpeg.dart';
    
    final FlutterFFprobe _flutterFFprobe = new FlutterFFprobe();
    
    var arguments = ["-i", "file1.mp4"];
    _flutterFFprobe.executeWithArguments(arguments).then((rc) => print("FFprobe process exited with rc $rc"));
    
  4. Check execution output. Zero represents successful execution, 255 means user cancel and non-zero values represent failure.

    
    final FlutterFFmpegConfig _flutterFFmpegConfig = new FlutterFFmpegConfig();
    
    _flutterFFmpegConfig.getLastReturnCode().then((rc) => print("Last rc: $rc"));
    
    _flutterFFmpegConfig.getLastCommandOutput().then((output) => print("Last command output: $output"));
    
  5. Stop ongoing FFmpeg operations. Note that these two functions do not wait for termination to complete and return immediately.

    • Stop all executions
      _flutterFFmpeg.cancel();
      
    • Stop a specific execution
      _flutterFFmpeg.cancelExecution(executionId);
      
  6. Get media information for a file.

    • Print all fields
    final FlutterFFprobe _flutterFFprobe = new FlutterFFprobe();
    
    _flutterFFprobe.getMediaInformation("<file path or uri>").then((info) => print(info));
    
    • Print selected fields
    final FlutterFFprobe _flutterFFprobe = new FlutterFFprobe();
    
    _flutterFFprobe.getMediaInformation("<file path or uri>").then((info) {
        print("Media Information");
    
        print("Path: ${info.getMediaProperties()['filename']}");
        print("Format: ${info.getMediaProperties()['format_name']}");
        print("Duration: ${info.getMediaProperties()['duration']}");
        print("Start time: ${info.getMediaProperties()['start_time']}");
        print("Bitrate: ${info.getMediaProperties()['bit_rate']}");
        Map<dynamic, dynamic> tags = info.getMediaProperties()['tags'];
        if (tags != null) {
            tags.forEach((key, value) {
                print("Tag: " + key + ":" + value + "\n");
            });
        }
    
        if (info.getStreams() != null) {
            List<StreamInformation> streams = info.getStreams();
    
            if (streams.length > 0) {
                for (var stream in streams) {
                    print("Stream id: ${stream.getAllProperties()['index']}");
                    print("Stream type: ${stream.getAllProperties()['codec_type']}");
                    print("Stream codec: ${stream.getAllProperties()['codec_name']}");
                    print("Stream full codec: ${stream.getAllProperties()['codec_long_name']}");
                    print("Stream format: ${stream.getAllProperties()['pix_fmt']}");
                    print("Stream width: ${stream.getAllProperties()['width']}");
                    print("Stream height: ${stream.getAllProperties()['height']}");
                    print("Stream bitrate: ${stream.getAllProperties()['bit_rate']}");
                    print("Stream sample rate: ${stream.getAllProperties()['sample_rate']}");
                    print("Stream sample format: ${stream.getAllProperties()['sample_fmt']}");
                    print("Stream channel layout: ${stream.getAllProperties()['channel_layout']}");
                    print("Stream sar: ${stream.getAllProperties()['sample_aspect_ratio']}");
                    print("Stream dar: ${stream.getAllProperties()['display_aspect_ratio']}");
                    print("Stream average frame rate: ${stream.getAllProperties()['avg_frame_rate']}");
                    print("Stream real frame rate: ${stream.getAllProperties()['r_frame_rate']}");
                    print("Stream time base: ${stream.getAllProperties()['time_base']}");
                    print("Stream codec time base: ${stream.getAllProperties()['codec_time_base']}");
    
                    Map<dynamic, dynamic> tags = stream.getAllProperties()['tags'];
                    if (tags != null) {
                      tags.forEach((key, value) {
                        print("Stream tag: " + key + ":" + value + "\n");
                      });
                    }
                }
            }
        }
    });
    
  7. Enable log callback and redirect all FFmpeg/FFprobe logs to a console/file/widget.

    void logCallback(Log log) {
        print("${log.executionId}:${log.message}");
    }
    ...
    _flutterFFmpegConfig.enableLogCallback(this.logCallback);
    
  8. Enable statistics callback and follow the progress of an ongoing FFmpeg operation.

    void statisticsCallback(Statistics statistics) {
        print("Statistics: executionId: ${statistics.executionId}, time: ${statistics.time}, size: ${statistics.size}, bitrate: ${statistics.bitrate}, speed: ${statistics.speed}, videoFrameNumber: ${statistics.videoFrameNumber}, videoQuality: ${statistics.videoQuality}, videoFps: ${statistics.videoFps}");
    }
    ...
    _flutterFFmpegConfig.enableStatisticsCallback(this.statisticsCallback);
    
  9. Poll statistics without implementing statistics callback.

    _flutterFFmpegConfig.getLastReceivedStatistics().then((stats) => print(stats));
    
  10. List ongoing executions.

    _flutterFFmpeg.listExecutions().then((ffmpegExecutions) {
      ffmpegExecutions.forEach((execution) {
        ffprint(
            "Execution id:${execution.executionId}, startTime:${execution.command}, command:${execution.startTime}.");
      });
    });
    
  11. Set log level.

    _flutterFFmpegConfig.setLogLevel(LogLevel.AV_LOG_WARNING);
    
  12. Register your own fonts by specifying a custom fonts directory, so they are available to use in FFmpeg filters. Please note that this function can not work on relative paths, you need to provide full file system path.

    _flutterFFmpegConfig.setFontDirectory("<folder with fonts>");
    
  13. Use your own fontconfig configuration.

    _flutterFFmpegConfig.setFontconfigConfigurationPath("<fontconfig configuration directory>");
    
  14. Disable log functionality of the library. Logs will not be printed to console and log callback will be disabled.

    _flutterFFmpegConfig.disableLogs();
    
  15. Disable statistics functionality of the library. Statistics callback will be disabled but the last received statistics data will be still available.

    _flutterFFmpegConfig.disableStatistics();
    
  16. Create new FFmpeg pipe.

    _flutterFFmpegConfig.registerNewFFmpegPipe().then((path) {
         then((stats) => print("New ffmpeg pipe at $path"));
    });
    

4. Example Application

You can see how FlutterFFmpeg is used inside an application by running example application provided under the example folder. It supports command execution, video encoding, accessing https, encoding audio, burning subtitles, video stabilisation, pipe operations and concurrent command execution.

5. Tips

  • flutter_ffmpeg uses file system paths, it does not know what an assets folder or a project folder is. So you can't use resources on those folders directly, you need to provide full paths of those resources.

  • flutter_ffmpeg requires ios deployment target to be at least 11.0 for Main releases and 9.3 for LTS releases. If you don't specify a deployment target or set a value smaller than the required one then your build may fail with the following error.

     Resolving dependencies of `Podfile`
     [!] CocoaPods could not find compatible versions for pod "flutter_ffmpeg":
       In Podfile:
         flutter_ffmpeg (from `.symlinks/plugins/flutter_ffmpeg/ios`)
     
     Specs satisfying the `flutter_ffmpeg (from `.symlinks/plugins/flutter_ffmpeg/ios`)` dependency were found, but they required a higher minimum
     deployment target.
    

    You can fix this issue by adding the following definition to your ios/Podfile file.

    • Main releases
    platform :ios, '11.0'
    
    • LTS releases
    platform :ios, '9.3'
    
  • If flutter_ffmpeg release builds on Android fail with the following exception, make sure that mavenCentral() is defined as a repository in your build.gradle and it is listed before jcenter().

    E/flutter (14793): [ERROR:flutter/shell/platform/android/platform_view_android_jni_impl.cc(43)] java.lang.UnsatisfiedLinkError: Bad JNI version returned from JNI_OnLoad in "/data/app/com.arthenica.flutter.ffmpeg.FlutterFFmpegExample-DV2qVHHlZArnXoQYMowxVQ==/base.apk!/lib/arm64-v8a/libmobileffmpeg.so": 0
    E/flutter (14793): 	at java.lang.Runtime.loadLibrary0(Runtime.java:1071)
    E/flutter (14793): 	at java.lang.Runtime.loadLibrary0(Runtime.java:1007)
    E/flutter (14793): 	at java.lang.System.loadLibrary(System.java:1668)
    E/flutter (14793): 	at com.arthenica.mobileffmpeg.Config.<clinit>(Unknown Source:148)
    E/flutter (14793): 	at com.arthenica.mobileffmpeg.Config.c(Unknown Source:0)
    E/flutter (14793): 	at b.a.a.a.d.onMethodCall(Unknown Source:323)
    E/flutter (14793): 	at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(Unknown Source:17)
    E/flutter (14793): 	at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(Unknown Source:57)
    E/flutter (14793): 	at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(Unknown Source:4)
    E/flutter (14793): 	at android.os.MessageQueue.nativePollOnce(Native Method)
    E/flutter (14793): 	at android.os.MessageQueue.next(MessageQueue.java:363)
    E/flutter (14793): 	at android.os.Looper.loop(Looper.java:173)
    E/flutter (14793): 	at android.app.ActivityThread.main(ActivityThread.java:8178)
    E/flutter (14793): 	at java.lang.reflect.Method.invoke(Native Method)
    E/flutter (14793): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
    E/flutter (14793): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
    E/flutter (14793):
    F/flutter (14793): [FATAL:flutter/shell/platform/android/platform_view_android_jni_impl.cc(942)] Check failed: CheckException(env).
    
  • flutter_ffmpeg includes native libraries that require ios deployment target to be at least 9.3. If a deployment target is not set or a value smaller than 9.3 is used then your build will fail with the following error.

    ld: targeted OS version does not support use of thread local variables in __gnutls_rnd_deinit for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    

    Some versions of Flutter and Cocoapods have issues about setting ios deployment target from Podfile. On those versions, having platform :ios, '9.3' in your Podfile is not enough. Runner project still uses the default value 8.0. You need to open Runner.xcworkspace in Xcode and set iOS Deployment Target of Runner project to 9.3 manually or create a new project.

  • Enabling ProGuard on releases older than v0.2.4 causes linking errors. Please add the following rule inside your proguard-rules.pro file to preserve necessary method names and prevent linking errors.

    -keep class com.arthenica.mobileffmpeg.Config {
        native <methods>;
        void log(int, byte[]);
        void statistics(int, float, float, long , int, double, double);
    }
    
  • ffmpeg requires a valid fontconfig configuration to render subtitles. Unfortunately, Android does not include a default fontconfig configuration. So, if you do not register a font or specify a fontconfig configuration under Android, then the burning process will not produce any errors but subtitles won't be burned in your file. You can overcome this behaviour by registering a font using setFontDirectory method or specifying your own fontconfig configuration using setFontconfigConfigurationPath method.

  • By default, Xcode compresses PNG files during packaging. If you use .png files in your commands make sure you set the following two settings to NO. If one of them is set to YES, your operations may fail with Error while decoding stream #0:0: Generic error in an external library error.

  • Some flutter_ffmpeg packages include libc++_shared.so native library. If a second library which also includes libc++_shared.so is added as a dependency, gradle fails with More than one file was found with OS independent path 'lib/x86/libc++_shared.so' error message.

    You can fix this error by adding the following block into your build.gradle.

    android {
        packagingOptions {
            pickFirst 'lib/x86/libc++_shared.so'
            pickFirst 'lib/x86_64/libc++_shared.so'
            pickFirst 'lib/armeabi-v7a/libc++_shared.so'
            pickFirst 'lib/arm64-v8a/libc++_shared.so'
        }
    }
    

6. Updates

Refer to Changelog for updates.

7. License

This project is licensed under the LGPL v3.0. However, if installation is customized to use a package with -gpl postfix (min-gpl, https-gpl, full-gpl) then FlutterFFmpeg is subject to the GPL v3.0 license.

In test application; embedded fonts are licensed under the SIL Open Font License, other digital assets are published in the public domain.

8. Patents

It is not clearly explained in their documentation but it is believed that FFmpeg, kvazaar, x264 and x265 include algorithms which are subject to software patents. If you live in a country where software algorithms are patentable then you'll probably need to pay royalty fees to patent holders. We are not lawyers though, so we recommend that you seek legal advice first. See FFmpeg Patent Mini-FAQ.

9. Contributing

Feel free to submit issues or pull requests.

Please note that master branch includes only the latest released source code. Changes planned for the next release are implemented under the development branch. Therefore, if you want to create a pull request, please open it against the development.

10. See Also

Comments
  • [FEATURE] Add Support for macOS, Windows, Linux, Web

    [FEATURE] Add Support for macOS, Windows, Linux, Web

    Description New Feature Request

    I think it would be great if the plugin supports all the other platforms that Flutter supports.

    Windows is a little bit behind but the others work like a charm. I think it would open new possibilities.

    enhancement wontfix 
    opened by YazeedAlKhalaf 34
  • Execution time difference between Flutter_FFMPEG(mobile-ffmpeg) and flutter_video_compress(ffmpeg-android)

    Execution time difference between Flutter_FFMPEG(mobile-ffmpeg) and flutter_video_compress(ffmpeg-android)

    Hi, Thanks for Flutter FFMPEG and its underlying library mobile-ffmpeg in android. I was earlier using flutter_video_compress which uses FFMPEG-android but the problem with that library is that's dead, don't support android 10 due to behavior change in android 10 and doesn't have 64 bit binaries for FFMPEG. I tried running same FFMPEG command for compression in both libraries flutter_video_compress and Flutter_FFMPEG which is as follows:

    "-i $newPath -vcodec h264 -crf 24 -vf scale=720:-2 -preset:v ultrafast $newPathCompressed"

    The same command takes 8-9 minute to compress 260MB video to 30MB in Flutter_FFMPEG package but takes 2-3 minutes to compress the same video to roughly 30MB in flutter_video_compress package. The limiting factor is scale, so if I add scale for video compression in ffmpeg command using Flutter_FFMPEG package then time increases substantially from 2-3 minutes to 8-9 minutes but doesn't increase in flutter_video_compress. I want to use flutter_ffmpeg package as the flutter_video_compress is dead and not maintained but the only thing stopping me right now is the substantial time difference for execution of FFMPEG commands in both packages. It would be great if you can comment on the reason for substantial time difference for FFMPEG command execution in both packages as it's beyond my understanding. According to my understanding, Flutter_FFMPEG and mobile-ffmpeg would be using latest versions of FFMPEG as compared to that used by flutter_video_compress and ffmpeg-android.

    enhancement fixed 
    opened by pranavkpr1 31
  • How to pipe ffmpeg output to video_player flutter widget

    How to pipe ffmpeg output to video_player flutter widget

    I have given a local file to ffmpeg and added some complex filters to it. Now i want to pipe that output to my video_player flutter widget so that i can view it in real time.

    question no-issue-activity 
    opened by premingiet 29
  • [ENH] Web support

    [ENH] Web support

    Hi @tanersener , Hi everybody,

    I am the Flutter Sound main maintainer, and today someone post something about the need of FFmpeg on Flutter Web. I think that several people already ported FFmpeg to javascript, using webassembly and Emscripten. Is there any reason for Flutter FFmpeg not being supported on Flutter Web ? Will you be interested by someone (me?) doing this port and do a Pull Request, in the next few weeks ?

    Thank you again for this terrific project.

    duplicate enhancement wontfix 
    opened by Larpoux 23
  • fatal error: 'mobileffmpeg/LogDelegate.h' file not found

    fatal error: 'mobileffmpeg/LogDelegate.h' file not found

    I am running into this issue in the title when running: flutter build ios --release

    2 warnings generated.
        In file included from
        /Users/eugene/Documents/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_ffmpeg-0.4.0
        /ios/Classes/EmptyLogDelegate.m:20:
        /Users/eugene/Documents/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_ffmpeg-0.4.0
        /ios/Classes/EmptyLogDelegate.h:20:10: fatal error: 'mobileffmpeg/LogDelegate.h' file
        not found
        #include <mobileffmpeg/LogDelegate.h>
    

    Ive seen the following: https://github.com/tanersener/flutter-ffmpeg/issues/210 https://github.com/tanersener/flutter-ffmpeg/issues/212 Ive tried

    rm -rf ~/Library/Caches/CocoaPods
    rm -rf Pods
    rm -rf ~/Library/Developer/Xcode/DerivedData/*
    pod deintegrate
    pod setup
    pod install
    flutter build ios --release
    

    None of it has worked and I am not sure why its not working. Any insight would be helpful

    question no-issue-activity 
    opened by eugrro 23
  • Apk size will be huge after adding flutter_ffmpeg package

    Apk size will be huge after adding flutter_ffmpeg package

    Hello, my apk size is 19MB, but after adding flutter_ffmpeg package with package name min it will be 60MB and 51MB with package name min-lts. How i can do to decrement my apk size? please help me

    Note: I want to use flutter_ffmpeg only for compress my audio to OPUS file

    here my example: All work fine, but my problem only with apk size will be up to 50MB.

     executeFFMPEG() async {
        try {
          final FlutterFFmpeg _flutterFFmpeg = new FlutterFFmpeg();
    
          String uuid = DateTime.now().millisecondsSinceEpoch.toString();
    
          String outputPath = '/output_audio_ffmpe$uuid.opus';
          io.Directory appDocDirectory;
          if (io.Platform.isIOS) {
            appDocDirectory = await getApplicationDocumentsDirectory();
          } else {
            appDocDirectory = await getExternalStorageDirectory();
          }
    
          outputPath = appDocDirectory.path + outputPath;
    
          _flutterFFmpeg.execute("-i ${_recording.path} -c:a opus -strict -2 $outputPath")
              .whenComplete(() {
            setState(() {
              outputPathFFMPEG = outputPath;
              sendToDB();
            });
          }).then((rc) => print("FFmpeg process exited with rc $rc"));
    
          print("File FFMPEG Converted $outputPath");
        } catch (e) {
          print("Try Catch for FFMPEG Execution $e");
        }
      }
    
    
    question no-issue-activity 
    opened by Malloumabba1 18
  • Crash on iOS

    Crash on iOS

    The app is crashing sometimes in iOS when I call getMediaInformation(path). And it has no error message, it just totally crash. It's working fine in android.

    Future<Map<dynamic, dynamic>> getMediaInformation(String path) async {
        return await _flutterFFmpeg.getMediaInformation(path);
      }
    
    needs-analysis 
    opened by gerry05 17
  • can't run on iOS, getting error on flutter run ?

    can't run on iOS, getting error on flutter run ?

    In file included from /Users/user/Softwares/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_ffmpeg-0.3.0/ios/Classes/EmptyLogDelegate.m:20: /Users/user/Softwares/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_ffmpeg-0.3.0/ios/Classes/EmptyLogDelegate.h:20:10: fatal error: 'mobileffmpeg/LogDelegate.h' file not found #include <mobileffmpeg/LogDelegate.h> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 error generated.

    question 
    opened by dubeyteja 16
  • JNI DETECTED ERROR IN APPLICATION in ffmpeg flutter

    JNI DETECTED ERROR IN APPLICATION in ffmpeg flutter

    Errors:

    Syncing files to device vivo Y21L... I/flutter (21932): Loading flutter-ffmpeg. I/OpenGLRenderer(21932): Initialized EGL, version 1.4 I/mobile-ffmpeg(21932): Loading mobile-ffmpeg. W/linker (21932): libmobileffmpeg-abidetect.so: unused DT entry: type 0x6ffffffe arg 0x694 W/linker (21932): libmobileffmpeg-abidetect.so: unused DT entry: type 0x6fffffff arg 0x1 W/linker (21932): libcpufeatures.so: unused DT entry: type 0x6ffffffe arg 0x7d0 W/linker (21932): libcpufeatures.so: unused DT entry: type 0x6fffffff arg 0x2 W/linker (21932): libmobileffmpeg-armv7a-neon.so: unused DT entry: type 0x6ffffffe arg 0x6290 W/linker (21932): libmobileffmpeg-armv7a-neon.so: unused DT entry: type 0x6fffffff arg 0xa W/linker (21932): libc++_shared.so: unused DT entry: type 0x6ffffffe arg 0x2b994 W/linker (21932): libc++_shared.so: unused DT entry: type 0x6fffffff arg 0x2 W/linker (21932): libavcodec.so: unused DT entry: type 0x6ffffffe arg 0x6538 W/linker (21932): libavcodec.so: unused DT entry: type 0x6fffffff arg 0x4 W/linker (21932): libavfilter.so: unused DT entry: type 0x6ffffffe arg 0x44f4 W/linker (21932): libavfilter.so: unused DT entry: type 0x6fffffff arg 0x7 W/linker (21932): libswscale.so: unused DT entry: type 0x6ffffffe arg 0xe94 W/linker (21932): libswscale.so: unused DT entry: type 0x6fffffff arg 0x3 W/linker (21932): libavformat.so: unused DT entry: type 0x6ffffffe arg 0x7414 W/linker (21932): libavformat.so: unused DT entry: type 0x6fffffff arg 0x4 W/linker (21932): libavutil.so: unused DT entry: type 0x6ffffffe arg 0x6d84 W/linker (21932): libavutil.so: unused DT entry: type 0x6fffffff arg 0x2 W/linker (21932): libswresample.so: unused DT entry: type 0x6ffffffe arg 0xe2c W/linker (21932): libswresample.so: unused DT entry: type 0x6fffffff arg 0x3 W/linker (21932): libavdevice.so: unused DT entry: type 0x6ffffffe arg 0x1448 W/linker (21932): libavdevice.so: unused DT entry: type 0x6fffffff arg 0x5 I/mobile-ffmpeg(21932): Loaded mobile-ffmpeg-https-arm-v7a-neon-4.2-lts. I/flutter (21932): Loaded flutter-ffmpeg-android-arm-v7a-neon. D/mobile-ffmpeg(21932): Callback thread started. D/flutter-ffmpeg(21932): Running FFmpeg command: -i File: '/storage/emulated/0/video_5.mp4'.mp4 -ss 00:00:01.000 -vframes 1 recordedImage.jpg with delimiter . I/Timeline(21932): Timeline: Activity_idle id: [email protected] time:113811921 D/flutter-ffmpeg(21932): FFmpeg exited with rc: 1 F/art (21932): art/runtime/check_jni.cc:65] JNI DETECTED ERROR IN APPLICATION: JNI NewByteArray called with pending exception 'java.lang.RuntimeException' thrown in unknown throw location F/art (21932): art/runtime/check_jni.cc:65] in call to NewByteArray

    My Code:

    void _pickVideo() async { ImagePicker.pickVideo(source: ImageSource.gallery) .then((File recordedVideo) { if (recordedVideo != null && recordedVideo.path != null) { setState(() { secondButtonText = 'saving in progress...'; File recordedImage; _flutterFFmpeg .execute( "-ss 00:1:45 -i $recordedVideo -vframes 1 -q:v 2 $recordedImage.jpg") .then((rc) => print("FFmpeg process exited with rc $rc")); GallerySaver.saveImage(recordedImage.path).then((path) { setState(() { firstButtonText = 'image saved!'; }); }); }); GallerySaver.saveVideo(recordedVideo.path).then((path) { setState(() { secondButtonText = 'video saved!'; }); }); } }); }

    Sir I am using ffmpeg package in my testapp project I want to select a video from my phone storage and extract one frame at a given time from it and save it to my phone storage. I am using Gallery Saver package it works for saving photos and video but for my specific task it does this error shows in output Every time i run the code rc exited : 1 comes and then the above error. App directly crashes after that. Please Help me Sir!!

    question 
    opened by shubham12387 16
  • iOS crash when using _flutterFFmpeg.getMediaInformation

    iOS crash when using _flutterFFmpeg.getMediaInformation

    Description app crashes on physical iPhone X (didnt try emulator) when app is gathering video file info using getMediaInformation(). it works fine on android. commenting out the call to getMediaInformation() and just using _flutterFFmpeg.execute() works perfectly fine (no crashes). not sure if it helps, but _flutterFFmpeg.enableStatisticsCallback() works perfectly fine too.

    Expected behavior getMediaInformation() would return meta-info about the video without crashing.

    Current behavior the app hard crashes. it immediately stops outputting errors/debugging to terminal and i get a "Lost connection to device."

    Screenshots If applicable, add screenshots to help explain your problem.

    Logs Post logs here or paste them to Ghostbin and insert the link here.

    Environment [✓] Flutter (Channel stable, v1.9.1+hotfix.6, on Mac OS X 10.15 19A603, locale en-US) • Flutter version 1.9.1+hotfix.6 at /Users/jimmy/Desktop/flutter • Framework revision 68587a0916 (9 weeks ago), 2019-09-13 19:46:58 -0700 • Engine revision b863200c37 • Dart version 2.5.0

    [!] Android toolchain - develop for Android devices (Android SDK version 29.0.2) • Android SDK at /Users/jimmy/Library/Android/sdk • Android NDK location not configured (optional; useful for native profiling support) • Platform android-29, build-tools 29.0.2 • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405) ! Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses

    [✓] Xcode - develop for iOS and macOS (Xcode 11.1) • Xcode at /Applications/Xcode.app/Contents/Developer • Xcode 11.1, Build version 11A1027 • CocoaPods version 1.8.4

    [✓] Android Studio (version 3.5) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin version 40.2.2 • Dart plugin version 191.8593 • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)

    [!] Connected device ! No devices available

    ! Doctor found issues in 2 categories.

    Other This seems to be the same issue that user "lukepighetti" referenced in issue: #48

    however, that issue was closed due to users no longer needing the fix.

    In the other issue (#48), i saw you asked for info from the "debug navigator" when running the project inside x code. I'm not sure how to do that? I just do a "flutter run" within the project within terminal. could you give simple instructions on how to do the x code debugging part?

    Worth mentioning again, this same code works perfectly on android.

    Thanks!

    question 
    opened by jam33 16
  • Getting standard output

    Getting standard output

    Currently, getLastCommandOutput() returns ffmpeg's error output, but AFAIK there is no way to get the standard (raw) output. This would be useful in order to convert a file to a memory buffer instead of having to write it to a temporary file just to read the file again.

    enhancement question fixed 
    opened by nbros 16
Releases(v0.4.2)
  • v0.4.2(Aug 5, 2021)

  • v0.4.1(Aug 5, 2021)

  • v0.4.0(Mar 13, 2021)

    Feature release based on ffmpeg v4.4.

    • Migrated to nullsafety
    • Fixes issue #246 and #266
    • Adds closeFFmpegPipe method to close pipes
    • Updated example application
    Source code(tar.gz)
    Source code(zip)
  • v0.3.1(Feb 8, 2021)

  • v0.3.0(Sep 20, 2020)

    Features release based on ffmpeg v4.4.

    • Uses thread pool executor to process Android executions
    • Adds listExecutions API method
    • Implements async FFmpeg execution methods
    • LogCallback and StatisticsCallback functions updated with executionId
    • Updates getMediaInformation implementation
    • Adds setEnvironmentVariable API method
    • Depends on mobile-ffmpeg v4.4
    • Allows modifying mobile-ffmpeg version for android
    • Includes an updated example application
    • Fixes issue #115, #120, #157, #159, #170, #178 and #202
    Source code(tar.gz)
    Source code(zip)
  • v0.2.10(Jan 19, 2020)

  • v0.2.9(Jan 19, 2020)

    Feature release.

    Features

    • Implements FFprobe
    • Add concurrent execution support
    • Re-organises plugin classes
    • iOS releases depend on iconv system library instead of iconv external library

    This release is not backward compatible with previous versions.

    Source code(tar.gz)
    Source code(zip)
  • v0.2.8(Oct 28, 2019)

  • v0.2.7(Jul 22, 2019)

  • v0.2.6(Jul 17, 2019)

  • v0.2.5(Jul 17, 2019)

  • v0.2.4(Jul 5, 2019)

    Maintenance release.

    Features

    • Adds support for Android devices with API Level 16+
    • Fixes issues #21 and #36
    • Removes conflicting attributes from AndroidManifest.xml
    • Includes ProGuard configuration file inside
    Source code(tar.gz)
    Source code(zip)
  • v0.2.3(Jun 20, 2019)

  • v0.2.2(Jun 20, 2019)

  • v0.2.1(Apr 4, 2019)

  • v0.2.0(Apr 4, 2019)

  • v0.1.1(Jan 8, 2019)

  • v0.1.0(Jan 7, 2019)

Owner
Taner Şener
Software Engineer
Taner Şener
Flutter video compress - Generate a new file by compressed video, and provide metadata. Get video thumbnail from a video path, supports JPEG/GIF. To reduce app size not using FFmpeg in IOS.

flutter_video_compress Generate a new path by compressed video, Choose to keep the source video or delete it by a parameter. Get video thumbnail from

天海るり 173 Sep 9, 2022
A collection of useful packages maintained by the Flutter team

Flutter Packages This repo is a companion repo to the main flutter repo. It contains the source code for Flutter's first-party packages (i.e., package

Flutter 2k Sep 13, 2022
Dumbo - A collection of all dumb stuff at one place, this repo is to be maintained for people who just simply are taking break from huge stuff and practicing something.

dumbo A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if this is

Krish Bhanushali 1 Jan 3, 2022
Actively maintained, community-driven Firebase BaaS for chat applications with an optional chat UI.

Flutter Firebase Chat Core Actively maintained, community-driven Firebase BaaS for chat applications with an optional chat UI. Flyer Chat is a platfor

Flyer Chat 155 Sep 12, 2022
A flutter plugin to draw the coordinates on the widget and as well as to find the given point is inside a list of coordinates or not.

Draw On A flutter plugin to draw the coordinates on widget and as well as to find the given point is inside a list of coordinates or not. For Draw on

Sivaramsiva10 4 Apr 5, 2022
Starter app for Flutter that includes many different production app features; some not typically included in demo apps.

first_app: Starter app for a Flutter production app Maintainer: Greger Wedel, https://github.com/gregertw Listed on: Latest build and artifacts: ** La

Greger Teigre Wedel 359 Sep 6, 2022
An isolated worker for Flutter (Isolate) and Web (Web Worker). Behaves almost the same as the compute function, except it is not a one-off worker.

A singleton isolated worker for all platforms. On most platforms, it uses Flutter's Isolate, except on the web, since Isolate is not available, it use

Iandi Santulus 27 Aug 17, 2022
Flutter package to hide out whole application or sections if you are not paid for the job done.

not_paid Worried about your payment? Using this package you can provide a non paid version of your app to the client that consistently starts fading o

hd-motion 11 Nov 30, 2021
A flutter app which calculate your heart beat and takes few inputs and predict whether you have heart disease or not.

Heart Care App ?? ?? ❤️ ⭐️ Features: ⚡️ Lets you sign up and login ⚡️ Montioring your heart failure risk and heart beat through charts ⚡️ View Medical

HINA KHADIM 7 Aug 15, 2022
Push Notification service for anime episodes and news. The episode updates will be based on actual upload on the internet and NOT Japan tv schedule as other apps do.

Quantz Push Notification service for anime episodes and news. Features Sub and dub - get notified with latest anime episodes on the internet. Ongoing

null 15 Aug 3, 2022
Gallery with thousands of photos, no time to organize, no way to search and not enough space

Artificial Intelligence-Powered Gallery Overview Gallery with thousands of photos, no time to organize, no way to search and not enough space; these a

Abd al-Rahman al-Ktefane 4 Jul 25, 2022
This is a simple open source project where you can easily contribute by uploading algorithms that are not specified in the list.

Support this project by giving it a thumbs up! AlgoBook A new Flutter application for algorithms. This app is mainly to refer to the algorithms that a

Gloria Thomas 18 Jul 23, 2022
M.Yavuz Yagis 3 Feb 21, 2022
A cryptocurrency, crypto-currency, or crypto is a digital currency designed to work as a medium of exchange through a computer network that is not reliant on any central authority

?? Crypto Trackers ?? Crypto Currency ?? A cryptocurrency, crypto-currency, or crypto is a digital currency designed to work as a medium of exchange t

Prashant Kumar Singh 9 Jun 19, 2022
A dart library to check if given point(s) are present inside polygon or not.

poly A library for checking if given point(s) is present inside Polygon or not. Contents Installation Examples Note: Instead of casting, use toListNum

Sacchi 9 Feb 25, 2022
A cryptocurrency, crypto-currency, or crypto is a digital currency designed to work as a medium of exchange through a computer network that is not reliant on any central authority

A cryptocurrency, crypto-currency, or crypto is a digital currency designed to work as a medium of exchange through a computer network that is not reliant on any central authority

Prashant Kumar Singh 9 Jun 19, 2022
A stateless stateful state management package that is not stateless.

Stateless A stateless stateful state management package that is not stateless. DISCLAIMER: Please do not use this package in production, it uses Dart

Jochum van der Ploeg 37 Sep 6, 2022
This is just the simplyfied Flutter Plugin use for one of the popular flutter plugin for social media login.

social_media_logins Flutter Plugin to login via Social Media Accounts. Available Social Media Logins: Facebook Google Apple Getting Started To use thi

Reymark Esponilla 3 Aug 24, 2022