Jelajahi Sumber

merge v0.2.8 (#76)

* freeze v0.2.8

* format dart files

* update versions in example application
Taner Sener 6 tahun lalu
induk
melakukan
7257e60055

+ 1 - 1
.github/FUNDING.yml

@@ -1,2 +1,2 @@
 patreon: tanersener
-custom: ['https://buymeacoff.ee/tanersener','https://paypal.me/teodosiy']
+custom: ['https://buymeacoff.ee/tanersener','https://paypal.me/teodosiyminchev']

+ 1 - 1
.github/ISSUE_TEMPLATE/issue-template.md

@@ -17,7 +17,7 @@ What happened.
 If applicable, add screenshots to help explain your problem.
 
 **Logs**
-Post logs here or paste them to [Ghostbin](https://ghostbin.com) and insert the link here.
+Post logs here or paste them to [Ghostbin](https://ghostbin.co) and insert the link here.
 
 **Environment**
 Flutter doctor output

+ 4 - 0
CHANGELOG.md

@@ -1,3 +1,7 @@
+## 0.2.8
+- Uses ffmpeg v4.3
+- Implements registerNewFFmpegPipe API method
+
 ## 0.2.7
 - Uses new package selection mechanism
 - Fixes issue #52

+ 21 - 11
README.md

@@ -1,6 +1,6 @@
 # flutter_ffmpeg 
 
-![GitHub release](https://img.shields.io/badge/release-v0.2.7-blue.svg)
+![GitHub release](https://img.shields.io/badge/release-v0.2.8-blue.svg)
 ![](https://img.shields.io/pub/v/flutter_ffmpeg.svg)
 
 FFmpeg plugin for Flutter. Supports iOS and Android.
@@ -11,7 +11,7 @@ FFmpeg plugin for Flutter. Supports iOS and Android.
 - Based on MobileFFmpeg
 - Supports
     - Both Android (API Level 16+) and iOS (SDK 9.3+)
-    - FFmpeg `v4.2-dev-x` (master) releases
+    - FFmpeg `v4.2-dev-x` and `v4.3-dev-x` (master) 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
     - 24 external libraries
@@ -70,7 +70,7 @@ FFmpeg plugin for Flutter. Supports iOS and Android.
 Add `flutter_ffmpeg` as a dependency in your `pubspec.yaml file`.
   ```
 dependencies:
-    flutter_ffmpeg: ^0.2.7
+    flutter_ffmpeg: ^0.2.8
   ```
 
 #### 2.1 Packages
@@ -94,16 +94,20 @@ Installation of `FlutterFFmpeg` using `pub` enables the default package, which i
   Do not forget to specify 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.map { |p|
-    symlink = File.join('.symlinks', 'plugins', p[:name])
-    File.symlink(p[:path], symlink)
-    if p[:name] == 'flutter_ffmpeg'
-        pod p[:name]+'/<package name>', :path => File.join(symlink, 'ios')
-    else
-        pod p[:name], :path => File.join(symlink, 'ios')
+    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.3 Package Names
@@ -335,6 +339,12 @@ In order to install the `LTS` variant, install the `https-lts` package using ins
          packageList.forEach((value) => print("External library: $value"));
     });
     ```
+15. Create new `FFmpeg` pipe. 
+    ```
+    _flutterFFmpeg.registerNewFFmpegPipe().then((path) {
+         then((stats) => print("New ffmpeg pipe at $path"));
+    });
+    ```
 
 ### 4. Tips
 

+ 2 - 2
android/build.gradle

@@ -11,7 +11,7 @@ String safeExtGet(String prop, String fallback) {
 }
 
 group 'com.arthenica.flutter.ffmpeg'
-version '0.2.7'
+version '0.2.8'
 
 buildscript {
     repositories {
@@ -45,5 +45,5 @@ android {
 }
 
 dependencies {
-    implementation 'com.arthenica:mobile-ffmpeg-' + safePackageName(safeExtGet('flutterFFmpegPackage', 'https')) + ':' + safePackageVersion(safeExtGet('flutterFFmpegPackage', 'https'), '4.2.2', '4.2.2')
+    implementation 'com.arthenica:mobile-ffmpeg-' + safePackageName(safeExtGet('flutterFFmpegPackage', 'https')) + ':' + safePackageVersion(safeExtGet('flutterFFmpegPackage', 'https'), '4.3', '4.2.2')
 }

+ 1 - 1
android/src/main/java/com/arthenica/flutter/ffmpeg/FlutterFFmpegExecuteAsyncCommandTask.java

@@ -58,7 +58,7 @@ public class FlutterFFmpegExecuteAsyncCommandTask extends AsyncTask<String, Inte
 
             Log.d(FlutterFFmpegPlugin.LIBRARY_NAME, String.format("Running FFmpeg command: %s with delimiter %s.", command, delimiter));
 
-            rc = FFmpeg.execute(command, delimiter);
+            rc = FFmpeg.execute(command);
 
             Log.d(FlutterFFmpegPlugin.LIBRARY_NAME, String.format("FFmpeg exited with rc: %d", rc));
         }

+ 6 - 0
android/src/main/java/com/arthenica/flutter/ffmpeg/FlutterFFmpegPlugin.java

@@ -60,6 +60,7 @@ public class FlutterFFmpegPlugin implements MethodCallHandler, EventChannel.Stre
     public static final String KEY_PLATFORM = "platform";
     public static final String KEY_PACKAGE_NAME = "packageName";
     public static final String KEY_LAST_RC = "lastRc";
+    public static final String KEY_PIPE = "pipe";
 
     public static final String KEY_LAST_COMMAND_OUTPUT = "lastCommandOutput";
     public static final String KEY_LOG_TEXT = "log";
@@ -241,6 +242,11 @@ public class FlutterFFmpegPlugin implements MethodCallHandler, EventChannel.Stre
             final FlutterFFmpegGetMediaInformationAsyncTask asyncTask = new FlutterFFmpegGetMediaInformationAsyncTask(flutterFFmpegResultHandler, timeout, result);
             asyncTask.execute(path);
 
+        } else if (call.method.equals("registerNewFFmpegPipe")) {
+
+            final String pipe = Config.registerNewFFmpegPipe(getActiveContext());
+            flutterFFmpegResultHandler.success(result, toStringMap(KEY_PIPE, pipe));
+
         } else {
             flutterFFmpegResultHandler.notImplemented(result);
         }

+ 6 - 0
example/.gitignore

@@ -26,6 +26,10 @@
 .pub-cache/
 .pub/
 build/
+flutter_*.png
+linked_*.ds
+unlinked.ds
+unlinked_spec.ds
 
 # Android related
 **/android/**/gradle-wrapper.jar
@@ -55,10 +59,12 @@ build/
 **/ios/.generated/
 **/ios/Flutter/App.framework
 **/ios/Flutter/Flutter.framework
+**/ios/Flutter/Flutter.podspec
 **/ios/Flutter/Generated.xcconfig
 **/ios/Flutter/app.flx
 **/ios/Flutter/app.zip
 **/ios/Flutter/flutter_assets/
+**/ios/Flutter/flutter_export_environment.sh
 **/ios/ServiceDefinitions.json
 **/ios/Runner/GeneratedPluginRegistrant.*
 

+ 8 - 1
example/README.md

@@ -141,4 +141,11 @@ Demonstrates how to use the flutter_ffmpeg plugin.
     _flutterFFmpeg.getExternalLibraries().then((packageList) {
          packageList.forEach((value) => print("External library: $value"));
     });
-    ```
+    ```
+15. Create new `FFmpeg` pipe. 
+    ```
+    _flutterFFmpeg.registerNewFFmpegPipe().then((path) {
+         then((stats) => print("New ffmpeg pipe at $path"));
+    });
+    ```
+

+ 2 - 1
example/android/gradle.properties

@@ -1,3 +1,4 @@
 org.gradle.jvmargs=-Xmx1536M
 android.enableJetifier=true
-android.useAndroidX=true
+android.useAndroidX=true
+android.enableR8=true

+ 55 - 36
example/ios/Podfile

@@ -15,58 +15,77 @@ def parse_KV_file(file, separator='=')
   if !File.exists? file_abs_path
     return [];
   end
-  pods_ary = []
+  generated_key_values = {}
   skip_line_start_symbols = ["#", "/"]
-  File.foreach(file_abs_path) { |line|
-      next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
-      plugin = line.split(pattern=separator)
-      if plugin.length == 2
-        podname = plugin[0].strip()
-        path = plugin[1].strip()
-        podpath = File.expand_path("#{path}", file_abs_path)
-        pods_ary.push({:name => podname, :path => podpath});
-      else
-        puts "Invalid plugin specification: #{line}"
-      end
-  }
-  return pods_ary
+  File.foreach(file_abs_path) do |line|
+    next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
+    plugin = line.split(pattern=separator)
+    if plugin.length == 2
+      podname = plugin[0].strip()
+      path = plugin[1].strip()
+      podpath = File.expand_path("#{path}", file_abs_path)
+      generated_key_values[podname] = podpath
+    else
+      puts "Invalid plugin specification: #{line}"
+    end
+  end
+  generated_key_values
 end
 
 target 'Runner' do
-  # 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')
+  # Flutter Pod
 
-  # Flutter Pods
-  generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig')
-  if generated_xcode_build_settings.empty?
-    puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first."
-  end
-  generated_xcode_build_settings.map { |p|
-    if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
-      symlink = File.join('.symlinks', 'flutter')
-      File.symlink(File.dirname(p[:path]), symlink)
-      pod 'Flutter', :path => File.join(symlink, File.basename(p[:path]))
+  copied_flutter_dir = File.join(__dir__, 'Flutter')
+  copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework')
+  copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec')
+  unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path)
+    # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet.
+    # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration.
+    # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.
+
+    generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig')
+    unless File.exist?(generated_xcode_build_settings_path)
+      raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first"
     end
-  }
+    generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path)
+    cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR'];
+
+    unless File.exist?(copied_framework_path)
+      FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir)
+    end
+    unless File.exist?(copied_podspec_path)
+      FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir)
+    end
+  end
+
+  # Keep pod path relative so it can be checked into Podfile.lock.
+  pod 'Flutter', :path => 'Flutter'
 
   # Plugin Pods
+
+  # 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.map { |p|
-    symlink = File.join('.symlinks', 'plugins', p[:name])
-    File.symlink(p[:path], symlink)
-    if p[:name] == 'flutter_ffmpeg'
-        pod p[:name]+'/full', :path => File.join(symlink, 'ios')
+  plugin_pods.each do |name, path|
+    symlink = File.join('.symlinks', 'plugins', name)
+    File.symlink(path, symlink)
+    if name == 'flutter_ffmpeg'
+        pod name+'/full', :path => File.join(symlink, 'ios')
     else
-        pod p[:name], :path => File.join(symlink, 'ios')
+        pod name, :path => File.join(symlink, 'ios')
     end
-  }
+  end
 end
 
+# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
+install! 'cocoapods', :disable_input_output_paths => true
+
 post_install do |installer|
   installer.pods_project.targets.each do |target|
     target.build_configurations.each do |config|
+      config.build_settings['PROVISIONING_PROFILE_SPECIFIER'] = ''
       config.build_settings['ENABLE_BITCODE'] = 'NO'
     end
   end

+ 12 - 12
example/ios/Podfile.lock

@@ -1,35 +1,35 @@
 PODS:
   - Flutter (1.0.0)
-  - flutter_ffmpeg/full (0.2.7):
+  - flutter_ffmpeg/full (0.2.8):
     - Flutter
-    - mobile-ffmpeg-full (= 4.2.2)
-  - mobile-ffmpeg-full (4.2.2)
+    - mobile-ffmpeg-full (= 4.3)
+  - mobile-ffmpeg-full (4.3)
   - path_provider (0.0.1):
     - Flutter
 
 DEPENDENCIES:
-  - Flutter (from `.symlinks/flutter/ios`)
+  - Flutter (from `Flutter`)
   - flutter_ffmpeg/full (from `.symlinks/plugins/flutter_ffmpeg/ios`)
   - path_provider (from `.symlinks/plugins/path_provider/ios`)
 
 SPEC REPOS:
-  https://github.com/cocoapods/specs.git:
+  trunk:
     - mobile-ffmpeg-full
 
 EXTERNAL SOURCES:
   Flutter:
-    :path: ".symlinks/flutter/ios"
+    :path: Flutter
   flutter_ffmpeg:
     :path: ".symlinks/plugins/flutter_ffmpeg/ios"
   path_provider:
     :path: ".symlinks/plugins/path_provider/ios"
 
 SPEC CHECKSUMS:
-  Flutter: 58dd7d1b27887414a370fcccb9e645c08ffd7a6a
-  flutter_ffmpeg: 05ee218287a2b55a13df8f7970aab1a52094083e
-  mobile-ffmpeg-full: 42f654ef799818c6b8344ffd5a63c83b53f86745
-  path_provider: f96fff6166a8867510d2c25fdcc346327cc4b259
+  Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
+  flutter_ffmpeg: c515a3a8a2d4e070fd684e85b2dd2084c749a585
+  mobile-ffmpeg-full: af38edede256cb1d4fcbf10dddef39bf529ecd50
+  path_provider: fb74bd0465e96b594bb3b5088ee4a4e7bb1f2a9d
 
-PODFILE CHECKSUM: 3c42d7d5cb11914bdcd50bd04ea49997cf3f22b5
+PODFILE CHECKSUM: 67dc48fdfc7437590697cf64597a0949c9173184
 
-COCOAPODS: 1.7.3
+COCOAPODS: 1.8.4

+ 0 - 3
example/ios/Runner.xcodeproj/project.pbxproj

@@ -278,12 +278,9 @@
 			files = (
 			);
 			inputPaths = (
-				"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
-				"${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework",
 			);
 			name = "[CP] Embed Pods Frameworks";
 			outputPaths = (
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;

+ 113 - 47
example/lib/flutter_ffmpeg_example.dart

@@ -55,18 +55,27 @@ class VideoUtil {
   static Future<File> copyFileAssets(String assetName, String localName) async {
     final ByteData assetByteData = await rootBundle.load(assetName);
 
-    final List<int> byteList = assetByteData.buffer.asUint8List(assetByteData.offsetInBytes, assetByteData.lengthInBytes);
+    final List<int> byteList = assetByteData.buffer
+        .asUint8List(assetByteData.offsetInBytes, assetByteData.lengthInBytes);
 
-    final String fullTemporaryPath = join((await tempDirectory).path, localName);
+    final String fullTemporaryPath =
+        join((await tempDirectory).path, localName);
 
-    return new File(fullTemporaryPath).writeAsBytes(byteList, mode: FileMode.writeOnly, flush: true);
+    return new File(fullTemporaryPath)
+        .writeAsBytes(byteList, mode: FileMode.writeOnly, flush: true);
   }
 
   static Future<String> assetPath(String assetName) async {
     return join((await tempDirectory).path, assetName);
   }
 
-  static String generateEncodeVideoScript(String image1Path, String image2Path, String image3Path, String videoFilePath, String videoCodec, String customOptions) {
+  static String generateEncodeVideoScript(
+      String image1Path,
+      String image2Path,
+      String image3Path,
+      String videoFilePath,
+      String videoCodec,
+      String customOptions) {
     return "-hide_banner    -y -loop   1 -i '" +
         image1Path +
         "' " +
@@ -98,7 +107,8 @@ class VideoUtil {
   }
 }
 
-class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderStateMixin {
+class FlutterFFmpegTestAppState extends State<MainPage>
+    with TickerProviderStateMixin {
   static const String ASSET_1 = "1.jpg";
   static const String ASSET_2 = "2.jpg";
   static const String ASSET_3 = "3.jpg";
@@ -132,9 +142,11 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
   void startupTests() {
     getFFmpegVersion().then((version) => print("FFmpeg version: $version"));
     getPlatform().then((platform) => print("Platform: $platform"));
-    getLogLevel().then((level) => print("Old log level: " + LogLevel.levelToString(level)));
+    getLogLevel().then(
+        (level) => print("Old log level: " + LogLevel.levelToString(level)));
     setLogLevel(LogLevel.AV_LOG_INFO);
-    getLogLevel().then((level) => print("New log level: " + LogLevel.levelToString(level)));
+    getLogLevel().then(
+        (level) => print("New log level: " + LogLevel.levelToString(level)));
     getPackageName().then((packageName) => print("Package name: $packageName"));
     getExternalLibraries().then((packageList) {
       packageList.forEach((value) => print("External library: $value"));
@@ -142,9 +154,12 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
   }
 
   void prepareAssets() {
-    VideoUtil.copyFileAssets('assets/pyramid.jpg', ASSET_1).then((path) => print('Loaded asset $path.'));
-    VideoUtil.copyFileAssets('assets/colosseum.jpg', ASSET_2).then((path) => print('Loaded asset $path.'));
-    VideoUtil.copyFileAssets('assets/tajmahal.jpg', ASSET_3).then((path) => print('Loaded asset $path.'));
+    VideoUtil.copyFileAssets('assets/pyramid.jpg', ASSET_1)
+        .then((path) => print('Loaded asset $path.'));
+    VideoUtil.copyFileAssets('assets/colosseum.jpg', ASSET_2)
+        .then((path) => print('Loaded asset $path.'));
+    VideoUtil.copyFileAssets('assets/tajmahal.jpg', ASSET_3)
+        .then((path) => print('Loaded asset $path.'));
   }
 
   void testParseArguments() {
@@ -156,11 +171,13 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
 
   void testRunCommand() {
     getLastReturnCode().then((rc) => print("Last rc: $rc"));
-    getLastCommandOutput().then((output) => print("Last command output: $output"));
+    getLastCommandOutput().then((output) =>
+        debugPrint("Last command output: \"$output\"", wrapWidth: 1024));
 
     print("Testing ParseArguments.");
 
     testParseArguments();
+    registerNewFFmpegPipe().then((path) => print("New FFmpeg pipe: $path"));
 
     print("Testing COMMAND.");
 
@@ -187,7 +204,8 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
     // disableLogs();
     // enableLogs();
 
-    execute(_commandController.text).then((rc) => print("FFmpeg process exited with rc $rc"));
+    execute(_commandController.text)
+        .then((rc) => print("FFmpeg process exited with rc $rc"));
     // executeWithArguments(_commandController.text.split(" ")).then((rc) => print("FFmpeg process exited with rc $rc"));
 
     setState(() {});
@@ -232,22 +250,26 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
               print('Stream channel layout: ${streamsInfo['channelLayout']}');
               print('Stream sar: ${streamsInfo['sampleAspectRatio']}');
               print('Stream dar: ${streamsInfo['displayAspectRatio']}');
-              print('Stream average frame rate: ${streamsInfo['averageFrameRate']}');
+              print(
+                  'Stream average frame rate: ${streamsInfo['averageFrameRate']}');
               print('Stream real frame rate: ${streamsInfo['realFrameRate']}');
               print('Stream time base: ${streamsInfo['timeBase']}');
               print('Stream codec time base: ${streamsInfo['codecTimeBase']}');
 
               final metadataMap = streamsInfo['metadata'];
               if (metadataMap != null) {
-                  print('Stream metadata encoder: ${metadataMap['encoder']}');
-                  print('Stream metadata rotate: ${metadataMap['rotate']}');
-                  print('Stream metadata creation time: ${metadataMap['creation_time']}');
-                  print('Stream metadata handler name: ${metadataMap['handler_name']}');
+                print('Stream metadata encoder: ${metadataMap['encoder']}');
+                print('Stream metadata rotate: ${metadataMap['rotate']}');
+                print(
+                    'Stream metadata creation time: ${metadataMap['creation_time']}');
+                print(
+                    'Stream metadata handler name: ${metadataMap['handler_name']}');
               }
 
               final sideDataMap = streamsInfo['sidedata'];
               if (sideDataMap != null) {
-                  print('Stream side data displaymatrix: ${sideDataMap['displaymatrix']}');
+                print(
+                    'Stream side data displaymatrix: ${sideDataMap['displaymatrix']}');
               }
             }
           }
@@ -279,9 +301,13 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
           final String ffmpegCodec = getFFmpegCodecName();
 
           VideoUtil.assetPath(videoPath).then((fullVideoPath) {
-            execute(VideoUtil.generateEncodeVideoScript(image1Path, image2Path, image3Path, fullVideoPath, ffmpegCodec, customOptions)).then((rc) {
+            execute(VideoUtil.generateEncodeVideoScript(image1Path, image2Path,
+                    image3Path, fullVideoPath, ffmpegCodec, customOptions))
+                .then((rc) {
               if (rc == 0) {
-                testGetMediaInformation(fullVideoPath);
+                getLastCommandOutput().then((output) => debugPrint(
+                    "Last command output: \"$output\"",
+                    wrapWidth: 1024));
               }
             });
 
@@ -299,10 +325,13 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
                 double bitrate = _doublePrecision(lastStatistics['bitrate'], 2);
                 double speed = _doublePrecision(lastStatistics['speed'], 2);
                 int videoFrameNumber = lastStatistics['videoFrameNumber'];
-                double videoQuality = _doublePrecision(lastStatistics['videoQuality'], 2);
-                double videoFps = _doublePrecision(lastStatistics['videoFps'], 2);
+                double videoQuality =
+                    _doublePrecision(lastStatistics['videoQuality'], 2);
+                double videoFps =
+                    _doublePrecision(lastStatistics['videoFps'], 2);
 
-                statisticsCallback(time, size, bitrate, speed, videoFrameNumber, videoQuality, videoFps);
+                statisticsCallback(time, size, bitrate, speed, videoFrameNumber,
+                    videoQuality, videoFps);
               }
             });
           });
@@ -323,8 +352,10 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
     setState(() {});
   }
 
-  void statisticsCallback(int time, int size, double bitrate, double speed, int videoFrameNumber, double videoQuality, double videoFps) {
-    print("Statistics: time: $time, size: $size, bitrate: $bitrate, speed: $speed, videoFrameNumber: $videoFrameNumber, videoQuality: $videoQuality, videoFps: $videoFps");
+  void statisticsCallback(int time, int size, double bitrate, double speed,
+      int videoFrameNumber, double videoQuality, double videoFps) {
+    print(
+        "Statistics: time: $time, size: $size, bitrate: $bitrate, speed: $speed, videoFrameNumber: $videoFrameNumber, videoQuality: $videoQuality, videoFps: $videoFps");
   }
 
   Future<String> getFFmpegVersion() async {
@@ -387,7 +418,8 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
     return await _flutterFFmpeg.setFontconfigConfigurationPath(path);
   }
 
-  Future<void> setFontDirectory(String fontDirectory, Map<String, String> fontNameMap) async {
+  Future<void> setFontDirectory(
+      String fontDirectory, Map<String, String> fontNameMap) async {
     return await _flutterFFmpeg.setFontDirectory(fontDirectory, fontNameMap);
   }
 
@@ -411,6 +443,10 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
     return await _flutterFFmpeg.getMediaInformation(path);
   }
 
+  Future<String> registerNewFFmpegPipe() async {
+    return await _flutterFFmpeg.registerNewFFmpegPipe();
+  }
+
   void _changedCodec(String selectedCodec) {
     setState(() {
       _currentCodec = selectedCodec;
@@ -529,25 +565,29 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
                     controller: _commandController,
                     decoration: InputDecoration(
                         border: const OutlineInputBorder(
-                          borderSide: const BorderSide(color: Color(0xFF3498DB)),
+                          borderSide:
+                              const BorderSide(color: Color(0xFF3498DB)),
                           borderRadius: const BorderRadius.all(
                             const Radius.circular(5),
                           ),
                         ),
                         focusedBorder: const OutlineInputBorder(
-                          borderSide: const BorderSide(color: Color(0xFF3498DB)),
+                          borderSide:
+                              const BorderSide(color: Color(0xFF3498DB)),
                           borderRadius: const BorderRadius.all(
                             const Radius.circular(5),
                           ),
                         ),
                         enabledBorder: const OutlineInputBorder(
-                          borderSide: const BorderSide(color: Color(0xFF3498DB)),
+                          borderSide:
+                              const BorderSide(color: Color(0xFF3498DB)),
                           borderRadius: const BorderRadius.all(
                             const Radius.circular(5),
                           ),
                         ),
                         contentPadding: EdgeInsets.fromLTRB(8, 12, 8, 12),
-                        hintStyle: new TextStyle(fontSize: 14, color: Colors.grey[400]),
+                        hintStyle: new TextStyle(
+                            fontSize: 14, color: Colors.grey[400]),
                         hintText: "Enter command"),
                     style: new TextStyle(fontSize: 14, color: Colors.black),
                   ),
@@ -566,7 +606,10 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
                       child: new Center(
                         child: new Text(
                           'RUN',
-                          style: new TextStyle(fontSize: 14.0, fontWeight: FontWeight.bold, color: Colors.white),
+                          style: new TextStyle(
+                              fontSize: 14.0,
+                              fontWeight: FontWeight.bold,
+                              color: Colors.white),
                         ),
                       ),
                     ),
@@ -577,8 +620,12 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
                       alignment: Alignment(-1.0, -1.0),
                       margin: EdgeInsets.all(20.0),
                       padding: EdgeInsets.all(4.0),
-                      decoration: new BoxDecoration(borderRadius: BorderRadius.all(new Radius.circular(5)), color: Color(0xFFF1C40F)),
-                      child: SingleChildScrollView(reverse: true, child: Text(_commandOutput))),
+                      decoration: new BoxDecoration(
+                          borderRadius:
+                              BorderRadius.all(new Radius.circular(5)),
+                          color: Color(0xFFF1C40F)),
+                      child: SingleChildScrollView(
+                          reverse: true, child: Text(_commandOutput))),
                 )
               ],
             ),
@@ -590,7 +637,9 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
                     child: Container(
                       width: 200,
                       alignment: Alignment(0.0, 0.0),
-                      decoration: BoxDecoration(color: Color.fromRGBO(155, 89, 182, 1.0), borderRadius: BorderRadius.circular(5)),
+                      decoration: BoxDecoration(
+                          color: Color.fromRGBO(155, 89, 182, 1.0),
+                          borderRadius: BorderRadius.circular(5)),
                       child: DropdownButtonHideUnderline(
                           child: DropdownButton(
                         style: new TextStyle(
@@ -618,7 +667,10 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
                       child: new Center(
                         child: new Text(
                           'ENCODE',
-                          style: new TextStyle(fontSize: 14.0, fontWeight: FontWeight.bold, color: Colors.white),
+                          style: new TextStyle(
+                              fontSize: 14.0,
+                              fontWeight: FontWeight.bold,
+                              color: Colors.white),
                         ),
                       ),
                     ),
@@ -629,8 +681,12 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
                       alignment: Alignment(-1.0, -1.0),
                       margin: EdgeInsets.all(20.0),
                       padding: EdgeInsets.all(4.0),
-                      decoration: new BoxDecoration(borderRadius: BorderRadius.all(new Radius.circular(5)), color: Color(0xFFF1C40F)),
-                      child: SingleChildScrollView(reverse: true, child: Text(_encodeOutput))),
+                      decoration: new BoxDecoration(
+                          borderRadius:
+                              BorderRadius.all(new Radius.circular(5)),
+                          color: Color(0xFFF1C40F)),
+                      child: SingleChildScrollView(
+                          reverse: true, child: Text(_encodeOutput))),
                 )
               ],
             ),
@@ -646,7 +702,8 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
   }
 
   void testParseSimpleCommand() {
-    var argumentArray = _flutterFFmpeg.parseArguments("-hide_banner   -loop 1  -i file.jpg  -filter_complex  [0:v]setpts=PTS-STARTPTS[video] -map [video] -vsync 2 -async 1  video.mp4");
+    var argumentArray = _flutterFFmpeg.parseArguments(
+        "-hide_banner   -loop 1  -i file.jpg  -filter_complex  [0:v]setpts=PTS-STARTPTS[video] -map [video] -vsync 2 -async 1  video.mp4");
 
     assert(argumentArray != null);
     assert(argumentArray.length == 14);
@@ -668,7 +725,8 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
   }
 
   void testParseSingleQuotesInCommand() {
-    var argumentArray = _flutterFFmpeg.parseArguments("-loop 1 'file one.jpg'  -filter_complex  '[0:v]setpts=PTS-STARTPTS[video]'  -map  [video]  video.mp4 ");
+    var argumentArray = _flutterFFmpeg.parseArguments(
+        "-loop 1 'file one.jpg'  -filter_complex  '[0:v]setpts=PTS-STARTPTS[video]'  -map  [video]  video.mp4 ");
 
     assert(argumentArray != null);
     assert(argumentArray.length == 8);
@@ -684,7 +742,8 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
   }
 
   void testParseDoubleQuotesInCommand() {
-    var argumentArray = _flutterFFmpeg.parseArguments("-loop  1 \"file one.jpg\"   -filter_complex \"[0:v]setpts=PTS-STARTPTS[video]\"  -map  [video]  video.mp4 ");
+    var argumentArray = _flutterFFmpeg.parseArguments(
+        "-loop  1 \"file one.jpg\"   -filter_complex \"[0:v]setpts=PTS-STARTPTS[video]\"  -map  [video]  video.mp4 ");
 
     assert(argumentArray != null);
     assert(argumentArray.length == 8);
@@ -698,7 +757,8 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
     assert("[video]" == argumentArray[6]);
     assert("video.mp4" == argumentArray[7]);
 
-    argumentArray = _flutterFFmpeg.parseArguments(" -i   file:///tmp/input.mp4 -vcodec libx264 -vf \"scale=1024:1024,pad=width=1024:height=1024:x=0:y=0:color=black\"  -acodec copy  -q:v 0  -q:a   0 video.mp4");
+    argumentArray = _flutterFFmpeg.parseArguments(
+        " -i   file:///tmp/input.mp4 -vcodec libx264 -vf \"scale=1024:1024,pad=width=1024:height=1024:x=0:y=0:color=black\"  -acodec copy  -q:v 0  -q:a   0 video.mp4");
 
     assert(argumentArray != null);
     assert(argumentArray.length == 13);
@@ -708,7 +768,8 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
     assert("-vcodec" == argumentArray[2]);
     assert("libx264" == argumentArray[3]);
     assert("-vf" == argumentArray[4]);
-    assert("scale=1024:1024,pad=width=1024:height=1024:x=0:y=0:color=black" == argumentArray[5]);
+    assert("scale=1024:1024,pad=width=1024:height=1024:x=0:y=0:color=black" ==
+        argumentArray[5]);
     assert("-acodec" == argumentArray[6]);
     assert("copy" == argumentArray[7]);
     assert("-q:v" == argumentArray[8]);
@@ -719,7 +780,8 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
   }
 
   void testParseDoubleQuotesAndEscapesInCommand() {
-    var argumentArray = _flutterFFmpeg.parseArguments("  -i   file:///tmp/input.mp4 -vf \"subtitles=file:///tmp/subtitles.srt:force_style=\'FontSize=16,PrimaryColour=&HFFFFFF&\'\" -vcodec libx264   -acodec copy  -q:v 0 -q:a  0  video.mp4");
+    var argumentArray = _flutterFFmpeg.parseArguments(
+        "  -i   file:///tmp/input.mp4 -vf \"subtitles=file:///tmp/subtitles.srt:force_style=\'FontSize=16,PrimaryColour=&HFFFFFF&\'\" -vcodec libx264   -acodec copy  -q:v 0 -q:a  0  video.mp4");
 
     assert(argumentArray != null);
     assert(argumentArray.length == 13);
@@ -727,7 +789,9 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
     assert("-i" == argumentArray[0]);
     assert("file:///tmp/input.mp4" == argumentArray[1]);
     assert("-vf" == argumentArray[2]);
-    assert("subtitles=file:///tmp/subtitles.srt:force_style='FontSize=16,PrimaryColour=&HFFFFFF&'" == argumentArray[3]);
+    assert(
+        "subtitles=file:///tmp/subtitles.srt:force_style='FontSize=16,PrimaryColour=&HFFFFFF&'" ==
+            argumentArray[3]);
     assert("-vcodec" == argumentArray[4]);
     assert("libx264" == argumentArray[5]);
     assert("-acodec" == argumentArray[6]);
@@ -738,7 +802,8 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
     assert("0" == argumentArray[11]);
     assert("video.mp4" == argumentArray[12]);
 
-    argumentArray = _flutterFFmpeg.parseArguments("  -i   file:///tmp/input.mp4 -vf \"subtitles=file:///tmp/subtitles.srt:force_style=\\\"FontSize=16,PrimaryColour=&HFFFFFF&\\\"\" -vcodec libx264   -acodec copy  -q:v 0 -q:a  0  video.mp4");
+    argumentArray = _flutterFFmpeg.parseArguments(
+        "  -i   file:///tmp/input.mp4 -vf \"subtitles=file:///tmp/subtitles.srt:force_style=\\\"FontSize=16,PrimaryColour=&HFFFFFF&\\\"\" -vcodec libx264   -acodec copy  -q:v 0 -q:a  0  video.mp4");
 
     assert(argumentArray != null);
     assert(argumentArray.length == 13);
@@ -746,7 +811,9 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
     assert("-i" == argumentArray[0]);
     assert("file:///tmp/input.mp4" == argumentArray[1]);
     assert("-vf" == argumentArray[2]);
-    assert("subtitles=file:///tmp/subtitles.srt:force_style=\\\"FontSize=16,PrimaryColour=&HFFFFFF&\\\"" == argumentArray[3]);
+    assert(
+        "subtitles=file:///tmp/subtitles.srt:force_style=\\\"FontSize=16,PrimaryColour=&HFFFFFF&\\\"" ==
+            argumentArray[3]);
     assert("-vcodec" == argumentArray[4]);
     assert("libx264" == argumentArray[5]);
     assert("-acodec" == argumentArray[6]);
@@ -757,5 +824,4 @@ class FlutterFFmpegTestAppState extends State<MainPage> with TickerProviderState
     assert("0" == argumentArray[11]);
     assert("video.mp4" == argumentArray[12]);
   }
-
 }

+ 67 - 11
example/pubspec.lock

@@ -1,20 +1,34 @@
 # Generated by pub
-# See https://www.dartlang.org/tools/pub/glossary#lockfile
+# See https://dart.dev/tools/pub/glossary#lockfile
 packages:
+  archive:
+    dependency: transitive
+    description:
+      name: archive
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.0.10"
+  args:
+    dependency: transitive
+    description:
+      name: args
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.5.2"
   async:
     dependency: transitive
     description:
       name: async
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.2.0"
+    version: "2.3.0"
   boolean_selector:
     dependency: transitive
     description:
       name: boolean_selector
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.0.4"
+    version: "1.0.5"
   charcode:
     dependency: transitive
     description:
@@ -29,6 +43,20 @@ packages:
       url: "https://pub.dartlang.org"
     source: hosted
     version: "1.14.11"
+  convert:
+    dependency: transitive
+    description:
+      name: convert
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.1.1"
+  crypto:
+    dependency: transitive
+    description:
+      name: crypto
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.1.3"
   cupertino_icons:
     dependency: "direct main"
     description:
@@ -47,12 +75,19 @@ packages:
       name: flutter_ffmpeg
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.2.7"
+    version: "0.2.8"
   flutter_test:
     dependency: "direct dev"
     description: flutter
     source: sdk
     version: "0.0.0"
+  image:
+    dependency: transitive
+    description:
+      name: image
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.1.4"
   matcher:
     dependency: transitive
     description:
@@ -66,35 +101,49 @@ packages:
       name: meta
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.1.6"
+    version: "1.1.7"
   path:
     dependency: "direct main"
     description:
       name: path
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.6.2"
+    version: "1.6.4"
   path_provider:
     dependency: "direct main"
     description:
       name: path_provider
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.5.0+1"
+    version: "1.4.0"
   pedantic:
     dependency: transitive
     description:
       name: pedantic
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.5.0"
+    version: "1.8.0+1"
+  petitparser:
+    dependency: transitive
+    description:
+      name: petitparser
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.4.0"
+  platform:
+    dependency: transitive
+    description:
+      name: platform
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.2.1"
   quiver:
     dependency: transitive
     description:
       name: quiver
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.0.3"
+    version: "2.0.5"
   sky_engine:
     dependency: transitive
     description: flutter
@@ -127,7 +176,7 @@ packages:
       name: string_scanner
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.0.4"
+    version: "1.0.5"
   term_glyph:
     dependency: transitive
     description:
@@ -156,6 +205,13 @@ packages:
       url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.8"
+  xml:
+    dependency: transitive
+    description:
+      name: xml
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.5.0"
 sdks:
-  dart: ">=2.2.0 <3.0.0"
+  dart: ">=2.4.0 <3.0.0"
   flutter: ">=0.1.4 <2.0.0"

+ 4 - 3
example/pubspec.yaml

@@ -1,5 +1,6 @@
 name: flutter_ffmpeg_example
 description: Demonstrates how to use the flutter_ffmpeg plugin.
+version: 1.0.0
 publish_to: 'none'
 
 environment:
@@ -9,9 +10,9 @@ dependencies:
   flutter:
     sdk: flutter
   cupertino_icons: ^0.1.2
-  path: ^1.6.2
-  path_provider: ^0.5.0+1
-  flutter_ffmpeg: 0.2.7
+  path: ^1.6.4
+  path_provider: ^1.4.0
+  flutter_ffmpeg: ^0.2.8
 
 dev_dependencies:
   flutter_test:

+ 2 - 11
flutter_ffmpeg.iml

@@ -14,18 +14,9 @@
       <excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_ffmpeg/.dart_tool" />
       <excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_ffmpeg/.pub" />
       <excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_ffmpeg/build" />
-      <excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_ffmpeg/example/build/app/intermediates/flutter/debug/flutter_assets/packages" />
-      <excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_ffmpeg/example/build/app/intermediates/merged_assets/debug/mergeDebugAssets/out/flutter_assets/packages" />
-      <excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_ffmpeg/example/build/flutter_assets/packages" />
-      <excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_ffmpeg/example/build/ios/Debug-iphonesimulator/Runner.app/flutter_assets/packages" />
-      <excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_ffmpeg/example/build/ios/iphonesimulator/Runner.app/flutter_assets/packages" />
-      <excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_ffmpeg/example/ios/.symlinks/plugins/flutter_ffmpeg/packages" />
-      <excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_ffmpeg/example/ios/Flutter/flutter_assets/packages" />
-      <excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_ffmpeg/packages" />
-      <excludeFolder url="file://$MODULE_DIR$/example/ios/Flutter/flutter_assets/packages" />
-      <excludeFolder url="file://$MODULE_DIR$/packages" />
+      <excludeFolder url="file://$MODULE_DIR$/example/ios/Flutter/App.framework/flutter_assets/packages" />
     </content>
-    <orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
+    <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
     <orderEntry type="library" name="Dart SDK" level="project" />
     <orderEntry type="library" name="Flutter Plugins" level="project" />

+ 6 - 0
ios/Classes/FlutterFfmpegPlugin.m

@@ -31,6 +31,7 @@ static NSString *const KEY_PLATFORM = @"platform";
 static NSString *const KEY_PACKAGE_NAME = @"packageName";
 static NSString *const KEY_LAST_RC = @"lastRc";
 static NSString *const KEY_LAST_COMMAND_OUTPUT = @"lastCommandOutput";
+static NSString *const KEY_PIPE = @"pipe";
 
 static NSString *const KEY_LOG_TEXT = @"log";
 static NSString *const KEY_LOG_LEVEL = @"level";
@@ -208,6 +209,11 @@ static NSString *const EVENT_STAT = @"FlutterFFmpegStatisticsCallback";
             result([FlutterFFmpegPlugin toMediaInformationDictionary:mediaInformation]);
         });
 
+    } else if ([@"registerNewFFmpegPipe" isEqualToString:call.method]) {
+
+        NSString *pipe = [MobileFFmpegConfig registerNewFFmpegPipe];
+        result([FlutterFFmpegPlugin toStringDictionary:KEY_PIPE :pipe]);
+
     } else {
 
         result(FlutterMethodNotImplemented);

+ 9 - 9
ios/flutter_ffmpeg.podspec

@@ -1,6 +1,6 @@
 Pod::Spec.new do |s|
   s.name             = 'flutter_ffmpeg'
-  s.version          = '0.2.7'
+  s.version          = '0.2.8'
   s.summary          = 'FFmpeg plugin for Flutter.'
   s.description      = 'FFmpeg plugin based on mobile-ffmpeg for Flutter.'
   s.homepage         = 'https://github.com/tanersener/flutter-ffmpeg'
@@ -24,7 +24,7 @@ Pod::Spec.new do |s|
     ss.source_files        = 'Classes/**/*'
     ss.public_header_files = 'Classes/**/*.h'
 
-    ss.dependency 'mobile-ffmpeg-min', '4.2.2'
+    ss.dependency 'mobile-ffmpeg-min', '4.3'
   end
 
   s.subspec 'min-lts' do |ss|
@@ -38,7 +38,7 @@ Pod::Spec.new do |s|
     ss.source_files        = 'Classes/**/*'
     ss.public_header_files = 'Classes/**/*.h'
 
-    ss.dependency 'mobile-ffmpeg-min-gpl', '4.2.2'
+    ss.dependency 'mobile-ffmpeg-min-gpl', '4.3'
   end
 
   s.subspec 'min-gpl-lts' do |ss|
@@ -52,7 +52,7 @@ Pod::Spec.new do |s|
     ss.source_files        = 'Classes/**/*'
     ss.public_header_files = 'Classes/**/*.h'
 
-    ss.dependency 'mobile-ffmpeg-https', '4.2.2'
+    ss.dependency 'mobile-ffmpeg-https', '4.3'
   end
 
   s.subspec 'https-lts' do |ss|
@@ -66,7 +66,7 @@ Pod::Spec.new do |s|
     ss.source_files        = 'Classes/**/*'
     ss.public_header_files = 'Classes/**/*.h'
 
-    ss.dependency 'mobile-ffmpeg-https-gpl', '4.2.2'
+    ss.dependency 'mobile-ffmpeg-https-gpl', '4.3'
   end
 
   s.subspec 'https-gpl-lts' do |ss|
@@ -80,7 +80,7 @@ Pod::Spec.new do |s|
     ss.source_files        = 'Classes/**/*'
     ss.public_header_files = 'Classes/**/*.h'
 
-    ss.dependency 'mobile-ffmpeg-audio', '4.2.2'
+    ss.dependency 'mobile-ffmpeg-audio', '4.3'
   end
 
   s.subspec 'audio-lts' do |ss|
@@ -94,7 +94,7 @@ Pod::Spec.new do |s|
     ss.source_files        = 'Classes/**/*'
     ss.public_header_files = 'Classes/**/*.h'
 
-    ss.dependency 'mobile-ffmpeg-video', '4.2.2'
+    ss.dependency 'mobile-ffmpeg-video', '4.3'
   end
 
   s.subspec 'video-lts' do |ss|
@@ -108,7 +108,7 @@ Pod::Spec.new do |s|
     ss.source_files        = 'Classes/**/*'
     ss.public_header_files = 'Classes/**/*.h'
 
-    ss.dependency 'mobile-ffmpeg-full', '4.2.2'
+    ss.dependency 'mobile-ffmpeg-full', '4.3'
   end
 
   s.subspec 'full-lts' do |ss|
@@ -122,7 +122,7 @@ Pod::Spec.new do |s|
     ss.source_files        = 'Classes/**/*'
     ss.public_header_files = 'Classes/**/*.h'
 
-    ss.dependency 'mobile-ffmpeg-full-gpl', '4.2.2'
+    ss.dependency 'mobile-ffmpeg-full-gpl', '4.3'
   end
 
   s.subspec 'full-gpl-lts' do |ss|

+ 12 - 0
lib/flutter_ffmpeg.dart

@@ -380,6 +380,18 @@ class FlutterFFmpeg {
     }
   }
 
+  /// Creates a new FFmpeg pipe and returns its path.
+  Future<String> registerNewFFmpegPipe() async {
+    try {
+      final Map<dynamic, dynamic> result =
+          await _methodChannel.invokeMethod('registerNewFFmpegPipe');
+      return result['pipe'];
+    } on PlatformException catch (e) {
+      print("Plugin error: ${e.message}");
+      return null;
+    }
+  }
+
   /// Parses the given [command] into arguments.
   List<String> parseArguments(String command) {
     List<String> argumentList = new List();

+ 3 - 3
pubspec.yaml

@@ -1,6 +1,6 @@
 name: flutter_ffmpeg
 description: Flutter plugin to run FFmpeg on mobile platforms. Supports iOS and Android.
-version: 0.2.7
+version: 0.2.8
 author: Taner Sener <tanersener@gmail.com>
 homepage: https://github.com/tanersener/flutter-ffmpeg
 
@@ -12,8 +12,8 @@ dependencies:
     sdk: flutter
 
 dev_dependencies:
-  path_provider: ^1.1.0
-  path: ^1.6.2
+  path_provider: ^1.4.0
+  path: ^1.6.4
 
 flutter:
   plugin: