exportVideo method
Export the video using this edition parameters and return a File
.
The onCompleted
param must be set to return the exported File video.
The onError
function provides the Exception and StackTrace that causes the exportation error.
If the name
is null
, then it uses this video filename.
If the outDir
is null
, then it uses TemporaryDirectory
.
The format
of the video to be exported, by default mp4
.
The scale
is scale=width*scale:height*scale
and reduce or increase video size.
The customInstruction
param can be set to add custom commands to the FFmpeg eexecution
(i.e. -an
to mute the generated video), some commands require the GPL package
The onProgress
is called while the video is exporting.
This argument is usually used to update the export progress percentage.
This function return Statistics
from FFmpeg session and the double progress value between 0.0 and 1.0.
The preset
is the compress quality
(Only available on GPL package).
A slower preset will provide better compression (compression is quality per filesize).
More info about presets
Set isFiltersEnabled
to false
if you do not want to apply any changes
Implementation
Future<void> exportVideo({
required void Function(File file) onCompleted,
void Function(Object, StackTrace)? onError,
String? name,
String? outDir,
String format = "mp4",
double scale = 1.0,
String? customInstruction,
void Function(Statistics, double)? onProgress,
VideoExportPreset preset = VideoExportPreset.none,
bool isFiltersEnabled = true,
}) async {
final String tempPath = outDir ?? (await getTemporaryDirectory()).path;
final String videoPath = file.path;
name ??= path.basenameWithoutExtension(videoPath);
final int epoch = DateTime.now().millisecondsSinceEpoch;
final String outputPath = "$tempPath/${name}_$epoch.$format";
// CALCULATE FILTERS
final String gif = format != "gif" ? "" : "fps=10 -loop 0";
final String trim = minTrim >= _min.dx && maxTrim <= _max.dx
? "-ss $_trimStart -to $_trimEnd"
: "";
final String crop = minCrop >= _min && maxCrop <= _max ? _getCrop() : "";
final String rotation =
_rotation >= 360 || _rotation <= 0 ? "" : _getRotation();
final String scaleInstruction =
scale == 1.0 ? "" : "scale=iw*$scale:ih*$scale";
// VALIDATE FILTERS
final List<String> filters = [crop, scaleInstruction, rotation, gif];
filters.removeWhere((item) => item.isEmpty);
final String filter = filters.isNotEmpty && isFiltersEnabled
? "-filter:v ${filters.join(",")}"
: "";
final String execute =
// ignore: unnecessary_string_escapes
" -i \'$videoPath\' ${customInstruction ?? ""} $filter ${_getPreset(preset)} $trim -y \"$outputPath\"";
// PROGRESS CALLBACKS
FFmpegKit.executeAsync(
execute,
(session) async {
final state =
FFmpegKitConfig.sessionStateToString(await session.getState());
final code = await session.getReturnCode();
if (ReturnCode.isSuccess(code)) {
onCompleted(File(outputPath));
} else {
if (onError != null) {
onError(
Exception(
'FFmpeg process exited with state $state and return code $code.\n${await session.getOutput()}'),
StackTrace.current,
);
}
return;
}
},
null,
onProgress != null
? (stats) {
// Progress value of encoded video
double progressValue =
stats.getTime() / (_trimEnd - _trimStart).inMilliseconds;
onProgress(stats, progressValue.clamp(0.0, 1.0));
}
: null,
);
}