media_compressor 1.0.1 copy "media_compressor: ^1.0.1" to clipboard
media_compressor: ^1.0.1 copied to clipboard

A Flutter plugin for efficient image and video compression

Media Compressor #

A Flutter plugin for compressing images and videos efficiently using native platform implementations.

Demo #

See the plugin in action:

Image Compression Demo Video Compression Demo

Latest Updates #

v1.0.1 (Current) #

  • πŸ› Bug Fix: Fixed iOS compilation error by adding missing Flutter framework import
  • βœ… All functionality working as expected on both platforms

Features #

βœ… Image Compression - Compress images with quality and dimension control
βœ… Video Compression - Compress videos with quality presets
βœ… Native Performance - Uses platform-specific compression for optimal results
βœ… Error Handling - Comprehensive error handling with detailed error messages
βœ… Cross-platform - Supports both Android and iOS
βœ… EXIF Orientation - Automatic correction of image orientation

Installation #

Add this to your package's pubspec.yaml file:

dependencies:
  media_compressor: ^1.0.0

Then run:

flutter pub get

Usage #

Import the Package #

import 'package:media_compressor/media_compressor.dart';

Compress an Image #

final result = await MediaCompressor.compressImage(
  ImageCompressionConfig(
    path: '/path/to/image.jpg',
    quality: 80,           // 0-100, where 100 is best quality
    maxWidth: 1920,        // Optional: max width in pixels
    maxHeight: 1080,       // Optional: max height in pixels
  ),
);

if (result.isSuccess) {
  print('Compressed image saved at: ${result.path}');
} else {
  print('Compression failed: ${result.error?.message}');
}

Compress a Video #

final result = await MediaCompressor.compressVideo(
  VideoCompressionConfig(
    path: '/path/to/video.mp4',
    quality: VideoQuality.medium,  // low, medium, high
  ),
);

if (result.isSuccess) {
  print('Compressed video saved at: ${result.path}');
} else {
  print('Compression failed: ${result.error?.message}');
}

Video Quality Presets #

The VideoQuality enum provides three quality levels:

enum VideoQuality {
  low,     // Lower bitrate, smaller file size
  medium,  // Balanced quality and size (recommended)
  high,    // Higher quality, larger file size
}

// Usage examples:
VideoCompressionConfig(
  path: '/path/to/video.mp4',
  quality: VideoQuality.low,     // For quick sharing, previews
)

VideoCompressionConfig(
  path: '/path/to/video.mp4',
  quality: VideoQuality.medium,  // Default - best for most cases
)

VideoCompressionConfig(
  path: '/path/to/video.mp4',
  quality: VideoQuality.high,    // For high-quality archival
)

Compression Result #

All compression methods return a CompressionResult object:

class CompressionResult {
  final bool isSuccess;
  final String? path;              // Path to compressed file
  final CompressionError? error;   // Error details if failed
  
  // Helper getters
  bool get isFailure => !isSuccess;
}

Error Handling #

class CompressionError {
  final String code;      // Error code for programmatic handling
  final String message;   // Human-readable error message
  final dynamic details;  // Additional error details
}

Common error codes:

  • INVALID_ARGUMENT - Invalid arguments provided (e.g., missing path, quality out of range, invalid dimensions)
  • COMPRESSION_ERROR - Native compression failed
  • FILE_NOT_FOUND - Input file doesn't exist at the specified path
  • NULL_RESULT - Compression returned null or empty result
  • TIMEOUT - Video compression exceeded timeout
  • UNKNOWN_ERROR - Unexpected error occurred

Platform-specific Setup #

Android #

Add the following permissions to your AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        android:maxSdkVersion="32" />
</manifest>

Note: For Android 13+ (API 33+), no storage permissions are needed for app-specific directories.

iOS #

Add the following to your Info.plist:

<key>NSPhotoLibraryUsageDescription</key>
<string>This app needs access to compress photos and videos.</string>

API Reference #

MediaCompressor #

The main singleton class for compression operations.

Methods

compressImage(ImageCompressionConfig config)

Compresses an image file with the specified configuration.

Parameters:

  • config - Image compression configuration

Returns: Future<CompressionResult>

compressVideo(VideoCompressionConfig config, {Duration? timeout})

Compresses a video file with the specified configuration.

Parameters:

  • config - Video compression configuration
  • timeout - Optional timeout duration (default: 5 minutes)

Returns: Future<CompressionResult>

ImageCompressionConfig #

Configuration for image compression.

ImageCompressionConfig({
  required String path,      // Path to the image file
  int quality = 80,          // Quality 0-100 (default: 80)
  int? maxWidth,             // Optional max width
  int? maxHeight,            // Optional max height
})

VideoCompressionConfig #

Configuration for video compression.

VideoCompressionConfig({
  required String path,              // Path to the video file
  VideoQuality quality = VideoQuality.medium,  // Quality preset
})

Video Compression Details

When you compress a video, the plugin uses native platform implementations to:

  • Reduce Bitrate: Videos are re-encoded with lower bitrates based on quality preset
  • Optimize Format: Output in MP4 container with H.264 video codec
  • Maintain Quality: Balance between file size and visual quality
  • Preserve Audio: Audio track is maintained during compression

Quality Levels:

Quality Use Case
low Quick sharing, minimal file size
medium General sharing, social media (recommended)
high High-quality archival, professional use

Note: Compression results depend on the original video's characteristics. Videos already heavily compressed may not see significant file size reduction.

Examples #

Complete Example #

import 'package:flutter/material.dart';
import 'package:media_compressor/media_compressor.dart';
import 'package:image_picker/image_picker.dart';

class CompressionExample extends StatefulWidget {
  @override
  _CompressionExampleState createState() => _CompressionExampleState();
}

class _CompressionExampleState extends State<CompressionExample> {
  String? _result;

  Future<void> _compressImage() async {
    final picker = ImagePicker();
    final image = await picker.pickImage(source: ImageSource.gallery);
    
    if (image == null) return;

    final result = await MediaCompressor.compressImage(
      ImageCompressionConfig(
        path: image.path,
        quality: 80,
        maxWidth: 1920,
        maxHeight: 1080,
      ),
    );

    setState(() {
      if (result.isSuccess) {
        _result = 'Image compressed: ${result.path}';
      } else {
        _result = 'Error: ${result.error?.message}';
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Media Compressor')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: _compressImage,
              child: Text('Compress Image'),
            ),
            if (_result != null)
              Padding(
                padding: EdgeInsets.all(16),
                child: Text(_result!),
              ),
          ],
        ),
      ),
    );
  }
}

Best Practices #

  1. Quality Settings: Start with quality 80-85 for images - it provides good compression with minimal quality loss
  2. Dimension Limits: Set maxWidth/maxHeight to prevent memory issues with very large images
  3. Error Handling: Always check result.isSuccess before using the compressed file
  4. File Cleanup: Delete temporary compressed files when no longer needed
  5. Timeout: For large videos, consider increasing the timeout duration

Performance Tips #

  • Image compression is fast and typically completes in milliseconds
  • Video compression can take several seconds to minutes depending on file size
  • Compressing multiple files? Do it sequentially to avoid memory issues
  • Consider showing a loading indicator during video compression

Troubleshooting #

Common Issues #

"File not found" error

  • Verify the file path is correct and the file exists
  • Check that the app has necessary permissions

Video compression timeout

  • Increase timeout duration for large videos
  • Use lower quality settings for faster compression
  • Check available device storage

Out of memory errors

  • Reduce maxWidth/maxHeight for images
  • Process files sequentially, not in parallel
  • Close other memory-intensive operations

Platform-Specific Features #

Both Android and iOS provide full-featured compression with their own native optimizations.

Core Features (Both Platforms):

  • βœ… Image compression with quality control (0-100)
  • βœ… Image resolution limiting (maxWidth/maxHeight)
  • βœ… Video compression with quality presets (low/medium/high)
  • βœ… EXIF orientation handling
  • βœ… Memory-efficient processing

For detailed information about platform-specific implementations, advanced features, bitrates, resolutions, and capabilities, see PLATFORM_FEATURES.md.

Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

License #

This project is licensed under the MIT License - see the LICENSE file for details.

Support #

For issues, feature requests, or questions, please file an issue on the GitHub repository.

Media Credits #

The demo uses sample media for showcasing compression features.

πŸ“· Image Credit #

Photo by Zhen Yao
from Unsplash

πŸŽ₯ Video Credit #

Video by tham nguyen
from Pixabay


Made with ❀️ for the Flutter community