NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
pub.dev · #3036 most downloaded on pub.dev
Professional Flutter plugin for high-quality video compression with real-time progress tracking and thumbnail generation.
Last release 12 days ago
26 Sep 2026
Release timing varies
gaps range from 2 weeks to 8 months
Nearly every release is documented
notes for 14 of 14 stable releases
Nothing withdrawn
no release was ever pulled
1 years old
14 releases · first in 2025
iOS now honors advanced.frameRate without a crop, including resize, trim, rotation, orientation correction, and frame-rate-only requests, fixing #31 .
advanced.frameRate without a crop, including resize, trim,Fix and regression coverage: #32
Validated with 97 package tests, 3 example tests, and 13 iOS export regression tests on iPhone 17 Pro / iOS 26.0.
Added AGP 9 built-in Kotlin support by removing direct KGP application from the Android plugin.
One column per month.
videoBitrate requests through Media3.frameRate requests through FrameDropEffect.Published on pub.dev: https://pub.dev/packages/v_video_compressor/versions/2.2.2
Full changelog: https://github.com/v-chat-sdk/v_video_compressor/blob/v2.2.2/CHANGELOG.md
videoBitrate to the Media3 encoder and
lowers output frame rate when frameRate is below the source frame rate,
fixing #26.Raised the SwiftPM package minimum to iOS 15 so FlutterFramework resolves with current Flutter toolchains, fixing #22.
FlutterFramework resolves
with current Flutter toolchains, fixing #22.videoBitrate requests with an export-size budget that
accounts for the source audio track and the effective trimmed duration.Added a strongly typed normalized VVideoCropRect contract across Dart, Android Media3, and iOS AVFoundation.
VVideoCropRect contract across Dart,video_trimmer preview/timeline that feeds the one-pass compressor.video_editor_3 coordinateSwift Package Manager support alongside the existing CocoaPods integration.
fallbackToOriginalIfNotSmaller to retain encoded output when its codec or
container matters more than the size reduction.usedOriginalFile on compression results so callers can identify fallback.This release remains compatible with Android API 21+ and iOS 12.0+.
No breaking changes! The feature is automatic:
VDimensionHandling.autoAlign (default): Smart alignment, only aligns when neededVDimensionHandling.letterbox: Adds black bars to maintain aspect ratioVDimensionHandling.exact: Keep exact dimensions (may cause artifacts)| Input Dimensions | Aligned To | Reason |
|---|---|---|
| 1920×1080 | 1920×1072 | Rounds down to 16-multiple |
| 1082×1278 | 1072×1264 | Fixes chroma padding artifacts |
| 720×1280 | 720×1280 | Already 16-aligned, no change |
VDimensionHandling enum for configuration optionsalignTo16() helper function (public API)VVideoAdvancedConfig with dimensionHandling parametertoMap()/fromMap()) for new parameteralignTo16() private helper functioncalculateAspectRatioPreservingDimensions() for smart alignmentdimension % 16 != 0alignTo16() private helper functionapplyAdvancedComposition() for smart alignmentrenderSize calculation before video compositionalignTo16() function tests with various inputsNo breaking changes! The feature is automatic:
// Old code still works exactly the same
const config = VVideoCompressionConfig.medium(
advanced: VVideoAdvancedConfig(
customWidth: 1082, // Now automatically aligns to 1072
customHeight: 1278, // Now automatically aligns to 1264
),
);
// Optional: Explicit control (default is autoAlign)
const config = VVideoCompressionConfig.medium(
advanced: VVideoAdvancedConfig(
customWidth: 1082,
customHeight: 1278,
dimensionHandling: VDimensionHandling.autoAlign, // Explicit (same as default)
),
);
// Get actual dimensions after alignment (optional)
// Check logs for dimension adjustment messages
// Format: "Dimension alignment: 1082x1278 → 1072x1264 (16-pixel boundary)"Fixed ITMS-91054 Error: Resolved invalid privacy manifest API category declaration
NSPrivacyAccessedAPICategoryPhotoLibrary from privacy manifestFileTimestamp and DiskSpacepreferredTransform handling for proper video rotationdeinit cleanup and resource managementNo migration required - this is a backward-compatible stability update.
For App Store submissions:
For video orientation issues:
// Existing code automatically benefits from orientation fixes
final result = await compressor.compressVideo(
videoPath,
VVideoCompressionConfig(
quality: VVideoCompressQuality.medium,
advanced: VVideoAdvancedConfig(
autoCorrectOrientation: true, // Now works more reliably
),
),
);
Add VVideoProgressEvent model with comprehensive progress information
BREAKING: None - fully backward compatible
NEW: Global progress stream accessible from anywhere in the app
NEW: Typed progress events with rich information
NEW: Multiple convenience methods for different use cases
NEW: Automatic stream lifecycle management
This release introduces a major improvement to progress tracking with a fully typed global stream that can be accessed from anywhere in your app.
VVideoProgressEvent with comprehensive progress information// Method 1: Listen to global stream directly
VVideoCompressor.progressStream.listen((event) {
print('Progress: ${event.progressFormatted}');
if (event.isBatchOperation) {
print('Batch: ${event.batchProgressDescription}');
}
});
// Method 2: Simple progress callback
VVideoCompressor.listenToProgress((progress) {
print('Progress: ${(progress * 100).toInt()}%');
});
// Method 3: Batch progress callback
VVideoCompressor.listenToBatchProgress((progress, currentIndex, total) {
print('Batch: Video ${currentIndex + 1}/$total - ${(progress * 100).toInt()}%');
});
Before: Required passing callbacks and checking Map types manually
// Old way - complex and error-prone
progressSubscription = eventChannel.receiveBroadcastStream().listen((event) {
if (event is Map && event.containsKey('progress')) {
final progress = (event['progress'] as num).toDouble();
onProgress(progress);
}
});
After: Fully typed global stream accessible from anywhere
// New way - simple and type-safe
VVideoCompressor.progressStream.listen((event) {
print('Progress: ${event.progressFormatted}');
});
The new VVideoProgressEvent provides comprehensive progress data:
progress: Progress value (0.0 to 1.0)progressFormatted: Formatted percentage string (e.g., "75.5%")videoPath: Path of the video being processedisBatchOperation: Whether this is part of a batch operationcurrentIndex: Current video index in batch operationstotal: Total number of videos in batch operationsbatchProgressDescription: Formatted batch progress stringcompressionId: Optional ID for tracking specific operationsGlobal Stream Manager:
VVideoStreamManager: Singleton manager for global stream accessTyped Models:
VVideoProgressEvent: Comprehensive typed progress event modelPlatform Updates:
VVideoCompressor.progressStream for universal accesslistenToProgress(), listenToBatchProgress(), listen()VVideoProgressEvent with comprehensive informationNo migration required - existing progress callbacks continue to work.
To use the new global stream:
// Replace individual progress callbacks
VVideoCompressor.progressStream.listen((event) {
// Handle progress from anywhere in your app
});
// Use in services/controllers
class VideoService {
static void startGlobalListener() {
VVideoCompressor.progressStream.listen((event) {
// Update state management, emit to other streams, etc.
});
}
}
// Use with state management
class VideoNotifier extends ChangeNotifier {
void startListening() {
VVideoCompressor.progressStream.listen((event) {
// Update state and notify listeners
notifyListeners();
});
}
}
This release introduces a major improvement for handling vertical videos that were appearing horizontal after compression.
This release introduces a major improvement for handling vertical videos that were appearing horizontal after compression.
autoCorrectOrientation Parameter: Automatically detects and preserves original video orientation// Fix vertical videos appearing horizontal after compression
final result = await compressor.compressVideo(
videoPath,
VVideoCompressionConfig(
quality: VVideoCompressQuality.medium,
advanced: VVideoAdvancedConfig(
autoCorrectOrientation: true, // NEW: Preserves original orientation
videoBitrate: 1500000,
audioBitrate: 128000,
),
),
);
Before: Vertical videos (9:16 aspect ratio) would appear horizontal after compression After: Videos maintain their original orientation automatically
All preset configurations now include automatic orientation correction:
VVideoAdvancedConfig.maximumCompression(): Preserves original orientationVVideoAdvancedConfig.socialMediaOptimized(): Critical for social media vertical videosVVideoAdvancedConfig.mobileOptimized(): Essential for mobile vertical videosAndroid Platform:
VVideoCompressionEngine to detect rotation metadatagetVideoRotation() helper method for metadata extractioncreateEditedMediaItemWithQuality() to apply orientation correctioniOS Platform:
VVideoCompressionEngine to read preferredTransform from video tracksapplyAdvancedComposition() to automatically preserve orientationNo migration required - this is a backward-compatible addition.
To enable orientation correction:
// Add to existing configurations
VVideoAdvancedConfig(
autoCorrectOrientation: true, // Add this line
// ... your existing parameters
)
For new projects:
// Use preset configurations (orientation correction included by default)
VVideoAdvancedConfig.socialMediaOptimized() // Perfect for vertical videos
VVideoAdvancedConfig.mobileOptimized() // Ideal for mobile apps
chore(release): 1.0.4 memory fixes and dual API support
chore(release): 1.0.4 memory fixes and dual API support
config map.config map.Removed unnecessary MANAGE_EXTERNAL_STORAGE permission from Android manifest
No migration required. This is a backwards-compatible change that only removes an unnecessary permission.
This release focuses on significant improvements to compression quality, file size optimization, and overall reliability across both Android and iOS p
This release focuses on significant improvements to compression quality, file size optimization, and overall reliability across both Android and iOS platforms.
Enhanced Bitrate Optimization: Improved default bitrates for better compression ratios
Smart Codec Selection: Automatic H.265 selection for optimal compression while maintaining H.264 for HIGH quality compatibility
Improved Size Estimation: More accurate bitrate-based calculations with resolution scaling and 5% container overhead
Enhanced Error Handling: Detailed error messages for specific failure scenarios (format not supported, file not found, encoder initialization failed)
Memory Management: Better resource cleanup with automatic finalization and garbage collection optimization
Fixed Missing Imports: Resolved compilation issues with Media3 Effects and Presentation imports
ADVANCED_FEATURES_SUPPORT.md details supported vs. unsupported featuresIMPLEMENTATION_SUMMARY.md provides comprehensive improvement overviewNone - This release maintains full backward compatibility with existing code.
No migration required. Existing code will automatically benefit from improved compression quality and smaller file sizes.
ADVANCED_FEATURES_SUPPORT.md for detailed feature support matrixCritical: Fixed OutOfMemoryError during video compression on low-memory devices
Review API: Check method signatures for any breaking changes
This is the first stable release of the V Video Compressor Flutter plugin, providing professional-grade video compression with comprehensive features for production apps.
| Platform | Status | Notes |
|---|---|---|
| Android | ✅ Full Support | API 21+ (Android 5.0+) |
| iOS | ✅ Full Support | iOS 11.0+ |
// Get video information
Future<VVideoInfo?> getVideoInfo(String videoPath);
// Estimate compression size
Future<VVideoCompressionEstimate?> getCompressionEstimate(
String videoPath, VVideoCompressQuality quality, {VVideoAdvancedConfig? advanced}
);
// Compress single video with progress
Future<VVideoCompressionResult?> compressVideo(
String videoPath, VVideoCompressionConfig config, {Function(double)? onProgress}
);
// Batch compress videos
Future<List<VVideoCompressionResult>> compressVideos(
List<String> videoPaths, VVideoCompressionConfig config,
{Function(double, int, int)? onProgress}
);
// Control operations
Future<void> cancelCompression();
Future<bool> isCompressing();
// Single thumbnail
Future<VVideoThumbnailResult?> getVideoThumbnail(
String videoPath, VVideoThumbnailConfig config
);
// Multiple thumbnails
Future<List<VVideoThumbnailResult>> getVideoThumbnails(
String videoPath, List<VVideoThumbnailConfig> configs
);
// Complete cleanup
Future<void> cleanup();
// Selective cleanup
Future<void> cleanupFiles({
bool deleteThumbnails = true,
bool deleteCompressedVideos = false,
bool clearCache = true,
});
| Quality | Resolution | Bitrate Range | Use Case |
|---|---|---|---|
| High | 1080p HD | 8-12 Mbps | Professional quality |
| Medium | 720p | 4-6 Mbps | Balanced quality/size |
| Low | 480p | 1-3 Mbps | Social media sharing |
| Very Low | 360p | 0.5-1.5 Mbps | Messaging apps |
| Ultra Low | 240p | 0.2-0.8 Mbps | Maximum compression |
image_picker or file_pickerdependencies:
v_video_compressor: ^1.0.0 # Only for compression
image_picker: ^1.0.7 # For video selection
file_picker: ^8.0.0 # Alternative file selection
path_provider: ^2.1.0 # For custom paths (optional)
// Basic compression with progress
final result = await compressor.compressVideo(
videoPath,
VVideoCompressionConfig.medium(),
onProgress: (progress) {
print('Progress: ${(progress * 100).toInt()}%');
},
);
// Advanced compression
final advancedConfig = VVideoAdvancedConfig(
customWidth: 1280,
customHeight: 720,
videoBitrate: 4000000,
videoCodec: VVideoCodec.h265,
removeAudio: false,
brightness: 0.1,
);
final result = await compressor.compressVideo(
videoPath,
VVideoCompressionConfig(
quality: VVideoCompressQuality.medium,
advanced: advancedConfig,
),
);
// Thumbnail generation
final thumbnail = await compressor.getVideoThumbnail(
videoPath,
VVideoThumbnailConfig(
timeMs: 5000,
maxWidth: 300,
maxHeight: 200,
format: VThumbnailFormat.jpeg,
quality: 85,
),
);
This is the first stable release. If upgrading from development versions:
v_video_compressor: ^1.0.0flutter pub getMIT License - See LICENSE file for details.
We welcome contributions! Please read our Contributing Guide for details.
Your coding agent can read these notes before it upgrades. Set up the MCP server →