• 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, ...) 23FFmpeg processes each frame 45Compress into MP4 with MPEG4 codec 67Final video created
Pro TipKeep frame count low and resolution reasonable for better performance!
Next Blog

Flutter Fielding Position Picker Using CustomPainter

Read Next