light_compressor_v2 1.4.0
light_compressor_v2: ^1.4.0 copied to clipboard
A powerful and easy-to-use video compression plugin for Flutter.
Changelog #
1.4.0 #
New #
- H.265 / HEVC output — pass an optional
videoFormattocompressVideo/compressVideosto choose the output codec (VideoFormat.h264— the default — orVideoFormat.h265). HEVC produces noticeably smaller files at comparable quality. Omitting the parameter keeps the previous H.264 behaviour and is fully backwards compatible.- Automatic fallback —
VideoFormat.h265is used only when the device can encode HEVC in hardware (Android: a non-softwarevideo/hevcencoder; iOS/macOS: an advertised HEVC encoder). On devices without it, the compressor transparently falls back to H.264 instead of failing. OnSuccess.usedFormat— every successful result now reports the codec actually used, so you can tell whether an H.265 request was honoured or fell back to H.264.
- Automatic fallback —
OnFailure.failureType— failures now carry aCompressionFailureType(permission,unsupported,notFound,unknown) so you can react to why a video failed — including per-item in a batch — without parsing message text. Defaults tounknownandOnFailure.messageis unchanged, so this is fully backwards compatible.- Example app gains a “Use H.265 (HEVC)” toggle in both the single and batch flows, and the single-video result now shows the codec used.
Changed #
- Android: video muxing now uses the platform
MediaMuxer(native H.264 and H.265 support) instead of a bundled mp4 writer. This removes the third-partymp4parser/isoparserdependency.
1.3.0 #
New #
- Background execution — pass an optional
BackgroundConfigtocompressVideo/compressVideosto keep a compression running while the app is backgrounded or the screen is off. Omitting it (the default) preserves the previous behaviour and is fully backwards compatible. Behaviour is platform-specific:- Android — runs under a foreground service. Its ongoing notification shows live progress (bar + %), an elapsed-time timer, the current file name (single) or a done/total count like
2 / 5(batch, since videos compress in parallel) and a Cancel action. The title comes fromBackgroundConfig. The plugin declares the service + receiver and requestsPOST_NOTIFICATIONS(Android 13+) automatically; no host-app manifest changes are required. - macOS — suppresses App Nap (
NSProcessInfo.beginActivity) so the process keeps full CPU while in the background. The notification fields are ignored. - iOS — not supported. iOS suspends backgrounded apps within seconds and offers no sanctioned way to keep video transcoding running, so passing a
BackgroundConfighas no effect there; the compression pauses and resumes when the app returns to the foreground.
- Android — runs under a foreground service. Its ongoing notification shows live progress (bar + %), an elapsed-time timer, the current file name (single) or a done/total count like
- Example app gains a “Run in background” toggle in both the single and batch flows.
1.2.0 #
New #
- Batch compression —
compressVideos({required List<String> paths, required List<String> videoNames, ...})compresses multiple videos with a shared set of options and returnsFuture<List<Result>>in the same order as the inputs (each entry anOnSuccess,OnFailureorOnCancelled). A single video failing does not stop the rest. onBatchUpdate— aStream<BatchEvent>that emitsBatchProgress(per-video and overall percent) andBatchItemCompleted(a video's result) as the batch runs, for building per-item UIs.- The single-video
compressVideoand itsonProgressUpdatedstream are unchanged — batch uses a separatecompression/batch-streamchannel, so existing code is unaffected.
Changed #
cancelCompression()now returnsFuture<void>instead ofFuture<Map<String, dynamic>?>. The old return type never carried a meaningful value; the cancellation outcome arrives as anOnCancelledresult on the pendingcompressVideo/compressVideoscall.
Fixed #
- Cancelling a single compression crashed the app on Android. Cancellation delivered two terminal callbacks for one video (
onCancelledfollowed byonFailure) and replied twice on the sameMethodChannel.Result, throwingIllegalStateException: Reply already submitted. Cancellation now yields exactly oneonCancelled, and the single-video handler de-duplicates its reply like batch already did. cancelCompression()never completed. The Android, iOS and macOS handlers did not reply to the method call, so the returnedFuturehung forever. All three platforms now reply.- iOS / macOS: the single-video handler funnels every terminal reply through one main-thread reply, so a cancel/finish race can no longer deliver two
FlutterResults or reply off the main thread.
1.1.0 #
New #
getMediaInfo(path)— returns a structuredMediaInfo(width, height, duration, file size, bitrate, rotation, frame rate, MIME type) with rotation-awaredisplayWidth/displayHeight. On Android, duration/bitrate fall back to theMediaExtractortrack format when the metadata retriever does not expose them.getVideoThumbnail(path, {positionInMs, quality})— extracts a JPEG frame and returns its file path (AndroidMediaMetadataRetriever, iOS/macOSAVAssetImageGenerator).clearCache()— deletes temporary files generated during compression and thumbnail extraction (.mp4and.jpg).- Structured success result —
OnSuccessnow carriesoriginalSize,compressedSize,durationandratio(percentage reduction). - Typed exceptions —
PermissionDeniedException,UnsupportedVideoException,VideoNotFoundException,MediaInfoException,ThumbnailException, all extendingLightCompressorException. Native failures are surfaced via stable error codes instead of message text. - Example app demonstrates metadata display, thumbnail preview, and a Clear Cache action.
Fixed #
- Android H.264 encoder — pair
KEY_PROFILEwith a supportedKEY_LEVEL, so the hardware encoder no longer failsconfigure()with error-38and silently downgrades to Baseline. - Reported duration — use the exact duration measured during transcoding instead of a file-size/bitrate estimate (previously could report wildly wrong values for files without duration metadata).
- Over-compression — when a source has no duration/bitrate metadata, estimate the bitrate from the resolution instead of collapsing to the minimum bitrate.
- Resource handling (Android) — keep
MediaMetadataRetriever/MediaExtractorfile descriptors open while reading and release the retriever (previously leaked). - macOS — fixed a build failure caused by an out-of-sync
LightCompressor.swift.
1.0.1 #
- Added Swift Package Manager (SPM) support for iOS.
- Fully migrated the Android native layer to Kotlin, including core compression algorithms, MP4 builder, and video/texture renderers.
- Integrated the native compression library sources directly into the plugin codebase.
- Upgraded the Android build system and configurations (converted build scripts to Kotlin DSL
.gradle.kts). - Added comprehensive production-ready documentation (
README.md). - Updated example project and video player.
- Optimized codebase and improved performance.
- Fixed minor issues.
1.0.0 (Fork) #
- Forked from the original
light_compressorpackage. - Updated
kotlin-gradle-pluginto version 1.8.21. - Upgraded the
LightCompressordependency to version 1.3.2. - Increased
compileSdkVersionto 33. - Fixed various bugs and improved performance.