A high-performance, hardware-accelerated video encoding engine for Flutter stories. Supporting 4K and thermal stability.
Hardware Accelerated — Uses AVFoundation on iOS/macOS and MediaCodec on Android for native-speed encoding.
Zero-Copy Pipeline — Optimized GPU-backed frame transfers on all platforms.
Thermal Stability — Built-in backpressure management to prevent device overheating during long exports.
Deterministic Pacing — Precise frame timestamping for professional-grade, jitter-free video output.
Type-Safe IPC — Leverages Pigeon for compile-time safe communication between Dart and native code.
Stats Streaming — Real-time telemetry: frames processed, throughput (FPS), and progress.
Silent Audio Track — Optional AAC silent audio for universal video player compatibility.
Feature
iOS
macOS
Android
Hardware Encoding
✅
✅
✅
H.264 (AVC)
✅
✅
✅
4K @ 60fps
✅
✅
✅
Silent Audio
✅
✅
✅
Backpressure
✅
✅
✅
SPM Support
✅
✅
—
dependencies :
flutter_story_encoder : ^1.2.0
iOS 13.0+
Optional — add to Info.plist if saving to the photo library:
<key >NSPhotoLibraryAddUsageDescription</key >
<string >We need permission to save your stories.</string >
Min SDK 21 (Lollipop). Recommended Min SDK 24+ for stable 4K Surface encoding.
import 'package:flutter_story_encoder/flutter_story_encoder.dart' ;
final bool started = await FlutterStoryEncoder .start (
config: EncoderConfig (
width: 1080 ,
height: 1920 ,
fps: 30 ,
bitrate: 10000000 , // 10 Mbps
outputPath: '/path/to/output.mp4' ,
addSilentAudio: true ,
),
onProgress: (EncodingStats stats) {
print ('FPS: ${stats .currentFps } | Frames: ${stats .framesProcessed }' );
},
onError: (msg, code) => print ('Error [$code ]: $msg ' ),
);
Capture frames from a RepaintBoundary and feed them to the encoder:
import 'dart:ui' as ui;
final RenderRepaintBoundary boundary =
key.currentContext! .findRenderObject () as RenderRepaintBoundary ;
// Best Practice: Capture at exact target dimensions
final double pixelRatio = targetWidth / boundary.size.width;
final ui.Image image = await boundary.toImage (pixelRatio: pixelRatio);
final ByteData ? byteData =
await image.toByteData (format: ui.ImageByteFormat .rawRgba);
if (byteData != null ) {
await FlutterStoryEncoder .appendFrame (byteData.buffer.asUint8List ());
}
3. Finish and get the output path
final String ? outputPath = await FlutterStoryEncoder .finish ();
print ('Video saved to: $outputPath ' );
await FlutterStoryEncoder .cancel ();
Property
Type
Description
width
int
Target video width in pixels.
height
int
Target video height in pixels.
fps
int
Frames per second (e.g. 30 or 60).
bitrate
int
Target bitrate in bits/s (e.g. 10000000 = 10Mbps).
outputPath
String
Absolute file path for the output .mp4 file.
addSilentAudio
bool
Adds a silent AAC audio track for compatibility.
Property
Type
Description
framesProcessed
int
Number of frames encoded so far.
currentFps
double
Current encoding throughput in FPS.
progress
double
Overall progress (0.0 – 1.0).
Match resolution : Set the RepaintBoundary pixel ratio to match the target resolution to avoid software scaling.
Bitrate : 10–15 Mbps recommended for 1080p high-quality stories.
Yield between frames : Use await Future.delayed(Duration.zero) between frame captures to keep the UI thread responsive.
Property
Value
Video Codec
H.264 / AVC
Audio Codec
AAC (silent track)
Profile
High Profile 4.1
Keyframe Interval
1 second
Rate Control
VBR (Variable Bitrate)
Color Space
BT.709
IPC Layer
Pigeon (type-safe)
MIT — see LICENSE for details.