native_video_toolkit 0.0.2
native_video_toolkit: ^0.0.2 copied to clipboard
Compress, merge, mute, and reverse video with zero bundled native dependencies — bound directly to AVFoundation (iOS/macOS, via ffigen + package:objective_c) and android.media (Android, via jni/jnigen [...]
0.0.2 #
- Fix
homepage/repository/issue_trackerto point at the canonicalflutter-packagesrepo. - Add badges and a License section to the README.
0.0.1 #
Initial release.
iOS / macOS #
compressVideo,mergeVideos,muteVideo,reverseVideo,generateThumbnail,ensurePlayableCopybound directly to AVFoundation viapackage:ffigen's Objective-C interop — noMethodChannel.- Automatic container/codec normalization (
ensureAvFoundationCompatible) for sources AVFoundation can't open natively, via an FFmpeg pre-pass. - Swift Package Manager support on both platforms, sharing one generated
binding set (verified byte-identical bound API surface between the
macOS and iOS SDKs) — plus a CocoaPods
.podspecfallback.
Android #
mergeVideos(fast, no-re-encode path only — see Known limitations),muteVideo,reverseVideo,ensurePlayableCopybound directly toandroid.media(MediaExtractor/MediaMuxer/MediaCodec) viapackage:jni/package:jnigen— noMethodChannel.- Every decode/encode/mux operation runs on its own background
Isolate, never blocking the caller's isolate. compressVideo/generateThumbnail/media probing work unmodified on Android — they're pureffmpeg_kit_flutter_newcalls with no AVFoundation/android.mediainvolvement on any platform.- Three real bugs found and fixed via actual device/emulator testing with
real video files (none of these were catchable by static analysis or a
clean build):
reverseVideo's encoder was being told every frame had 0 bytes of data (thequeueInputBuffersizeargument, not the pixel data itself, which was written correctly via theImageAPI) — silently wedged the encoder's entire pipeline with no exception and near-zero CPU, one of the harder failure modes to diagnose.reverseVideo's encode loop wrote every encoder output buffer to the muxer, including ones flaggedBUFFER_FLAG_CODEC_CONFIG—MediaMuxeronly ever wants codec-config data fromaddTrack's format, never as a sample; feeding it the redundant buffer anyway threw a native"Already have codec specific data"error and wedged the muxer's writer thread.mergeVideos' fast path computed each clip's timestamp offset from the container's reporteddurationUs, which can undershoot an audio track's actual last sample (encoder priming/padding) — fixed by tracking the last actually-written timestamp per track instead of trusting reported duration.
Known limitations #
reverseVideohas no audio track on either platform (sample-accurate audio reversal is out of scope) and decodes every frame into memory before writing anything out (rejected above a safety ceiling per resolution, rather than hanging).- Android's
mergeVideoshas no re-encode fallback for clips with mismatched encoding settings yet — it throws a clear error instead. A fallback viaandroidx.media3'sTransformeris planned; the jnigen bindings for it are already generated but not wired up. - Windows and Linux aren't implemented.