Skip to content

Instantly share code, notes, and snippets.

@ianholing
Last active May 26, 2022 08:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ianholing/8d416f2bde6e4402c787731f655db19b to your computer and use it in GitHub Desktop.
Save ianholing/8d416f2bde6e4402c787731f655db19b to your computer and use it in GitHub Desktop.
AvatART App realtime video encoding with flutter ffmpeg
Future<String> generateVideo(String videoPath, List<StyleChangeRecord> videoChangeRecords, Function(data.Stack<ProgressItem> progress) callback) async {
await _checkDirs();
_cleanBasePathWithFilter(".aac");
_pushProgress(ProgressItem("Transformation Step", 1, 4, "Clean folder.."), callback);
List<Future> futures = <Future>[];
new Directory('$basePath/$_framesFolder').listSync().forEach((frame) async {
if (FileSystemEntity.typeSync(frame.path) == FileSystemEntityType.file) {
futures.add((frame as File).delete());
}
});
print ("Wait for delete files");
Future.wait(futures);
if (videoPath == "" || !File(videoPath).existsSync()) {
videoPath = new Directory('$basePath')
.listSync()
.firstWhere((element) => element.path.endsWith("mp4"))
.path;
}
print ("Original video path: $videoPath");
DateTime now = DateTime.now();
var currentTime = new DateTime(now.year, now.month, now.day, now.hour, now.minute, now.second);
var destinPath = basePath +"/AvatART_${currentTime.toString().replaceAll(" ", "_")}.mp4";
print ("Destination video path: $destinPath");
_updateProgress("Creating frames..", callback);
final FlutterFFmpeg _flutterFFmpeg = new FlutterFFmpeg();
var _framesDir = await new Directory('$basePath/$_framesFolder').create();
var rc = await _flutterFFmpeg.execute("-i $videoPath -vf fps=$fps ${_framesDir.path}/out%d.png");
print ("FFMPEG 1 SAYS (0 = OK): " + rc.toString());
_updateProgress("Extracting audio..", callback);
rc = await _flutterFFmpeg.execute("-i $videoPath $basePath/audio.aac");
print ("FFMPEG 2 SAYS (0 = OK): " + rc.toString());
_updateProgress("Style transformations..", callback);
await _processFileList(_framesDir.listSync(), videoChangeRecords, callback);
_updateProgress("Merge results..", callback);
final watermarkPath = await _checkWatermarkExist(videoPath);
print ("WATERMARK APPLIED: $watermarkPath");
rc = await _flutterFFmpeg.execute("-i ${_framesDir.path}/out%d.png -i $basePath/audio.aac -pix_fmt yuv420p -r $fps -shortest -y $basePath/preview.mp4");
print ("FFMPEG 3 SAYS (0 = OK): " + rc.toString());
_updateProgress("Finish processing..", callback);
rc = await _flutterFFmpeg.execute("-i $basePath/preview.mp4 -i $watermarkPath -filter_complex \"overlay=0:0\" $destinPath");
print ("FFMPEG 4 SAYS (0 = OK): " + rc.toString());
return destinPath;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment