• Flutter
  • Video Generation
  • FFmpeg

Capture widget as video in flutter usingFFmpeg package

Aman Kumar

Aman Kumar

Flutter Developer, Gigawave

4 min read · June 14, 2025

We want to record a widget's UI as PNG images (frames) and then combine those frames into a video using FFmpeg.

  • Capture the widget's UI as PNG images (frames).
  • Combine those frames into a video using FFmpeg.

1. Wrapping the Widget

app/main.dart
1final GlobalKey _globalKey = GlobalKey(); 2 3 4Widget build(BuildContext context) { 5 return RepaintBoundary( 6 key: _globalKey, 7 child: widget.child, 8 ); 9}
  • RepaintBoundary : This allows you to snapshot the widget's current UI.
  • GlobalKey : Used to get access to this widget later during image capture.

2. Capturing a Frame

app/main.dart
1final RenderRepaintBoundary? boundary = 2 _globalKey.currentContext?.findRenderObject() as RenderRepaintBoundary?; 3 4final ui.Image image = await boundary.toImage(pixelRatio: widget.pixelRatio); 5final byteData = await image.toByteData(format: ui.ImageByteFormat.png); 6await File(framePath).writeAsBytes(byteData.buffer.asUint8List());
  • boundary.toImage(...) : Takes a screenshot of the widget.
  • pixelRatio : Controls resolution/quality of captured frame.
  • ImageByteFormat.png : Saves it in PNG format (required by FFmpeg).
  • It saves the frame with a sequential name like: frame_0000.png, frame_0001.png, etc.

3. Scheduling the Captures

app/main.dart
1_timer = Timer.periodic(Duration(milliseconds: 100), (timer) { 2 captureFrame(frameCount, framesDir.path); 3 ... 4});
  • Runs every 100ms (which means 10 frames per second).
  • Continues for the duration you set (widget.duration), collecting all frames.

FFmpeg Magic — Combine Images into Video

app/main.dart
1await FFmpegKit.executeWithArguments([ 2 '-y', // Overwrite output if it exists 3 '-framerate', '10', // Input frame rate: 10 FPS 4 '-f', 'image2', // Input format is a series of images 5 '-pattern_type', 'sequence', // Expect a sequence (frame_0000.png) 6 '-start_number', '0', // Start from frame_0000 7 '-i', '.../frame_%04d.png', // Input path (%04d means 4-digit padded number) 8 '-vcodec', 'mpeg4', // Output video codec 9 '-pix_fmt', 'yuv420p', // Pixel format for Android/iOS support 10 '-an', // No audio 11 'output_video.mp4', // Final video file 12]);

Explanation of Each FFmpeg Option:

FlagPurpose
-y
Auto overwrite output file if it exists
-framerate 10
Read input at 10 frames per second
-f image2
Use raw image input format
-pattern_type sequence
Accept sequential file names (frame_0001.png)
-start_number 0
Start from image frame_0000.png
-i frame_%04d.png
Read frames in order: 0000, 0001, 0002, etc.
-vcodec mpeg4
Use MPEG-4 video codec
-pix_fmt yuv420p
Required format for wide compatibility (especially iOS/Android players)
-an
Skip audio (you can add later if needed)

Output Example

Let's say you recorded for 5 seconds at 10 FPS. You'll get:

  • 50 PNG images inside tempDir/frames/
  • A single .mp4 file like output_video.mp4 in your temp directory
  • That video is playable, shareable, and storable, all from a widget & visuals.

What You Can Customize

FeatureHow to change
Frame rate
Change -framerate and timer interval
Resolution
Change pixelRatio or scale images before FFmpeg
Add Audio
Add -i audio.mp3 before -i image, then -shortest
Export Path
Change outputVideoPathas per your needs

Summary of FFmpeg Command Flow:

app/main.dart
1PNG images (frame_0000.png, ...) 2 ↓ 3FFmpeg processes each frame 4 ↓ 5Compress into MP4 with MPEG4 codec 6 ↓ 7✅ Final video created
Pro TipKeep frame count low and resolution reasonable for better performance!
Next Blog

Flutter Fielding Position Picker Using CustomPainter

Read Next