As a video editing professional working extensively with command-line tools, I've found FFmpeg to be the most powerful and versatile solution for merging and combining multiple videos. Understanding FFmpeg merge commands is essential for anyone working with video processing, whether you're a content creator, developer, or multimedia enthusiast.
FFmpeg provides multiple methods to combine videos depending on your specific needs—whether you want to concatenate videos sequentially, stack them side-by-side, or create complex multi-video layouts. This comprehensive guide covers all the essential FFmpeg terminal commands with practical examples and best practices.
Before merging videos, ensure FFmpeg is installed on your system. Here are the installation commands for different operating systems:
# Ubuntu/Debian
sudo apt update
sudo apt install ffmpeg
# macOS (using Homebrew)
brew install ffmpeg
# Windows (using Chocolatey)
choco install ffmpeg
# Verify installation
ffmpeg -version
The most common way to merge videos is concatenation—playing videos one after another sequentially. This method is perfect for combining multiple clips into a single continuous video.
The concat demuxer is the fastest and most reliable method for merging videos with identical codecs and parameters.
# Create filelist.txt with the following content:
echo "file 'video1.mp4'" > filelist.txt
echo "file 'video2.mp4'" >> filelist.txt
echo "file 'video3.mp4'" >> filelist.txt
# Or use a single command:
printf "file '%s'\n" video1.mp4 video2.mp4 video3.mp4 > filelist.txt
# Basic concatenation (no re-encoding)
ffmpeg -f concat -safe 0 -i filelist.txt -c copy output_merged.mp4
# With re-encoding (if videos have different formats)
ffmpeg -f concat -safe 0 -i filelist.txt -c:v libx264 -c:a aac output_merged.mp4
The concat filter allows you to merge videos with different properties by automatically re-encoding them to match.
ffmpeg -i video1.mp4 -i video2.mp4 \
-filter_complex "[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" output_merged.mp4
ffmpeg -i video1.mp4 -i video2.mp4 -i video3.mp4 \
-filter_complex "[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" output_merged.mp4
Create split-screen effects by placing videos side-by-side horizontally. This is perfect for comparison videos or dual-perspective content.
# Simple side-by-side merge
ffmpeg -i video1.mp4 -i video2.mp4 \
-filter_complex hstack output_sidebyside.mp4
# With specific resolution scaling
ffmpeg -i video1.mp4 -i video2.mp4 \
-filter_complex "[0:v]scale=640:480[v0];[1:v]scale=640:480[v1];[v0][v1]hstack" \
output_sidebyside.mp4
ffmpeg -i video1.mp4 -i video2.mp4 \
-filter_complex "[0:v][1:v]hstack=inputs=2[v]" \
-map "[v]" -map 0:a -c:v libx264 -crf 23 -preset medium \
output_sidebyside.mp4
Stack videos vertically to create top-and-bottom layouts, ideal for before/after comparisons or multi-angle presentations.
# Basic vertical stack
ffmpeg -i video1.mp4 -i video2.mp4 \
-filter_complex vstack output_vertical.mp4
# With resolution adjustment
ffmpeg -i video1.mp4 -i video2.mp4 \
-filter_complex "[0:v]scale=1280:720[v0];[1:v]scale=1280:720[v1];[v0][v1]vstack" \
output_vertical.mp4
Create professional grid layouts with multiple videos displayed simultaneously, perfect for surveillance footage or multi-cam productions.
ffmpeg -i video1.mp4 -i video2.mp4 -i video3.mp4 -i video4.mp4 \
-filter_complex \
"[0:v]scale=640:360[v0]; \
[1:v]scale=640:360[v1]; \
[2:v]scale=640:360[v2]; \
[3:v]scale=640:360[v3]; \
[v0][v1]hstack[top]; \
[v2][v3]hstack[bottom]; \
[top][bottom]vstack[out]" \
-map "[out]" -c:v libx264 -crf 23 -preset medium \
output_grid_2x2.mp4
ffmpeg -i v1.mp4 -i v2.mp4 -i v3.mp4 -i v4.mp4 -i v5.mp4 -i v6.mp4 -i v7.mp4 -i v8.mp4 -i v9.mp4 \
-filter_complex \
"[0:v]scale=426:240[v0]; [1:v]scale=426:240[v1]; [2:v]scale=426:240[v2]; \
[3:v]scale=426:240[v3]; [4:v]scale=426:240[v4]; [5:v]scale=426:240[v5]; \
[6:v]scale=426:240[v6]; [7:v]scale=426:240[v7]; [8:v]scale=426:240[v8]; \
[v0][v1][v2]hstack=inputs=3[row1]; \
[v3][v4][v5]hstack=inputs=3[row2]; \
[v6][v7][v8]hstack=inputs=3[row3]; \
[row1][row2][row3]vstack=inputs=3[out]" \
-map "[out]" -c:v libx264 -crf 23 output_grid_3x3.mp4
Overlay one video on top of another to create picture-in-picture effects, commonly used for reaction videos and tutorials.
# PIP in top-right corner
ffmpeg -i background.mp4 -i overlay.mp4 \
-filter_complex "[1:v]scale=320:180[pip]; \
[0:v][pip]overlay=main_w-overlay_w-10:10" \
output_pip.mp4
# PIP in bottom-left corner
ffmpeg -i background.mp4 -i overlay.mp4 \
-filter_complex "[1:v]scale=320:180[pip]; \
[0:v][pip]overlay=10:main_h-overlay_h-10" \
output_pip.mp4
ffmpeg -i background.mp4 -i overlay.mp4 \
-filter_complex "[1:v]scale=400:225,pad=410:235:5:5:black[pip]; \
[0:v][pip]overlay=main_w-overlay_w-20:20" \
-c:v libx264 -crf 23 output_pip_bordered.mp4
# Convert all videos to 30fps before merging
ffmpeg -i video1.mp4 -i video2.mp4 \
-filter_complex "[0:v]fps=30[v0];[1:v]fps=30[v1];[v0][v1]concat=n=2:v=1:a=0[outv]" \
-map "[outv]" -c:v libx264 -crf 23 output_30fps.mp4
# 1-second crossfade transition between two videos
ffmpeg -i video1.mp4 -i video2.mp4 \
-filter_complex \
"[0:v][1:v]xfade=transition=fade:duration=1:offset=4[vout]; \
[0:a][1:a]acrossfade=d=1[aout]" \
-map "[vout]" -map "[aout]" output_crossfade.mp4
# Merge videos and mix audio tracks
ffmpeg -i video1.mp4 -i video2.mp4 \
-filter_complex "[0:v][1:v]hstack[v]; \
[0:a][1:a]amix=inputs=2:duration=longest[a]" \
-map "[v]" -map "[a]" -c:v libx264 -c:a aac output_mixed_audio.mp4
| Parameter | Description | Example Values |
|---|---|---|
-i |
Input file specification | video.mp4, input.avi |
-c:v |
Video codec | libx264, libx265, copy |
-c:a |
Audio codec | aac, mp3, copy |
-crf |
Quality level (lower = better) | 18-28 (23 recommended) |
-preset |
Encoding speed preset | ultrafast, fast, medium, slow |
-filter_complex |
Complex filtergraph | Multiple filter operations |
-map |
Stream mapping | [v], [a], 0:v:0 |
-safe 0 |
Allow absolute file paths | 0 (enable), 1 (disable) |
ffmpeg -f concat -safe 0 -i filelist.txt \
-c:v libx264 -crf 18 -preset slow \
-c:a aac -b:a 320k \
output_high_quality.mp4
ffmpeg -f concat -safe 0 -i filelist.txt \
-c:v libx264 -crf 23 -preset medium \
-c:a aac -b:a 192k \
output_balanced.mp4
ffmpeg -f concat -safe 0 -i filelist.txt \
-c:v libx264 -crf 28 -preset ultrafast \
-c:a aac -b:a 128k \
output_fast.mp4
# Scale all videos to 1920x1080 before concatenating
ffmpeg -i video1.mp4 -i video2.mp4 -i video3.mp4 \
-filter_complex \
"[0:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2[v0]; \
[1:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2[v1]; \
[2:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2[v2]; \
[v0][0:a][v1][1:a][v2][2:a]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" output_normalized.mp4
ffmpeg -f concat -safe 0 -i filelist.txt -i background_music.mp3 \
-filter_complex "[0:a][1:a]amix=inputs=2:duration=first:dropout_transition=2[aout]" \
-map 0:v -map "[aout]" -c:v copy -c:a aac \
output_with_music.mp4
#!/bin/bash
# Create file lists for each video set
for dir in video_set_*/; do
output="${dir%/}_merged.mp4"
# Create filelist.txt for this directory
printf "file '%s'\n" "$dir"*.mp4 > "$dir/filelist.txt"
# Merge videos
ffmpeg -f concat -safe 0 -i "$dir/filelist.txt" -c copy "$output"
echo "Merged $dir into $output"
done
-t parameter to generate a quick test output:
ffmpeg -f concat -safe 0 -i filelist.txt -t 30 test_output.mp4
Solution: Add the -safe 0 parameter to allow absolute file paths in your
filelist.
Solution: Use the -async 1 parameter to fix sync issues:
ffmpeg -f concat -safe 0 -i filelist.txt \
-c:v libx264 -c:a aac -async 1 \
output_synced.mp4
Solution: Re-encode all videos to a common format using the concat filter instead of concat demuxer.
Solution: Increase CRF value (23-28) or use a faster preset:
ffmpeg -f concat -safe 0 -i filelist.txt \
-c:v libx264 -crf 28 -preset fast \
-c:a aac -b:a 128k \
output_compressed.mp4
# Get video information
ffmpeg -i video.mp4
# Extract audio from video
ffmpeg -i video.mp4 -vn -acodec copy audio.aac
# Extract video without audio
ffmpeg -i video.mp4 -an -vcodec copy video_no_audio.mp4
# Change video resolution
ffmpeg -i input.mp4 -vf scale=1280:720 output.mp4
# Convert video to different format
ffmpeg -i input.avi -c:v libx264 -c:a aac output.mp4
# Trim video
ffmpeg -i input.mp4 -ss 00:00:10 -t 00:00:30 -c copy output.mp4
# Add watermark to video
ffmpeg -i video.mp4 -i logo.png -filter_complex "overlay=10:10" output.mp4
# Speed up video (2x)
ffmpeg -i input.mp4 -filter:v "setpts=0.5*PTS" output.mp4
# Slow down video (0.5x)
ffmpeg -i input.mp4 -filter:v "setpts=2.0*PTS" output.mp4
| Platform | Recommended Resolution | FFmpeg Command |
|---|---|---|
| YouTube | 1920x1080 (1080p) | -c:v libx264 -crf 21 -preset slow -c:a aac -b:a 192k |
| Instagram Feed | 1080x1080 (Square) | -vf scale=1080:1080 -c:v libx264 -crf 23 -c:a aac |
| Instagram Stories | 1080x1920 (9:16) | -vf scale=1080:1920 -c:v libx264 -crf 23 |
| 1280x720 (720p) | -c:v libx264 -crf 23 -preset medium -c:a aac |
|
| 1280x720 (720p) | -c:v libx264 -crf 23 -c:a aac -b:a 128k |
FFmpeg provides powerful and flexible options for merging and combining multiple videos through terminal commands. Whether you need simple sequential concatenation, complex grid layouts, or creative picture-in-picture effects, FFmpeg handles it all efficiently. The key is understanding which method suits your specific requirements and mastering the filter_complex syntax for advanced operations.
By using the appropriate FFmpeg merge commands and following the best practices outlined in this guide, you can create professional video compositions without expensive editing software. Start with simple concatenation, then experiment with more advanced techniques as you become comfortable with the command-line interface.