Overlay Media Node
Picture-in-picture for your finished videos, with ffmpeg doing the heavy lifting
- output_path
You generated a clip you like, and now you want a smaller version of it floating in the corner of another clip - a picture-in-picture. You could rebuild the whole thing in the node graph, or you could hand this node two file paths and let ffmpeg composite them for you. That's the entire pitch of Overlay Media Node, and it's genuinely the right tool for the job if your media already exists as files.
The name is a slight lie, by the way: it says "media" because the overlay can be a video or an image, passed as a path. And it doesn't process tensors - it takes two file paths, runs ffmpeg, and hands you back the path to a new mp4 on disk. File-level compositing, not frame-level, which is exactly why it works on arbitrary codecs and keeps your audio intact without you touching a single audio node.
How it works
The node probes both files with ffmpeg to get their dimensions and durations, then builds an ffmpeg filter graph. The overlay gets scaled (auto-fit to the main video if you leave the size at zero, keeping aspect ratio), shifted onto the timeline with setpts, and composited with the overlay filter, gated by enable=between(t,start,end) so it only shows up in your chosen window. If the overlay is shorter than the window, it loops. Audio is handled separately: keep the main clip's audio, take the overlay's, mix them, or drop audio entirely.
The one thing to know before you wire it up: main_media and overlay_media are STRING inputs with forceInput, which means you can't type a path into a widget. You wire them from a node that outputs a path - the pack's own VideoUpload node, a VHS_SelectFilename, or anything else that hands you a file path string.
The inputs that matter
- main_media / overlay_media - the base clip and the thing on top. Both are paths, both must exist or the node just logs "File not found" and quits.
- overlay_position - presets
left-top,left-bottom,right-top,right-bottom, or rawx,ycoordinates if you want it somewhere in between. - overlaysize_width / overlaysize_height - set both to
0to auto-fit the overlay to the main video. If you set a size, it scales the overlay to that exactly. - start / end - the time window (in seconds) when the overlay is visible. Leave
endat 0 and it defaults tostartplus the overlay's own duration. - audio_option -
main,overlay,mix, ornone. Default ismain, so the main clip keeps talking while the PiP floats over it.
The single output, output_path, is the path to the rendered file. The bundled Pic-in-Pic workflows feed that straight into VHS_LoadVideoPath (from VideoHelperSuite) to pull the result back into the graph for a preview or further processing - that's the pattern to copy: composite at the file level, then re-import if you need the frames.
Installing it
ComfyUI Manager is the easy route - search for ComfyUI Overlay Media Node and install. Or clone it by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/Elaine-chennn/comfyui-overlay-media
pip install -r requirements.txt
then restart ComfyUI. There are no model files and no GPU requirements; the only dependency is the Python ffmpeg wrapper. Here's the trap: that wrapper still needs the actual ffmpeg binary on your PATH. On the Windows portable build that usually isn't true, so grab a static ffmpeg build and make sure ffmpeg runs from a terminal before you blame this node.
Where people get burned
The output is always written as pip_gen.mp4 in your output folder - a fixed name that overwrites your last result on every run. If you want to keep renders, copy or rename them immediately. With overlay or mix audio it also drops pip_video.mp4 and pip_audio.aac intermediates into the same folder, so don't be surprised by the clutter. And if a run silently produces nothing, check your start/end: start must be earlier than end and inside the main clip, or the node logs an "Invalid start time" error and returns nothing.
This is a small, rough-around-the-edges pack - its category is literally overlay_media/test - but for slapping one finished clip onto another it's the fastest path in the graph, and it won't eat your audio while doing it.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| main_media | STRING | — | |
| overlay_media | STRING | — | |
| overlay_position | STRING | left-top | — |
| overlaysize_width | INT | 0 | — |
| overlaysize_height | INT | 0 | — |
| start | FLOAT | 0.00 | — |
| end | FLOAT | 0.00 | — |
| audio_option | COMBO | main | 4 options: main, overlay, mix, none |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| output_path | STRING | — |