• Flutter
  • FFmpeg
  • Video Processing

Merge Two Videos in Flutter Using FFmpegKit

Aman Kumar

Aman Kumar

Flutter Developer, Gigawave

4 min read · June 14, 2025

Packages Required

  • ffmpeg_kit_flutter_full_gpl : to run FFmpeg commands in Dart
  • path_provider : to access temporary directories

Overview of the Merging Function

The main Dart function responsible for merging and overlaying the videos is:

app/main.dart
1Future<String> mergerVideoAndOverlay(...)

Step-by-Step Explanation of the Code

1. Getting Overlay Position

app/main.dart
1String position = getOverlayPosition(logoPosition);

This method fetches the correct coordinates (e.g., W-w:0) for the logo overlay based on user selection (top-left, top-right, etc.).

2. Create Temporary Output Paths

app/main.dart
1final tempDir = await getTemporaryDirectory(); 2final resizedPath = 'TEMP_DIR_PATH/resized_...'; 3final outputPath = 'TEMP_DIR_PATH/final_output_...';

These are temporary paths for storing intermediate and final merged videos.

3. Resize the Original Camera Video

app/main.dart
1final resizeSession = await FFmpegKit.executeWithArguments([ 2 '-y', 3 '-i', cameraVideoPath, 4 '-vf', 'scale=1080:1920:force_original_aspect_ratio=decrease', 5 '-r', '24', 6 resizedPath, 7]);

This step ensures the camera video fits the standard mobile resolution (1080x1920) while maintaining its aspect ratio.

4. Build FFmpeg Input List

app/main.dart
1'-i', timeOverlayVideoPath, // [0:v] 2'-i', logoOverlayImageFilePath, // [1:v] if logo 3'-i', resizedPath, // [2:v] if logo

We prepare FFmpeg input streams depending on whether the logo overlay is required or not.

5. Construct filter_complex

The filter_complex section is the most powerful part of FFmpeg:

app/main.dart
1// Scale time overlay 2'[0:v]scale=width:height[ovrl1];' 3// Overlay time on base video 4'[resized_video][ovrl1]overlay=0:0[tmp1];' 5// If logo is included 6'[1:v]scale=width:height[ovrl2];[tmp1][ovrl2]overlay=position[v]' 7// If no logo 8'[tmp1]copy[v]'
  • Resize the timestamp overlay
  • Apply it at position (0,0)
  • If logo is present, scale and overlay it using dynamic coordinates

6. Add Output Flags and Run Merge

app/main.dart
1'-filter_complex', filter, 2'-map', '[v]', 3'-pix_fmt', 'yuv420p', 4'-vsync', 'cfr', 5'-r', '24', 6outputPath,

These FFmpeg options finalize the encoding format and output video path.

7. Verify the Merge

app/main.dart
1final mergeSession = await FFmpegKit.executeWithArguments(ffmpegCommand); 2final fileExists = await File(outputPath).exists();

Once FFmpeg finishes, we check if the final file was successfully created.

Error Handling

app/main.dart
1catch (e, stacktrace) { 2 CustomLogger.error("Error in process and merge: $e"); 3 rethrow; 4}

All exceptions and FFmpeg logs are captured for debugging and logged using a custom logger.

Output Example

You get a new video with the timestamp overlaid from a separate video file, and optionally a logo in your chosen corner.

Useful Links

Final Words

This method gives you complete flexibility to overlay dynamic content like timestamps or branding in Flutter. With FFmpegKit, it's now easier than ever to build professional video editing features right inside your mobile app.

If you found this helpful, consider sharing or bookmarking this page!

Next Blog

Flutter Fielding Position Picker Using CustomPainter

Read Next