4

I need to merge (concatenate) two audio files in a Flutter app.

I am trying to use Flutter_ffmpeg package .

https://pub.dev/packages/flutter_ffmpeg

Ffmpeg is powerful tool for audio and video.

flutter_cache_manager package to store the files that came from https

https://pub.dev/packages/flutter_cache_manager

And path provided to deal with the paths

https://pub.dev/packages/path_provider

For the part of caching I already made some successful tests,

But, I need your help to understand how can I use ffmpeg package.
According to the readme I need to do something like

import 'package:flutter_ffmpeg/flutter_ffmpeg.dart';

final FlutterFFmpeg _flutterFFmpeg = new FlutterFFmpeg(); 
var fileCached1 = await DefaultCacheManager().getSingleFile(url1);
var fileCached2 = await DefaultCacheManager().getSingleFile(url2);
var arguments = ["-i", "concat:fileCached1.wav|fileCached2.wav", "-c copy", "output.way"];
_flutterFFmpeg.executeWithArguments(arguments ).then((rc) => print("FFmpeg process exited with rc $rc"));

How can I have access to the output.wav to play? How can I use the path_provider?

I really need you help. :) There is little information about flutter_ffmpeg. This question might be useful for someone else to.

Thanks in advance, Ricardo

Russell Ghana
  • 2,963
  • 3
  • 20
  • 31
Richardd
  • 956
  • 14
  • 27
  • How do you provide input files to ffmpeg command? DefaultCacheManager.getSingleFile() is for which package and does it accept url as url of image assets? – Utsavkumar Lal Sep 21 '22 at 11:39

2 Answers2

7

The path_provider package let you to access appDir & temp directory of your application, let say that you want to access the application documents directory :

Directory appDocumentDir = await getApplicationDocumentsDirectory();
String rawDocumentPath = appDocumentDir.path;

and if your output's file name is "output.wav"

String outputPath = Strings.concatAll([rawDocumentPath, "/output.wav"]);

now outputPath contain the path to output file that will be generated by FFMPEG and you can use it later when you want to play/copy/upload or whatever you want to.

but in the FFMPEG part, the command line for concat two input file is:

ffmpeg -i input1.wav -i input2.wav -filter_complex '[0:0][1:0]concat=n=2:v=0:a=1[out]' -map '[out]' output.wav

If you want to have 3 input files, use n=3 and change the other parts in command.

usage of Flutter_ffmpeg will be something like this:

import 'package:flutter_ffmpeg/flutter_ffmpeg.dart';

final FlutterFFmpeg _flutterFFmpeg = new FlutterFFmpeg();

_flutterFFmpeg.execute("-i input1.wav -i input2.wav -filter_complex '[0:0][1:0]concat=n=2:v=0:a=1[out]' -map '[out]' output.wav").then((rc) => print("FFmpeg process exited with rc $rc"));

ideally we want to use outputPath here so do something like this :

String commandToExecute = Strings.concatAll(["-i input1.wav -i input2.wav -filter_complex '[0:0][1:0]concat=n=2:v=0:a=1[out]' -map '[out]' ", outputPath]);

and your final statement for executing the process will be :

_flutterFFmpeg.execute(commandToExecute).then((rc) => print("FFmpeg process exited with rc $rc"));

after execution you can check execution output. Zero represents successful execution, 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"));

so in case of failure or getting error, you can check the command output for fixing bugs

you can find more information about flutter_ffmpeg in here :

https://pub.dev/packages/flutter_ffmpeg

also for using ffmpeg and find more about filters you can check this out :

https://ffmpeg.org/ffmpeg-filters.html

Russell Ghana
  • 2,963
  • 3
  • 20
  • 31
  • Hi Rasool Ghana! Thanks for your very clear and well structured answer. I am trying it. Soon I will give feedback. Thanks for your time. – Richardd Mar 21 '20 at 00:18
  • Hi Rasool! I am more than happy with your very professional explanation. You really helped me. Thanks, have a good day! – Richardd Mar 21 '20 at 11:11
0

First get the directory

final appDirectory = await getExternalStorageDirectory();

Then in the execute commands append the output file with directory.

_flutterFFmpeg.execute("-i $videoURL -i $audioURL -c copy ${appDirectory?.path}/output.mp4");