pro_video_editor 0.4.0 copy "pro_video_editor: ^0.4.0" to clipboard
pro_video_editor: ^0.4.0 copied to clipboard

A Flutter video editor: Seamlessly enhance your videos with user-friendly editing features.

Logo

pub package Sponsor License GitHub issues

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.

Table of contents #

Preview #

Basic-Editor Grounded-Design Paint-Editor
Main-Editor Grounded-Editor Paint-Editor
Crop-Rotate-Editor Tune-Editor Filter-Editor
Crop-Rotate-Editor Tune-Editor Filter-Editor
Paint-Editor-Grounded Emoji-Editor
Paint-Editor-Grounded Emoji-Editor

Features #

๐ŸŽฅ Video Editing Capabilities

  • ๐Ÿ“ˆ 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.

๐Ÿ”ง Transformations

  • โœ‚๏ธ Crop by x, y, width, and height
  • ๐Ÿ” Flip horizontally and/or vertically
  • ๐Ÿ”„ Rotate by 90deg turns
  • ๐Ÿ” Scale to a custom size

๐ŸŽจ Visual Effects

  • ๐Ÿ–ผ๏ธ 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.

๐Ÿ“ฑ Runtime Features

  • ๐Ÿ“Š Progress: Track the progress of one or multiple running tasks.
  • ๐Ÿงต Multi-Tasking: Execute multiple video processing tasks concurrently.

Platform Support #

Method Android iOS macOS Windows Linux Web
Metadata โœ… โœ… โœ… โœ… โš ๏ธ โœ…
Thumbnails โœ… โœ… โœ… โŒ โŒ โœ…
KeyFrames โœ… โœ… โœ… โŒ โŒ โœ…
Rotate โœ… โœ… โœ… โŒ โŒ ๐Ÿšซ
Flip โœ… โœ… โœ… โŒ โŒ ๐Ÿšซ
Crop โœ… โœ… โœ… โŒ โŒ ๐Ÿšซ
Scale โœ… โœ… โœ… โŒ โŒ ๐Ÿšซ
Trim โœ… โœ… โœ… โŒ โŒ ๐Ÿšซ
Playback-Speed โœ… โœ… โœ… โŒ โŒ ๐Ÿšซ
Remove-Audio โœ… โœ… โœ… โŒ โŒ ๐Ÿšซ
Overlay Layers โœ… โœ… โœ… โŒ โŒ ๐Ÿšซ
Multiple ColorMatrix 4x5 โœ… โœ… โœ… โŒ โŒ ๐Ÿšซ
Cancel export task โœ… โœ… โœ… โŒ โŒ ๐Ÿšซ
Blur background ๐Ÿงช ๐Ÿงช ๐Ÿงช โŒ โŒ ๐Ÿšซ
Custom Audio Tracks โŒ โŒ โŒ โŒ โŒ ๐Ÿšซ
Merge Videos โŒ โŒ โŒ โŒ โŒ ๐Ÿšซ
Censor-Layers "Pixelate" โŒ โŒ โŒ โŒ โŒ ๐Ÿšซ

Legend

  • โœ… 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

Setup #

Android, iOS, macOS, Linux, Windows, Web

No additional setup required.

Usage #

Basic Example

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);

/// If you're rendering larger videos, it's better to write them directly to a file
/// instead of returning them as a Uint8List, as this can overload your RAM.
///
/// final directory = await getTemporaryDirectory();
/// String outputPath = '${directory.path}/my_video.mp4';
///
/// await ProVideoEditor.instance.renderVideoToFile('${directory.path}/my_video.mp4', data);

/// Listen progress
StreamBuilder<ProgressModel>(
    stream: ProVideoEditor.instance.progressStream,
    builder: (context, snapshot) {
      var progress = snapshot.data?.progress ?? 0;
      return CircularProgressIndicator(value: animatedValue);
    }
)

Quality Preset Example

/// Use quality presets for simplified video export configuration
/// Available presets: ultra4K, k4, p1080High, p1080, p720High, p720, p480, low, custom

var data = RenderVideoModel.withQualityPreset(
    video: EditorVideo.asset('assets/my-video.mp4'),
    qualityPreset: VideoQualityPreset.p1080,  // 1080p at 8 Mbps
    startTime: const Duration(seconds: 5),
    endTime: const Duration(seconds: 20),
);

Uint8List result = await ProVideoEditor.instance.renderVideo(data);

/// Override the preset's bitrate if needed
var customData = RenderVideoModel.withQualityPreset(
    video: EditorVideo.asset('assets/my-video.mp4'),
    qualityPreset: VideoQualityPreset.p720,
    bitrateOverride: 5000000,  // 5 Mbps instead of default 3 Mbps
);

Cancel an active render

The cancel API is currently implemented only on Android, iOS, and macOS. On Windows, Linux, and Web, cancel is not wired up yet, so callers should either:

  • gate by platform before calling cancel, or
  • be prepared to handle a PlatformException / UnimplementedError.

When you cancel a render started with renderVideoToFile, the returned Future completes with a RenderCanceledException. If your UI is awaiting that future directly (instead of using unawaited), make sure to catch this exception so you can reset any loading state cleanly rather than treating it as an error.

final renderModel = RenderVideoModel(
  video: EditorVideo.asset('assets/sample.mp4'),
);

final outputPath = '${(await getTemporaryDirectory()).path}/video.mp4';

// Start the render. Keep the model.id so you can cancel it later.
final renderFuture = ProVideoEditor.instance.renderVideoToFile(
  outputPath,
  renderModel,
);

// Option 1: fire-and-forget (example app pattern).
unawaited(renderFuture);

// Option 2: if you await directly, handle cancellation:
try {
  await renderFuture;
} on RenderCanceledException {
  // User canceled: reset UI state, do not treat as an error.
}

// ...from a UI callback (Android/iOS/macOS only)
if (Platform.isAndroid || Platform.isIOS || Platform.isMacOS) {
  await ProVideoEditor.instance.cancel(renderModel.id);
}

Advanced Example

/// 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,
                ),
              )
            ],
          );
        });
    }
)

Editor Example

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.

Metadata Example

VideoMetadata result = await ProVideoEditor.instance.getMetadata(
    video: EditorVideo.asset('assets/my-video.mp4'),
);

Thumbnails Example

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,
    ),
);

Keyframes Example

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,
    ),
);

Sponsors #

Included Packages #

A big thanks to the authors of these amazing packages.

Contributors #

Made with contrib.rocks.

60
likes
160
points
7.18k
downloads
screenshot

Publisher

verified publisherwaio.ch

Weekly Downloads

A Flutter video editor: Seamlessly enhance your videos with user-friendly editing features.

Repository (GitHub)
View/report issues

Topics

#video-editor #video #movie #editor

Documentation

Documentation
API reference

Funding

Consider supporting this project:

github.com

License

BSD-3-Clause (license)

Dependencies

flutter, flutter_web_plugins, http, mime, path_provider, plugin_platform_interface, web

More

Packages that depend on pro_video_editor

Packages that implement pro_video_editor