Overlay images on video: skip the editor, use one API call

You have 40 clips that each need a logo in the corner and a name banner that appears at 0:03 and leaves at 0:08. Opening Premiere, After Effects, or CapCut for that means 40 timelines, 40 exports, and 40 chances to nudge the banner three pixels off. The overlay itself takes a few hundred milliseconds of compute; the editor is the slow part.
Quick answer: Use FFmpeg'soverlayfilter to overlay images on video:ffmpeg -i in.mp4 -i logo.png -filter_complex "[0:v][1:v]overlay=W-w-24:24" out.mp4puts a PNG 24 pixels from the top-right corner. To overlay images on video from an API instead, send the source video URL, the overlay image URL, and x/y coordinates to a video API like FFmpeg Micro, then download the rendered file when the job reports done. No editor, no FFmpeg install, no render queue.
Overlaying isn't an editing problem, it's a coordinate problem
Conventional wisdom says compositing needs a timeline: you drag a PNG onto a track, scrub to find the in-point, keyframe an opacity fade. Most tutorials teach exactly that, and for a one-off hero video it's the right call.
But a lower third is not a creative decision at render time. It's four numbers and a font: x, y, start second, end second. Once you've designed the banner, every subsequent clip is data entry. That's why the fix isn't a faster editor, it's not opening an editor at all. The compositor you already have is FFmpeg's overlay filter, and it takes those four numbers directly.
The one command that overlays an image on video
overlay takes two video inputs and paints the second onto the first. Position is set with x and y, and both accept expressions built from four variables that FFmpeg fills in for you.
ffmpeg -i input.mp4 -i logo.png \
-filter_complex "[0:v][1:v]overlay=x=W-w-24:y=24:format=auto" \
-map 0:a -c:a copy -c:v libx264 -crf 20 -preset medium output.mp4
W and H are the main video's width and height. w and h are the overlay's. That gives you the whole positioning grid without hardcoding pixels:
| Position | Expression |
|---|---|
| Top-left | `x=24:y=24` |
| Top-right | `x=W-w-24:y=24` |
| Bottom-right | `x=W-w-24:y=H-h-24` |
| Bottom-center | `x=(W-w)/2:y=H-h-60` |
| Dead center | `x=(W-w)/2:y=(H-h)/2` |
To knock the logo back so it doesn't fight the footage, pre-multiply its alpha before the overlay: [1:v]format=rgba,colorchannelmixer=aa=0.55[wm];[0:v][wm]overlay=W-w-24:24. That's 55% opacity, and it's the single most common tweak after position.
If the whole job is a logo stamp, that command is what our Watermark blueprint runs behind a form: upload the video, pick the corner and size, download. Same filter, no shell.
Lower thirds: timing, fades, and the timeline gotcha
A lower third is an overlay with an in-point and an out-point. enable='between(t,2,7)' turns the overlay on at 2 seconds and off at 7, where t is the main video's clock in seconds.
The gotcha is the fade. fade runs on the overlay input's own timeline, which for a still image starts at zero no matter when the banner appears. So you fade at 0, then shift the whole overlay stream forward with setpts:
ffmpeg -i input.mp4 -loop 1 -i lower-third.png \
-filter_complex "\
[1:v]format=rgba,\
fade=t=in:st=0:d=0.4:alpha=1,\
fade=t=out:st=4.6:d=0.4:alpha=1,\
setpts=PTS+2/TB[lt];\
[0:v][lt]overlay=x=60:y=H-h-90:enable='between(t,2,7)'[v]" \
-map "[v]" -map 0:a -c:a copy -c:v libx264 -crf 20 -pix_fmt yuv420p out.mp4
Read the overlay chain on its own clock: fade in over the first 0.4s, hold, fade out starting at 4.6s for a 5-second banner. setpts=PTS+2/TB slides that 5-second block to start at t=2, and enable clips anything outside the window. Get the two clocks mixed up and the banner appears already faded out, which is the most common "my fade doesn't work" report on the FFmpeg user list.
Don't want to design a PNG? Draw the banner in the filter graph with drawbox and drawtext:
-vf "drawbox=x=60:y=H-170:w=640:h=100:color=black@0.65:t=fill:enable='between(t,2,7)',\
drawtext=fontfile=/Library/Fonts/Arial.ttf:text='Dana Reyes':fontsize=42:fontcolor=white:x=88:y=H-148:enable='between(t,2,7)'"
That renders text directly, no design tool in the loop. drawtext has real limits once you want per-word timing, which is why karaoke-style captions need the ass filter instead.
Picture-in-picture and logos that survive every resolution
Picture-in-picture is the same filter with the second input scaled down and given a border. Scale, pad, overlay:
ffmpeg -i screen.mp4 -i webcam.mp4 \
-filter_complex "[1:v]scale=480:-2,pad=iw+8:ih+8:4:4:white[pip];\
[0:v][pip]overlay=x=W-w-30:y=H-h-30:shortest=1[v]" \
-map "[v]" -map 0:a -c:v libx264 -crf 20 -pix_fmt yuv420p pip.mp4
Batches break this. A logo sized in fixed pixels looks right on your 1920x1080 master and cartoonishly large on the 720p or 9:16 variant of the same clip. Size it relative to the video instead, using scale2ref to measure the main input:
-filter_complex "[1:v][0:v]scale2ref=w=-2:h=main_h*0.12[logo][vid];\
[vid][logo]overlay=W-w-24:24"
That pins the logo to 12% of frame height on every input. Note w=-2 rather than -1: -1 can produce an odd width, and libx264 with yuv420p rejects odd dimensions. Recent FFmpeg builds print a deprecation warning for scale2ref and point you at the scale filter's reference options; the command above still runs.
FFmpeg CLI versus one API call
The filter graph is free. The infrastructure around it is what costs you, especially once overlays run on every upload rather than on your laptop.
| Raw FFmpeg | FFmpeg Micro API | |
|---|---|---|
| Setup | Install FFmpeg, pin a version, ship fonts | None |
| Where it runs | Your box, container, or a Lambda that times out | Managed workers |
| Long jobs | You babysit the process | Poll the job or take a webhook |
| Fonts for `drawtext` | Bundle them or hit `Fontconfig error` | Handled server-side |
| Fits in n8n / Make / Zapier | Execute Command node, disabled by default in n8n v2.0+ | HTTP node |
| Cost model | Instance hours whether or not you render | Free tier, then usage |
The API version is the same job expressed as JSON: source video URL, overlay image URL, position, start and end time. Submit it, poll or take a webhook, download the output. Check the docs for the exact parameter names before wiring it into production.
curl -X POST https://api.ffmpeg-micro.com/jobs \
-H "Authorization: Bearer $FFMPEG_MICRO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://cdn.example.com/clip.mp4",
"overlay_url": "https://cdn.example.com/lower-third.png",
"x": 60, "y": "H-h-90",
"start": 2, "end": 7
}'
The reason this matters in n8n specifically: n8n disabled the Execute Command node by default in v2.0, so shelling out to FFmpeg on n8n Cloud is no longer an option. Pass URLs to an HTTP node and take a webhook back, and the video bytes never touch your workflow memory. That's the same architecture that keeps intro and outro assembly and multi-clip composition from blowing up an instance.
Common pitfalls
These five account for nearly every broken overlay command I've seen posted:
- Black box instead of a transparent logo. Your overlay is a JPEG, which has no alpha channel. Export PNG or WebP with transparency, and add
format=rgbato the overlay chain before any fade. - Silent output. The moment you use
-filter_complexwith-map "[v]", FFmpeg stops auto-selecting streams. Add-map 0:a -c:a copyor your audio disappears. Cannot find a matching stream for unlabeled input pad 1 on filter Parsed_overlay_0. You gaveoverlayonly one labeled input. It always needs two:[0:v][1:v]overlay=....height not divisible by 2. Ascale=...:-1produced an odd number. Use-2instead, which rounds to the nearest even value.- Plays in VLC, black in Safari and QuickTime. Add
-pix_fmt yuv420p. Filter graphs often leave the stream in a pixel format those players won't touch.
One more that costs money rather than time: overlaying forces a full re-encode of the video stream. You can't -c:v copy your way out of it. Pick -crf 20 -preset medium as a sane default and read the bitrate and codec math if the output is heavier than the source.
When you should still open an editor
If the overlay position needs to follow a moving subject, or you're masking, rotoscoping, or color-matching the banner to the footage, use After Effects or DaVinci Resolve. Expression-driven x and y can animate a slide-in, but they can't track a face.
Same for a single hero video where the design isn't settled. Iterating on placement is genuinely faster with a scrubber than with a render loop. The API wins when the design is locked and the volume is above roughly ten clips, which is where manual export time stops being noise.
FAQ
How do I overlay an image on video without Premiere or After Effects?
Run FFmpeg's overlay filter, or send the job to a video API. ffmpeg -i in.mp4 -i logo.png -filter_complex "[0:v][1:v]overlay=W-w-24:24" out.mp4 composites a PNG onto video in one command with no editor installed. Both paths produce the same pixels; the editor only adds a timeline you don't need for a fixed-position graphic.
Can I add a lower third to video programmatically?
Yes. Combine overlay with enable='between(t,start,end)' to control when the banner appears, and fade with alpha=1 on the overlay input for the in and out transitions. Fade times are measured on the overlay's own timeline, not the main video's, so shift the overlay with setpts=PTS+N/TB to place it.
How do I put a logo on 200 videos at once?
Loop the same filter over your file list, or submit one job per video to a video API and let the workers run in parallel. The API path is what most people mean by batch here, because 200 sequential local encodes will pin your CPU for hours while 200 queued jobs finish concurrently.
Does an overlay reduce video quality?
Slightly, because adding an overlay requires re-encoding the video stream. Stream copy (-c:v copy) is impossible once you touch pixels. At -crf 18 to -crf 20 with libx264 the loss is not visible on normal footage.
Can AI agents do video overlays?
Yes, through an MCP server. FFmpeg Micro exposes video processing as MCP tools, so Claude or another agent can stamp a watermark or place a lower third as a tool call inside a longer workflow.
Pick one clip that needs a logo and a name banner, and run it through the API before you build the batch loop. The free tier covers enough jobs to confirm the coordinates are right: sign up free.
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.
You might also like

Batch transcode a folder of videos with one workflow
How to batch transcode a folder of videos with one workflow: fan out jobs to a video API, handle retries and webhooks, and skip the FFmpeg install.

Video watermarking API: protect UGC and branded content
A video watermarking API for UGC and branded content: FFmpeg overlay commands, the one-call equivalent, batch workflows in n8n or Make, and the honest limits.

The Best GUI for FFmpeg (And When You Don't Need One)
An honest, tested rundown of the best GUI for FFmpeg: HandBrake, FastFlix, Videomass, ViComp, and when a browser playground and one API call beat a window.
Skip the command line
The Logo Watermark blueprint stamps your logo on the video for you: upload both files, pick a corner, done.
Run it (free)