ffmpeg_helper
FFmpeg commands helper for flutter with support for setup on windows platform. Create thumbnail and run ffprobe on all platforms except WEB. This uses ffmpeg_kit_flutter_min_gpl package for android/ios/macos Info was taken from ffmpeg_cli and recreated it as that project was stale.
// Initialize
late FFMpegHelper ffmpeg;
@override
void initState() {
super.initState();
ffmpeg = FFMpegHelper(ffMpegConfigurator: FFMpegWindowsConfigurator());
}
// Command builder
// Use prebuilt args and filters or create custom ones
final FFMpegCommand cliCommand = FFMpegCommand(
inputs: [
FFMpegInput.asset(selectedFile!.path),
],
args: [
const LogLevelArgument(LogLevel.info),
const OverwriteArgument(),
const TrimArgument(
start: Duration(seconds: 0),
end: Duration(seconds: 10),
),
],
filterGraph: FilterGraph(
chains: [
FilterChain(
inputs: [],
filters: [
ScaleFilter(
height: 300,
width: -2,
),
],
outputs: [],
),
],
),
outputFilepath: path.join(appDocDir.path, "ffmpegtest.mp4"),
);
FFMpegHelperSession session = await ffmpeg.runAsync(
cliCommand,
statisticsCallback: (Statistics statistics) {
print('bitrate: ${statistics.getBitrate()}');
},
);
Thumbnail creator
// use ffmpeg.getThumbnailFileAsync() to get session
Future<FFMpegHelperSession> getThumbnailFileAsync({
required String videoPath,
required Duration fromDuration,
required String outputPath,
String? ffmpegPath,
FilterGraph? filterGraph,
int qualityPercentage = 100,
Function(Statistics statistics)? statisticsCallback,
Function(File? outputFile)? onComplete,
FFMpegConfigurator? ffMpegConfigurator,
})
// use ffmpeg.getThumbnailFileSync() to get thumbnail file
Future<File?> getThumbnailFileSync({
required String videoPath,
required Duration fromDuration,
required String outputPath,
String? ffmpegPath,
FilterGraph? filterGraph,
int qualityPercentage = 100,
Function(Statistics statistics)? statisticsCallback,
Function(File? outputFile)? onComplete,
FFMpegConfigurator? ffMpegConfigurator,
})
Run FFMpeg and get session so that user can cancel it later.
Future<FFMpegHelperSession> runAsync(
FFMpegCommand command, {
Function(Statistics statistics)? statisticsCallback,
Function(File? outputFile)? onComplete,
Function(Log)? logCallback,
})
Run FFMpeg as future.
Future<File?> runSync(
FFMpegCommand command, {
Function(Statistics statistics)? statisticsCallback,
})
Run ffprobe
Future<MediaInformation?> runProbe(String filePath)
Setup FFMPEG for windows
// check on windows
// bool isPresent = ffmpeg.checkFFMpeg();
Future<void> checkFFMpeg() async {
bool present = await ffmpeg.ffMpegConfigurator!.isFFMpegPresent();
ffmpegPresent = present;
if (present) {
print('ffmpeg available');
} else {
print('ffmpeg needs to setup');
}
setState(() {});
}
// Download on windows if ffmpeg is present (only check for windows)
Future<void> downloadFFMpeg() async {
await ffmpeg.ffMpegConfigurator!.initialize();
bool success = await ffmpeg.ffMpegConfigurator!.setupFFMpeg(
onProgress: (FFMpegProgress progress) {
downloadProgress.value = progress;
/* print(
'downloading ffmpeg: ${((received / total) * 100).toStringAsFixed(2)}'); */
},
);
setState(() {
ffmpegPresent = success;
});
}
// check setup progress on windows
// On windows if ffmpeg is not present it will download official zip file and extract on doc directory of app.
SizedBox(
width: 300,
child: ValueListenableBuilder(
valueListenable: downloadProgress,
builder: (BuildContext context, FFMpegProgress value, _) {
//print(value.downloaded / value.fileSize);
double? prog;
if ((value.downloaded != 0) && (value.fileSize != 0)) {
prog = value.downloaded / value.fileSize;
} else {
prog = 0;
}
if (value.phase == FFMpegProgressPhase.decompressing) {
prog = null;
}
if (value.phase == FFMpegProgressPhase.inactive) {
return const SizedBox.shrink();
}
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(value.phase.name),
const SizedBox(height: 5),
LinearProgressIndicator(value: prog),
],
);
},
),
),
Libraries
- abstract_classes/ffmpeg_arguments_abstract
- abstract_classes/ffmpeg_configurator_abstract
- abstract_classes/ffmpeg_filter_abstract
- colors
- ffmpeg/args/add_thumbnail_arg
- ffmpeg/args/audio_bitrate_arg
- ffmpeg/args/copy_acodec_arg
- ffmpeg/args/copy_vcodec_arg
- ffmpeg/args/crf_arg
- ffmpeg/args/custom_arg
- ffmpeg/args/gif_arg
- ffmpeg/args/log_level_arg
- ffmpeg/args/overwrite_arg
- ffmpeg/args/preset_arg
- ffmpeg/args/progress_arg
- ffmpeg/args/remove_audio_arg
- ffmpeg/args/remove_video_arg
- ffmpeg/args/seek_arg
- ffmpeg/args/trim_arg
- ffmpeg/args/video_bitrate_arg
- ffmpeg/ffmpeg_command
- ffmpeg/ffmpeg_command_builder
- ffmpeg/ffmpeg_filter_chain
- ffmpeg/ffmpeg_filter_graph
- ffmpeg/ffmpeg_input
- ffmpeg/ffmpeg_stream
- ffmpeg/ffmpeg_windows_configurator
- ffmpeg/filters/crop_filter
- ffmpeg/filters/custom_filter
- ffmpeg/filters/fps_filter
- ffmpeg/filters/hflip_filter
- ffmpeg/filters/null_filter
- ffmpeg/filters/rotation_filter
- ffmpeg/filters/scale_filter
- ffmpeg/filters/vflip_filter
- ffmpeg/filters/volume_filter
- ffmpeg_helper
- helpers/ffmpeg_helper_class
- helpers/helper_sessions
- logging
- time