Search code examples
flutterffmpegandroid-ffmpegflutter-ffmpeg

Flutter FFmpeg | Concat Multiple Videos From TXT File And Save As A Video


I have a text file with all path of video files that I want to concat using https://pub.dev/packages/ffmpeg_kit_flutter in my flutter app.

For this purpose, I write a file my_file.txt with the below data...

/data/user/0/com.example.video_merger/cache/75f72300-1203-4e2c-93cf-65777152f1d16524788775537818173.mp4
/data/user/0/com.example.video_merger/cache/318d5ea7-3e0c-4453-903b-06966aa86f348487775694692938421.mp4

Now I am using the below code to merge all the upper videos.

String outputPath = "/data/user/0/com.example.video_merger/app_flutter/output.mp4";
String commandToExecute = '-f concat -i $rawDocumentPath/my_file.txt -c copy $outputPath';
FFmpegKit.execute(commandToExecute).then((session) async {
  final returnCode = await session.getReturnCode();
  print("FFmpeg Process Exited With ReturnCode = $returnCode");
  GallerySaver.saveVideo(outputPath).then((_) {
    print("Merged Video Saved");
  });
  if (ReturnCode.isSuccess(returnCode)) {
    // SUCCESS
  } else if (ReturnCode.isCancel(returnCode)) {
    // CANCEL
  } else {
    // ERROR
  }
});

But it is giving me error as shown below...

FFmpeg Process Exited With ReturnCode = 1 
E/GallerySaver(31493): /data/user/0/com.example.video_merger/app_flutter/output.mp4: open failed: ENOENT (No such file or directory)

But when I use the below ffmpeg command directly without reading from text file works fine and save my video.

String commandToExecute = '-y -i ${_storedVideoOne!.path} -i ${_storedVideoTwo!.path} -r 24000/1001 -filter_complex \'[0:v:0][0:a:0][1:v:0][1:a:0]concat=n=2:v=1:a=1[out]\' -map \'[out]\' $outputPath';

Now my question is that I will have dynamic number of videos to concat so I want to use text file where I will write all paths then will make merged video from them. So what is the error in my ffmpeg command...???

Log Report:

I used the log reporting as follows to get the below output of errors...

    FFmpegKit.executeAsync(
      commandToExecute2,
          (session) async {
            final returnCode = await session.getReturnCode();
            print("FFmpeg Process Exited With ReturnCode = $returnCode");
            GallerySaver.saveVideo(outputPath).then((_) async {
              print("Merged Video Saved");
            });
            if (ReturnCode.isSuccess(returnCode)) {
              // SUCCESS
            } else if (ReturnCode.isCancel(returnCode)) {
              // CANCEL
            } else {
              // ERROR
            }
          },
          (log) {
        print("XXXXXXXXXXXX fFmpeg XXXXXXXXXX ${log.getMessage()}");
      },
    );

And here is the Log Output...

I/flutter ( 5432): Text On File: /data/user/0/com.example.video_merger/cache/75f72300-1203-4e2c-93cf-65777152f1d16524788775537818173.mp4
I/flutter ( 5432): /data/user/0/com.example.video_merger/cache/318d5ea7-3e0c-4453-903b-06966aa86f348487775694692938421.mp4
I/flutter ( 5432): XXXXXXXXXXXX fFmpeg XXXXXXXXXX ffmpeg version n5.1.2
I/flutter ( 5432): XXXXXXXXXXXX fFmpeg XXXXXXXXXX Copyright (c) 2000-2022 the FFmpeg developers
I/flutter ( 5432): XXXXXXXXXXXX fFmpeg XXXXXXXXXX
I/flutter ( 5432): XXXXXXXXXXXX fFmpeg XXXXXXXXXX  built with Android (7155654, based on r399163b1) clang version 11.0.5 (https://android.googlesource.com/toolchain/llvm-project 87f1315dfbea7c137aa2e6d362dbb457e388158d)
I/flutter ( 5432): XXXXXXXXXXXX fFmpeg XXXXXXXXXX  configuration: --cross-prefix=aarch64-linux-android- --sysroot=/files/android-sdk/ndk/22.1.7171670/toolchains/llvm/prebuilt/linux-x86_64/sysroot --prefix=/home/taner/Projects/ffmpeg-kit/prebuilt/android-arm64/ffmpeg --pkg-config=/usr/bin/pkg-config --enable-version3 --arch=aarch64 --cpu=armv8-a --target-os=android --enable-neon --enable-asm --enable-inline-asm --ar=aarch64-linux-android-ar --cc=aarch64-linux-android24-clang --cxx=aarch64-linux-android24-clang++ --ranlib=aarch64-linux-android-ranlib --strip=aarch64-linux-android-strip --nm=aarch64-linux-android-nm --extra-libs='-L/home/taner/Projects/ffmpeg-kit/prebuilt/android-arm64/cpu-features/lib -lndk_compat' --disable-autodetect --enable-cross-compile --enable-pic --enable-jni --enable-optimizations --enable-swscale --disable-static --enable-shared --enable-pthreads --enable-v4l2-m2m --disable-outdev=fbdev --disable-indev=fbdev --enable-small --disable-xmm-clobber-test --disable-debug --enable-lto --disable-neon-clobber-t
I/flutter ( 5432): XXXXXXXXXXXX fFmpeg XXXXXXXXXX  libavutil      57. 28.100 / 57. 28.100
I/flutter ( 5432): XXXXXXXXXXXX fFmpeg XXXXXXXXXX  libavcodec     59. 37.100 / 59. 37.100
I/flutter ( 5432): XXXXXXXXXXXX fFmpeg XXXXXXXXXX  libavformat    59. 27.100 / 59. 27.100
I/flutter ( 5432): XXXXXXXXXXXX fFmpeg XXXXXXXXXX  libavdevice    59.  7.100 / 59.  7.100
I/flutter ( 5432): XXXXXXXXXXXX fFmpeg XXXXXXXXXX  libavfilter     8. 44.100 /  8. 44.100
I/flutter ( 5432): XXXXXXXXXXXX fFmpeg XXXXXXXXXX  libswscale      6.  7.100 /  6.  7.100
I/flutter ( 5432): XXXXXXXXXXXX fFmpeg XXXXXXXXXX  libswresample   4.  7.100 /  4.  7.100
I/flutter ( 5432): XXXXXXXXXXXX fFmpeg XXXXXXXXXX [concat @ 0xb400007d62447910] Line 1: unknown keyword '/data/user/0/com.example.video_merger/cache/75f72300-1203-4e2c-93cf-65777152f1d16524788775537818173.mp4'
I/flutter ( 5432): XXXXXXXXXXXX fFmpeg XXXXXXXXXX /data/user/0/com.example.video_merger/app_flutter/my_file.txt: Invalid data found when processing input
I/flutter ( 5432): FFmpeg Process Exited With ReturnCode = 1

Solution

  • your text file format is not the one ffmpeg is expecting, you have to add file keyword before the file path like this

    file '/path/to/file1.wav'
    file '/path/to/file2.wav'
    file '/path/to/file3.wav'
    

    that's why in the logs it says unknown keyword

    Link for ref