The ProVideoEditor is a Flutter widget designed for video editing within your application. It provides a flexible and convenient way to integrate video editing capabilities into your Flutter project.
- 📷 Preview
- ✨ Features
- 🔧 Setup
- ❓ Usage
- 💖 Sponsors
- 📦 Included Packages
- 🤝 Contributors
- 📜 License
- 📜 Notices
Basic-Editor | Grounded-Design | Paint-Editor |
---|---|---|
![]() |
![]() |
![]() |
Crop-Rotate-Editor | Tune-Editor | Filter-Editor |
---|---|---|
![]() |
![]() |
![]() |
Paint-Editor-Grounded | Emoji-Editor | |
---|---|---|
![]() |
![]() |
- 📈 Metadata: Extract detailed metadata from the video file.
- 🖼️ Thumbnails: Generate one or multiple thumbnails from the video.
- 🎞️ Keyframes: Retrieve keyframe information from the video.
- ✂️ Trim: Cut the video to a specified start and end time.
- ⏩ Playback Speed: Adjust the playback speed of the video.
- 🔇 Mute Audio: Remove or mute the audio track from the video.
- ✂️ Crop by
x
,y
,width
, andheight
- 🔁 Flip horizontally and/or vertically
- 🔄 Rotate by 90deg turns
- 🔍 Scale to a custom size
- 🖼️ Layers: Overlay a image like a text or drawings on the video.
- 🧮 Color Matrix: Apply one or multiple 4x5 color matrices (e.g., for filters).
- 💧 Blur: Add a blur effect to the video.
- 📡 Bitrate: Set a custom video bitrate. If constant bitrate (CBR) isn't supported, it will gracefully fall back to the next available mode.
- 📊 Progress: Track the progress of one or multiple running tasks.
- 🧵 Multi-Tasking: Execute multiple video processing tasks concurrently.
Method | Android | iOS | macOS | Windows | Linux | Web |
---|---|---|---|---|---|---|
Metadata |
✅ | ✅ | ✅ | ✅ | ✅ | |
Thumbnails |
✅ | ✅ | ✅ | ❌ | ❌ | ✅ |
KeyFrames |
✅ | ✅ | ✅ | ❌ | ❌ | ✅ |
Rotate |
✅ | ✅ | ✅ | ❌ | ❌ | 🚫 |
Flip |
✅ | ✅ | ✅ | ❌ | ❌ | 🚫 |
Crop |
✅ | ✅ | ✅ | ❌ | ❌ | 🚫 |
Scale |
✅ | ✅ | ✅ | ❌ | ❌ | 🚫 |
Trim |
✅ | ✅ | ✅ | ❌ | ❌ | 🚫 |
Playback-Speed |
✅ | ✅ | ✅ | ❌ | ❌ | 🚫 |
Remove-Audio |
✅ | ✅ | ✅ | ❌ | ❌ | 🚫 |
Overlay Layers |
✅ | ✅ | ✅ | ❌ | ❌ | 🚫 |
Multiple ColorMatrix 4x5 |
✅ | ✅ | ✅ | ❌ | ❌ | 🚫 |
Blur background |
🧪 | 🧪 | 🧪 | ❌ | ❌ | 🚫 |
Custom Audio Tracks |
❌ | ❌ | ❌ | ❌ | ❌ | 🚫 |
Merge Videos |
❌ | ❌ | ❌ | ❌ | ❌ | 🚫 |
Censor-Layers "Pixelate" |
❌ | ❌ | ❌ | ❌ | ❌ | 🚫 |
- ✅ Supported with Native-Code
⚠️ Supported with Native-Code but not tested- 🧪 Supported but visual output can differs from Flutter
- ❌ Not supported but planned
- 🚫 Not supported and not planned
No additional setup required.
var data = RenderVideoModel(
video: EditorVideo.asset('assets/my-video.mp4'),
// video: EditorVideo.file(File('/path/to/video.mp4')),
// video: EditorVideo.network('https://example.com/video.mp4'),
// video: EditorVideo.memory(videoBytes),
enableAudio: false,
startTime: const Duration(seconds: 5),
endTime: const Duration(seconds: 20),
);
Uint8List result = await ProVideoEditor.instance.renderVideo(data);
/// Listen progress
StreamBuilder<ProgressModel>(
stream: ProVideoEditor.instance.progressStream,
builder: (context, snapshot) {
var progress = snapshot.data?.progress ?? 0;
return CircularProgressIndicator(value: animatedValue);
}
)
/// Every option except videoBytes is optional.
var task = RenderVideoModel(
id: 'my-special-task'
video: EditorVideo.asset('assets/my-video.mp4'),
imageBytes: imageBytes, /// A image "Layer" which will overlay the video.
outputFormat: VideoOutputFormat.mp4,
enableAudio: false,
playbackSpeed: 2,
startTime: const Duration(seconds: 5),
endTime: const Duration(seconds: 20),
blur: 10,
bitrate: 5000000,
transform: const ExportTransform(
flipX: true,
flipY: true,
x: 10,
y: 20,
width: 300,
height: 400,
rotateTurns: 3,
scaleX: .5,
scaleY: .5,
),
colorMatrixList: [
[ 1.0, 0.0, 0.0, 0.0, 50.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 ],
[ 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 ],
],
);
Uint8List result = await ProVideoEditor.instance.renderVideo(task);
/// Listen progress
StreamBuilder<ProgressModel>(
stream: ProVideoEditor.instance.progressStreamById(task.id),
builder: (context, snapshot) {
var progress = snapshot.data?.progress ?? 0;
return TweenAnimationBuilder<double>(
tween: Tween<double>(begin: 0, end: progress),
duration: const Duration(milliseconds: 300),
builder: (context, animatedValue, _) {
return Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
spacing: 10,
children: [
CircularProgressIndicator(value: animatedValue),
Text(
'${(animatedValue * 100).toStringAsFixed(1)} / 100',
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
),
)
],
);
});
}
)
The video editor requires the use of the pro_image_editor. You can find the basic video editor example here and the "grounded" design example here.
You can also use other prebuilt designs from pro_image_editor, such as the WhatsApp or Frosted Glass design. Just check the examples in pro_image_editor to see how it's done.
VideoMetadata result = await ProVideoEditor.instance.getMetadata(
video: EditorVideo.asset('assets/my-video.mp4'),
);
List<Uint8List> result = await ProVideoEditor.instance.getThumbnails(
ThumbnailConfigs(
video: EditorVideo.asset('assets/my-video.mp4'),
outputFormat: ThumbnailFormat.jpeg,
timestamps: const [
Duration(seconds: 10),
Duration(seconds: 15),
Duration(seconds: 22),
],
outputSize: const Size(200, 200),
boxFit: ThumbnailBoxFit.cover,
),
);
List<Uint8List> result = await ProVideoEditor.instance.getKeyFrames(
KeyFramesConfigs(
video: EditorVideo.asset('assets/my-video.mp4'),
outputFormat: ThumbnailFormat.jpeg,
maxOutputFrames: 20,
outputSize: const Size(200, 200),
boxFit: ThumbnailBoxFit.cover,
),
);
A big thanks to the authors of these amazing packages.
- Packages created by the Dart team:
Made with contrib.rocks.