Need to burn a company logo or copyright notice into a video? FFmpeg’s overlay filter lets you place a transparent PNG watermark at any position, opacity, and time range — all from the command line, no GUI required. Time to complete: 10 minutes.

Tested with: FFmpeg 6.1 (ubuntu-latest / GitHub Actions CI-validated)


What You Will Learn

  1. How the overlay filter works and why -filter_complex is required
  2. Position variables (main_w, overlay_w, etc.) for resolution-independent placement
  3. Transparent PNG (alpha channel) compositing
  4. Semi-transparent watermarks with opacity control
  5. Time-limited display — show the logo only during intro or outro
  6. Scrolling animated watermark
  7. Compositing multiple logos simultaneously
  8. Five common errors and fixes
  9. Five frequently asked questions

Command Examples

1. Basic: Logo in the Top-Left Corner

ffmpeg -i input.mp4 -i logo.png -filter_complex "overlay=10:10" output.mp4
  • -i input.mp4 — main video
  • -i logo.png — watermark image
  • overlay=X:Y — place the logo’s top-left corner at (X, Y); origin is the video’s top-left

2. Bottom-Right Placement (Most Common)

ffmpeg -i input.mp4 -i logo.png \
  -filter_complex "overlay=main_w-overlay_w-20:main_h-overlay_h-20" \
  output.mp4
  • main_w-overlay_w-20 — X: 20px margin from the right edge
  • main_h-overlay_h-20 — Y: 20px margin from the bottom edge

3. Resize Logo Before Compositing (Transparent PNG)

Resize the logo to 150px wide before placing it bottom-right:

ffmpeg -i input.mp4 -i logo.png \
  -filter_complex "[1:v]scale=150:-1[wm];[0:v][wm]overlay=main_w-overlay_w-20:main_h-overlay_h-20" \
  output.mp4

Filter graph breakdown:

  1. [1:v]scale=150:-1[wm] — resize logo (second input) to 150px wide (aspect-ratio preserved), label it [wm]
  2. [0:v][wm]overlay=... — composite main video with the resized logo

FFmpeg handles alpha-channel transparency in PNGs automatically. No extra options needed.

4. Semi-Transparent Watermark (Opacity Control)

Use colorchannelmixer to adjust the alpha channel (0.5 = 50% opacity):

ffmpeg -i input.mp4 -i logo.png \
  -filter_complex "[1:v]scale=150:-1,colorchannelmixer=aa=0.5[wm];[0:v][wm]overlay=main_w-overlay_w-20:main_h-overlay_h-20" \
  output.mp4
  • aa=0.5 — alpha multiplier (0.0=fully transparent, 1.0=fully opaque)

5. Time-Limited Display (Show Only During Intro)

# Show logo only during seconds 0–5
ffmpeg -i input.mp4 -i logo.png \
  -filter_complex "overlay=main_w-overlay_w-20:main_h-overlay_h-20:enable='between(t,0,5)'" \
  output.mp4
# Show logo from 10s to 30s
ffmpeg -i input.mp4 -i logo.png \
  -filter_complex "overlay=10:10:enable='between(t,10,30)'" \
  output.mp4
  • t — current timestamp in seconds
  • between(t, start, end) — returns 1 (active) within the range

6. Scrolling Watermark (Left to Right)

Logo scrolls across the bottom of the frame:

ffmpeg -i input.mp4 -i logo.png \
  -filter_complex "[1:v]scale=200:-1[wm];[0:v][wm]overlay=x='mod(t*100,main_w+overlay_w)-overlay_w':y=main_h-overlay_h-20" \
  output.mp4
  • mod(t*100, main_w+overlay_w)-overlay_w — moves 100px/second; loops from off-left to off-right

7. Multiple Logos Simultaneously

Place two logos (top-left and bottom-right) at the same time:

ffmpeg -i input.mp4 -i logo1.png -i logo2.png \
  -filter_complex "[1:v]scale=100:-1[wm1];[2:v]scale=150:-1[wm2];[0:v][wm1]overlay=10:10[tmp];[tmp][wm2]overlay=main_w-overlay_w-20:main_h-overlay_h-20" \
  output.mp4

Position Variable Reference

VariableMeaning
main_w / WMain video width
main_h / HMain video height
overlay_wLogo width
overlay_hLogo height
tCurrent time in seconds (for animation)

Common Position Formulas

PositionX ExpressionY Expression
Top-left1010
Top-rightmain_w-overlay_w-1010
Bottom-left10main_h-overlay_h-10
Bottom-right (recommended)main_w-overlay_w-20main_h-overlay_h-20
Center(main_w-overlay_w)/2(main_h-overlay_h)/2

Option Reference

OptionMeaningExample
overlay=X:YLogo placement (top-left origin)overlay=10:10
enable='between(t,S,E)'Time-limited display (S to E seconds)enable='between(t,0,5)'
[N:v]scale=W:-1Resize N-th input to W px wide[1:v]scale=150:-1
colorchannelmixer=aa=AAlpha multiplier (0.0–1.0)aa=0.5 (50% opacity)
x='mod(t*speed,...)'Scrolling animationx='mod(t*100,main_w+overlay_w)-overlay_w'

Troubleshooting

Problem 1: Too many inputs for overlay filter

Cause: Using -vf instead of -filter_complex. The overlay filter requires two inputs and doesn’t work with -vf.
Fix:

# Wrong
ffmpeg -i input.mp4 -i logo.png -vf "overlay=10:10" output.mp4

# Correct
ffmpeg -i input.mp4 -i logo.png -filter_complex "overlay=10:10" output.mp4

Problem 2: Logo Is Invisible (Fully Transparent)

Cause: The PNG’s alpha channel is fully transparent, or the logo is too small.
Fix:

# Inspect logo dimensions and pixel format
ffprobe -v quiet -show_streams logo.png | grep -E "width|height|pix_fmt"

Problem 3: Output file #0 does not contain any stream

Cause: The filter graph labels don’t match (e.g., [wm] defined but referenced as [logo]).
Fix: Verify that every label you define ([wm]) is used exactly once on both sides of the graph.

Problem 4: Logo Appears Stretched or Distorted

Cause: scale=W:H was used with both width and height specified explicitly.
Fix: Use scale=150:-1 (set height to -1 for automatic aspect-ratio preservation).

Problem 5: Output File Is Much Larger Than Expected

Cause: overlay always triggers re-encoding of the video stream (this is by design).
Fix: Set CRF to maintain quality:

ffmpeg -i input.mp4 -i logo.png \
  -filter_complex "overlay=main_w-overlay_w-20:main_h-overlay_h-20" \
  -c:v libx264 -crf 18 -preset fast -c:a copy output.mp4

FAQ

Q1. Can I use a JPEG logo?
A. Yes, but JPEG has no alpha channel (no transparency). For a transparent logo you need PNG or WebP. A solid-color rectangular logo in JPEG will composite fine.

Q2. Does using overlay always re-encode the video?
A. Yes. The overlay filter composites frames pixel-by-pixel, which requires re-encoding the video stream. Audio can still be copied losslessly with -c:a copy.

Q3. Will the logo position adjust automatically for different video resolutions?
A. Yes — that’s exactly what expressions like main_w-overlay_w-20:main_h-overlay_h-20 are for. They adapt to any resolution.

Q4. Can the logo fade in and out over time?
A. It requires a complex filter graph. The simpler approach is enable='between(t,0,5)' to switch display on/off. A smooth fade requires animating colorchannelmixer=aa= with a time expression.

Q5. How do I add the same logo to all videos in a folder?

for f in *.mp4; do
  ffmpeg -i "$f" -i logo.png \
    -filter_complex "[1:v]scale=150:-1[wm];[0:v][wm]overlay=main_w-overlay_w-20:main_h-overlay_h-20" \
    -c:v libx264 -crf 18 -c:a copy "watermarked_${f}" -y
done


Tested with: ffmpeg 6.1.1 / Ubuntu 24.04 (GitHub Actions runner)
Primary sources: ffmpeg.org/ffmpeg.html / ffmpeg.org/ffmpeg-filters.html / trac.ffmpeg.org