flutter_compress 1.1.0 copy "flutter_compress: ^1.1.0" to clipboard
flutter_compress: ^1.1.0 copied to clipboard

Native video & image compression for Android, iOS & Web — no FFmpeg. Target-size/bitrate/quality control, HEVC with H.264 fallback, live progress and cancellation.

flutter_compress #

pub package platform license

One plugin to compress both video and images — on Android, iOS and Web — with no FFmpeg.

Every platform uses its own hardware-accelerated encoder, so output is fast, small, and native-quality — with no 20 MB FFmpeg binary, no GPL, and nothing extra to ship. And the API speaks intent — "make it ~10 MB", "half the bitrate", "under 200 KB" — instead of making you guess at opaque quality knobs.

中文文档见 README.zh-CN.md

🌐 Try the live web demo in your browser →

Preview 1 Preview 2

Why flutter_compress? #

  • 🪶 No FFmpeg, no GPL, no bloat — nothing to bundle beyond the OS encoders your users already have. Your app stays small and license-clean.
  • 🌍 One API, three platforms — the same Dart code runs on Android, iOS and the browser (via WebCodecs). Most alternatives skip Web entirely.
  • 🎯 Hit a target size, precisely — ask for a size and the plugin derives the bitrate with identical math on every platform.
  • 🎬🖼️ Video and images — two dedicated, non-overlapping APIs (compress vs compressImage), each tuned for its medium.
  • 📡 Production-ready — live progress, cancellation, sequential batching, background-safe on mobile, and a keep-original-if-larger guard.

Under the hood #

Platform Video engine Image engine
Android Media3 Transformer (Google-maintained, HW-accelerated) Bitmap
iOS explicit AVAssetReader/AVAssetWriter (real bitrate control) ImageIO
Web WebCodecs + mp4box.js / mp4-muxer (~0.2 MB, no FFmpeg) Canvas

Features #

🎬 Video — compress #

  • 🎯 Target size, or explicit bitrate, quality %, or preset tiers.
  • 🧬 HEVC (H.265) with automatic H.264 fallback on all platforms.
  • 📉 Resolution cap, frame-rate cap, audio removal, trim, ÷16 alignment.
  • 🖼️ Thumbnails, media info, and a pre-flight size estimate (no encoding).
  • 📡 Live progress, cancellation, and sequential batch.

🖼️ Image — compressImage #

  • 🎯 Target size (precise — the engine iterates on quality, then downscales) or quality.
  • 🎞️ Formats: JPEG · PNG · WebP · HEIC (auto-fallback where unsupported).
  • 📐 Resolution cap and optional EXIF keep (orientation, GPS…).
  • ⚡ Millisecond-fast, single-image or batch.

Platform support #

🎬 Video #

Capability Android iOS Web
Compress (target size / bitrate / quality)
HEVC (H.265) with H.264 fallback
Resolution cap (maxWidth/maxHeight)
Frame-rate cap (frameRate) ⚠️
Audio: remove / bitrate ⚠️
Trim (trim)
Thumbnail / info / estimate
Progress / cancel / batch
Background compression ✅ foreground service ✅ background task n/a
saveToDownloads MediaStore Documents browser download

¹ Web uses HEVC only where the browser supports WebCodecs HEVC encoding (e.g. Safari, Chrome with HW HEVC); otherwise it falls back to H.264.

🖼️ Image #

Capability Android iOS Web
Compress (target size / quality)
JPEG / PNG / WebP
HEIC ⚠️
Resolution cap (maxWidth/maxHeight)
Keep EXIF (keepExif)
saveToDownloads MediaStore Documents browser download

¹ Android only writes HEIC when a device HEIC encoder is present; otherwise the engine falls back to JPEG (the actual format is reported on the result).

Install #

dependencies:
  flutter_compress: ^1.1.0

Quick start #

import 'package:flutter_compress/flutter_compress.dart';

final result = await FlutterCompress.instance.compress(
  inputPath,
  const VideoCompressConfig(
    targetSizeMB: 10,          // highest-priority size control
    codec: VideoCodec.h265,    // auto-falls-back to H.264
    maxWidth: 1280,            // downscale-only
    maxHeight: 1280,
  ),
  onProgress: (p) => debugPrint('${(p.progress * 100).toStringAsFixed(0)}%'),
);

print('saved ${result.savedPercent.toStringAsFixed(1)}% → ${result.outputPath}');

Configuration #

VideoCompressConfig — set one size/quality control; priority is:

targetSizeMBvideoBitrateKbpsqualityPercentquality

Field Meaning
targetSizeMB Desired output size; the plugin derives the bitrate.
videoBitrateKbps Explicit average video bitrate.
qualityPercent Output bitrate = percent% of the source bitrate (1–100).
quality Preset tier: high / medium / low / veryLow.
codec h265 (default, auto-fallback) or h264.
maxWidth / maxHeight Cap dimensions; aspect kept, only ever scales down.
frameRate Cap the fps.
removeAudio / audioBitrateKbps Drop or re-encode audio.
trim TrimRange(startMs, endMs).
alignment auto16 (default) rounds to ÷16 to avoid edge artifacts.
keepOriginalIfLarger Return the original if compression wouldn't help.

API #

final api = FlutterCompress.instance;

// Probe & estimate (no encoding)
final VideoInfo info = await api.getVideoInfo(path);
final CompressionEstimate est = await api.estimate(path, config);

// Compress (single)
final token = CancellationToken();
final result = await api.compress(
  path, config,
  onProgress: (p) => print(p.progress),   // 0.0–1.0
  cancellationToken: token,
  outputDirectory: dir,                    // optional
);
await token.cancel();                      // aborts the job above

// Batch (sequential), thumbnails, housekeeping
await api.compressAll(paths, config);
final String thumb = await api.getThumbnail(path, positionMs: 1000, maxWidth: 320);
final String saved = await api.saveToDownloads(result.outputPath);
await api.clearCache();

// Global progress feed (e.g. for a batch UI)
api.progressStream.listen((p) => print('${p.id} ${p.progress}'));

Images #

The image API is fully separate from the video one.

final api = FlutterCompress.instance;

// Probe (no encoding)
final ImageMeta meta = await api.getImageInfo(path);

// Compress to a target size (precise — images encode fast, so the engine
// binary-searches quality, then downscales if needed to land under it).
final ImageCompressResult r = await api.compressImage(
  path,
  const ImageCompressConfig(
    format: ImageFormat.jpeg,   // jpeg / png / webp / heic
    targetSizeKB: 200,          // highest-priority size control
    maxWidth: 2560,             // downscale-only
    maxHeight: 2560,
  ),
  outputDirectory: dir,         // optional; null → plugin cache
);
print('${r.format} ${r.width}x${r.height} • saved ${r.savedPercent.toStringAsFixed(1)}%');

// Or control quality directly, and batch:
await api.compressImage(path, const ImageCompressConfig(quality: 80));
await api.compressImages(paths, const ImageCompressConfig(format: ImageFormat.webp));

ImageCompressConfig — priority is targetSizeKBquality:

Field Meaning
format jpeg (default) / png / webp / heic.
targetSizeKB Desired output size; the engine iterates to land at/under it.
quality 1–100, used when targetSizeKB is null (ignored for PNG).
maxWidth / maxHeight Cap dimensions; aspect kept, only scales down.
keepExif Keep EXIF (orientation, GPS, …); default strips it.

Platform setup #

  • Android — min SDK 24, compileSdk 36. The plugin declares FOREGROUND_SERVICE, FOREGROUND_SERVICE_DATA_SYNC, POST_NOTIFICATIONS, and (for saveToDownloads on API ≤ 28) WRITE_EXTERNAL_STORAGE.
  • iOS — min 13.0. Uses beginBackgroundTask for a short background grace period. To make saveToDownloads files visible in the Files app, add UIFileSharingEnabled and LSSupportsOpeningDocumentsInPlace to Info.plist.
  • Web — needs WebCodecs (Chrome/Edge 94+, Safari 16.4+). Inputs/outputs are blob: URLs; the vendored demux/mux JS (~0.2 MB) loads lazily on first use. Pick a file via file_picker and pass xFile.path (a blob: URL on web). Try the live demo to see it in action.

Known limitations #

  • Web (v1): audio is dropped and trim is not yet applied.

License #

MIT — see LICENSE.

0
likes
160
points
103
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Native video & image compression for Android, iOS & Web — no FFmpeg. Target-size/bitrate/quality control, HEVC with H.264 fallback, live progress and cancellation.

Repository (GitHub)
View/report issues

Topics

#video #compression #video-compression #media #transcoder

License

MIT (license)

Dependencies

flutter, flutter_web_plugins, plugin_platform_interface, web

More

Packages that depend on flutter_compress

Packages that implement flutter_compress