Video processing is one of the most resource-intensive tasks, especially in terms of RAM and CPU usage. Without proper optimization, your application can easily crash. During development, I encountered issues when using third-party libraries from Pub.dev to:
Convert videos into GIFs.
Convert a list of images into a video.
These libraries often take a long time to process and produce results that do not meet the desired quality. However, with FFmpeg, you can efficiently solve these issues.
Introduction to FFmpeg
is a powerful open-source library designed for audio and video processing. FFmpeg supports various tasks such as:
Format conversion (MP4, MKV, MP3, etc.).
Video and audio processing: Adding watermarks, trimming, merging, and compressing.
Creating GIFs from videos.
Streaming and media optimization.
The package brings the full capabilities of FFmpeg to Flutter. Additionally, you can explore other packages at .
Installing the FFmpeg Toolkit
Note: This guide is based on Flutter 3.24.5 and ffmpeg_kit_flutter_full_gpl 6.0.3. It appears that newer versions of Flutter may not work well with this library.
Installation
Add the dependency to your pubspec.yaml file:
ffmpeg_kit_flutter_full_gpl: ^latest_version
Run the following command:
flutter pub get
Android Configuration
Add the following to your android/app/build.gradle file:
<key>NSPhotoLibraryUsageDescription</key>
<string>We need access to your photo library to pick files.</string>
<key>NSDocumentDirectoryUsageDescription</key>
<string>We need access to your documents to pick files.</string>
<key>UIFileSharingEnabled</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
Ensure that your ios/Podfile specifies the platform version:
platform :ios, '13.0'
Convert a Sequence of Images to Video
Below is a function to convert a list of images into a video.
My idea is to store all images in a directory, and FFmpegKit will read them to create a video.
final result = convertImageDirectoryToVideo(
imagesPath: "path/to/images",
outputVideoPath: "path/to/videoOutput.mp4",
);
Ensure that the directory path/to/images contains images named with sequential numbers and in .png format, as illustrated in the example:
The output file path/to/videoOutput.mp4 must have a unique name to avoid errors during FFmpeg processing.
In the command above, the images will be automatically resized to match an even-numbered resolution. You can modify the command as needed.
Add a Watermark to a Video
Function to Add Watermark
Future<({bool isSuccess, String message})> addWatermarkToVideo({
required String videoPath,
required String watermarkPath,
required String outputPath,
required int x,
required int y,
int? width,
int? height,
}) async {
var isSuccess = false;
var message = "";
final scaleFilter = (width != null && height != null)
? "[1:v]scale=$width:$height[wm];[0:v][wm]overlay=$x:$y"
: "overlay=$x:$y";
final command =
'-i $videoPath -i $watermarkPath -filter_complex "$scaleFilter" -codec:a copy $outputPath';
await FFmpegKit.execute(command).then((session) async {
final returnCode = await session.getReturnCode();
if (returnCode?.isValueSuccess() ?? false) {
message = "Watermark added successfully!";
isSuccess = true;
} else {
message = "Failed to add watermark.";
}
});
return (isSuccess: isSuccess, message: message);
}
Example Usage
final result = addWatermarkToVideo(
videoPath: videoPath!,
watermarkPath: watermarkPath!,
outputPath: outputPath,
x: 20,
y: 30,
width: 200,
height: 200,
);
x, y: Coordinates of the watermark.
width, height: Dimensions of the watermark (optional).