ffmpegfilter-complexoverlaypicture-in-picturevideo-compositingbucket-doc

FFmpeg Overlay Filter: Picture-in-Picture and Compositing

·Javid Jamae·6 min read
FFmpeg Overlay Filter: Picture-in-Picture and Compositing

You need to put one video on top of another, and FFmpeg's documentation reads like a math textbook. The overlay filter is one of the most used filters in FFmpeg, but getting the positioning, scaling, and timing right takes more trial and error than it should.

This guide covers the overlay filter from basic image-on-video compositing to timed picture-in-picture with multiple streams.

How the FFmpeg Overlay Filter Works

The overlay filter takes two video inputs and stacks one on top of the other. The first input is the background (main video), and the second is the foreground (the overlay). You control placement with x and y coordinates.

The basic syntax inside filter_complex:

ffmpeg -i main.mp4 -i logo.png -filter_complex "[0:v][1:v]overlay=10:10" output.mp4

This places logo.png at 10 pixels from the left and 10 pixels from the top of main.mp4. Two inputs, one filter, x and y coordinates.

You need -filter_complex instead of -vf whenever you're working with multiple inputs. The [0:v] and [1:v] labels reference the first and second input streams by index.

Position Variables for Dynamic Placement

Hardcoding pixel values breaks the moment your input resolution changes. FFmpeg gives you position variables that reference the dimensions of each stream at runtime:

  • W and H refer to the main (background) video's width and height
  • w and h refer to the overlay's width and height

To pin a watermark to the bottom-right corner with 10px padding:

ffmpeg -i main.mp4 -i watermark.png -filter_complex "[0:v][1:v]overlay=W-w-10:H-h-10" output.mp4

Center the overlay on the background:

ffmpeg -i main.mp4 -i overlay.png -filter_complex "[0:v][1:v]overlay=(W-w)/2:(H-h)/2" output.mp4

These expressions get evaluated per-frame, so they adapt to any input resolution without changes to your command.

FFmpeg Picture-in-Picture with Scaling

A picture-in-picture layout means shrinking one video and placing it over another. The overlay filter doesn't handle scaling on its own. You need to chain a scale filter before the overlay.

ffmpeg -i main.mp4 -i pip.mp4 -filter_complex \
  "[1:v]scale=320:180[pip];[0:v][pip]overlay=W-w-20:20" \
  output.mp4

This scales the second input to 320x180, labels it [pip], then overlays it in the top-right corner of the main video. The label syntax is how you route streams through a filter graph. You scale first, then overlay the result.

For maintaining aspect ratio while scaling, use -1 for one dimension:

[1:v]scale=320:-1[pip]

FFmpeg will calculate the height automatically.

Video-on-Video vs. Image-on-Video Compositing

When you overlay a static image (PNG, JPEG) on video, FFmpeg treats the image as a single-frame video stream. It just works. The image stays visible for the full duration.

Video-on-video compositing works the same way syntactically, but you need to think about duration. By default, the output ends when the shortest input ends. If your overlay clip is 5 seconds but your main video is 60 seconds, the output will be 5 seconds unless you set eof_action:

ffmpeg -i main.mp4 -i overlay.mp4 -filter_complex \
  "[0:v][1:v]overlay=10:10:eof_action=pass" output.mp4

eof_action=pass tells FFmpeg to keep outputting the main video after the overlay stream ends. Other options are repeat (loop the last overlay frame) and endall (stop everything).

Timed Overlays with Enable Expressions

Sometimes you only want the overlay visible during a specific time window. The enable parameter controls this:

ffmpeg -i main.mp4 -i lower_third.png -filter_complex \
  "[0:v][1:v]overlay=0:H-h:enable='between(t,5,15)'" output.mp4

This shows the lower-third graphic only between seconds 5 and 15. The t variable represents the timestamp in seconds.

You can combine multiple timed overlays by chaining filters. Each overlay adds one layer:

ffmpeg -i main.mp4 -i intro.png -i cta.png -filter_complex \
  "[0:v][1:v]overlay=0:0:enable='between(t,0,5)'[tmp];[tmp][2:v]overlay=(W-w)/2:H-h-50:enable='between(t,30,40)'" \
  output.mp4

This shows intro.png for the first 5 seconds, then cta.png centered near the bottom from 30 to 40 seconds.

Running Overlay Commands with FFmpeg Micro API

Building these commands locally is fine for testing. Running them in production means provisioning servers, managing FFmpeg installations, and handling job queues. FFmpeg Micro runs your overlay commands as API calls.

curl -X POST https://api.ffmpeg-micro.com/v1/transcodes \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "inputs": [
      {"url": "https://storage.example.com/main.mp4"},
      {"url": "https://storage.example.com/overlay.png"}
    ],
    "outputFormat": "mp4",
    "options": [
      {"option": "-filter_complex", "argument": "[0:v][1:v]overlay=W-w-10:H-h-10"}
    ]
  }'

The inputs array maps to FFmpeg's -i flags in order. The options array passes any FFmpeg flags you'd use on the CLI. Same filter syntax, no infrastructure.

Common Pitfalls

Pixel format mismatches. If your overlay has transparency (PNG with alpha), you may need format=yuva420p on the overlay or format=yuv420p on the output to avoid color issues. Adding format=auto to the overlay filter can help: overlay=10:10:format=auto.

Forgetting to map audio. The examples above only handle video. Your output will be silent unless you map the audio stream explicitly. Add -map 0:a -c:a copy to carry the main video's audio through.

Using -vf instead of -filter_complex. The -vf flag only works with a single input. The moment you have two -i flags and need to combine them, you must switch to -filter_complex. This trips up nearly everyone the first time.

FAQ

How do I put a logo in the corner of a video with FFmpeg?

Use the overlay filter with position variables. For bottom-right placement: ffmpeg -i video.mp4 -i logo.png -filter_complex "[0:v][1:v]overlay=W-w-10:H-h-10" output.mp4. The W and H variables reference the main video dimensions, while w and h reference the overlay dimensions.

Can I overlay a video on top of another video in FFmpeg?

Yes. The syntax is identical to image overlays. Use two -i inputs and the overlay filter: ffmpeg -i background.mp4 -i foreground.mp4 -filter_complex "[0:v][1:v]overlay=x:y" output.mp4. Set eof_action=pass if the overlay video is shorter than the background.

How do I make a picture-in-picture effect in FFmpeg?

Chain the scale and overlay filters. Scale the PiP stream first, then overlay it: [1:v]scale=320:180[pip];[0:v][pip]overlay=W-w-20:20. This scales the second input to 320x180 and positions it in the top-right corner.

Why is my FFmpeg overlay output missing audio?

The overlay filter only processes video streams. You need to explicitly map the audio: add -map 0:a -c:a copy to your command to copy the main video's audio track to the output.

How do I show an overlay only during a specific time range?

Use the enable parameter with a between expression: overlay=0:0:enable='between(t,5,15)'. This shows the overlay only between 5 and 15 seconds. The t variable is the current timestamp in seconds.

Every overlay command you can run locally works the same way through the FFmpeg Micro API. Skip the server setup and run filter_complex pipelines as HTTP requests.

About Javid Jamae

Founder & CEO at FFmpeg Micro

Javid is a software engineer, author, and entrepreneur with over 25 years of professional software development experience across enterprise, startup, and consulting environments. He founded FFmpeg Micro to make video processing accessible to developers through a simple, automation-first REST API.

Software EngineeringVideo ProcessingFFmpegCloud ArchitectureAPI DesignAutomation

Ready to process videos at scale?

Start using FFmpeg Micro's simple API today. No infrastructure required.

Get Started Free