Overlay animated images with transparency over a static background image using ffmpeg? - ffmpeg

I'm looking to create a video using a set of png images that have transparency merged with a static background.
After doing a lot of digging I seems like it's definitely possible by using the filters library.
My initial video making without including the background is:
ffmpeg -y -qscale 1 -r 1 -b 9600 -loop -i bg.png -i frame_%d.png -s hd720 testvid.mp4
Using -vf I can apply the background as overlay:
ffmpeg -y -qscale 1 -r 1 -b 9600 -i frame_%d.png -vf "movie=bg.png [wm];[in][wm] overlay=0:0 [out]" -s hd720 testvid.mp4
However the problem is it's overlaying the background over the input. According libacfilter I can split the input and play with it's content. I'm wondering if I can somehow change the overlay order?
Any help greatly appreciated!
UPDATE 1:
I'm trying to make the following filter work but I'm getting the movie without the background:
ffmpeg -y -qscale 1 -r 1 -b 9600 -i frame_%d.png -vf "movie=bg.png [bg]; [in] split [T1], fifo, [bg] overlay=0:0, [T2] overlay=0:0 [out]; [T1] fifo [T2]" -s hd720 testvid.mp4
UPDATE 2:
Got video making using -vf option. Just piped the input slit it applied image over it and overlayed the two split feeds! Probably not the most efficient way... but it worked!
ffmpeg -y -r 1 -b 9600 -i frame_%d.png -vf "movie=bg.png, scale=1280:720:0:0 [bg]; [in] format=rgb32, split [T1], fifo, [bg] overlay=0:0, [T2] overlay=0:0 [out]; [T1] fifo [T2]" -s hd720 testvid.mp4

The overlay order is controlled by the order of the inputs, from the ffmpeg docs
[...] takes two inputs and one output, the first input is the "main" video on which the second input is overlayed.
You second command thus becomes:
ffmpeg -y -loop 1 -qscale 1 -r 1 -b 9600 -i frame_%d.png -vf "movie=bg.png [wm];[wm][in] overlay=0:0" -s hd720 testvid.mp4
With the latest versions of ffmpeg the new -filter_complex command makes the same process even simpler:
ffmpeg -loop 1 -i bg.png -i frame_%d.png -filter_complex overlay -shortest testvid.mp4
A complete working example:
The source of our transparent input images (apologies for dancing):
Exploded to frames with ImageMagick:
convert dancingbanana.gif -define png:color-type=6 over.png
(Setting png:color-type=6 (RGB-Matte) is crucial because ffmpeg doesn't handle indexed transparency correctly.) Inputs are named over-0.png, over-1.png, over-2.png, etc.
Our background image (scaled to banana):
Using ffmpeg version N-40511-g66337bf (a git build from yesterday), we do:
ffmpeg -loop 1 -i bg.png -r 5 -i over-%d.png -filter_complex overlay -shortest out.avi
-loop loops the background image input so that we don't just have one frame, crucial!
-r slows down the dancing banana a bit, optional.
-filter_complex is a very recently added ffmpeg feature making handling of multiple inputs easier.
-shortest ends encoding when the shortest input ends, which is necessary as looping the background means that that input will never end.
Using a slightly less cutting-edge build, ffmpeg version 0.10.2.git-d3d5e84:
ffmpeg -loop 1 -r 5 -i back.png -vf 'movie=over-%d.png [over], [in][over] overlay' -frames:v 8 out.avi
movie doesn't allow rate setting, so we slow down the background instead which gives the same effect. Because the overlaid movie isn't a proper input, we can't use -shortest and instead explicitly set the number of frames to output to how many overlaid input frames we have.
The final result (output as a gif for embedding):

for references in the future as of 17/02/2015, the command-line is :
ffmpeg -loop 1 -i images/background.png -i images/video_overlay%04d.png -filter_complex overlay=shortest=1 testvid.mp4
thanks for llogan who took the time to reply here : https://trac.ffmpeg.org/ticket/4315#comment:1

Related

Add image.png to top of image.jpg with ffmpeg became more dark

I try to create frame for picture use FFMPEG so its logic same as watermark. so i used this code
ffmpeg -i output_1920x1280.jpg -vf "movie=cpf-border.png [watermark]; [in][watermark] overlay=0:0 [out]" -q:v 1 withBorder.jpg
and try with diff command like this
ffmpeg -i output_1920x1280.jpg -i cpf-border.png -pix_fmt rgba -filter_complex "overlay=0:0" withBorder.jpg
but still same. there no error but the result of image its more dark. cause the frame base on white color so i saw that when do side by side can you help me maybe there another syntax to handle this or use another tools
It looks like there is some kind of bug related to YCbCr color space conversion.
We may select rgba format for each input before the overlay, and select rgb24 format after the overlay:
ffmpeg -y -i output_1920x1280.jpg -i cpf-border.png -filter_complex "[0]format=rgba[v1];[1]format=rgba[v2];[v1][v2]overlay=0:0,format=rgb24" -q:v 1 -src_range 0 -dst_range 1 withBorder.jpg
Result:

FFmpeg | Option loop not found

The loop option is not working with gif image.
When I'm working with png image the code good.
But when I'm working with animated gif image the error is thrown Option loop not found.
In my example I'm trying to create the video from input image with specific duration.
ffmpeg -loop 1 -t 5 -i 15324210315b56e3a78abe5.png -i watermark.png -filter_complex "[0]scale=trunc(iw/2)*2:trunc(ih/2)*2[v];[v][1]overlay=x=(W-w-10):y=(H-h-10)" output.mp4
Below command is not working
ffmpeg -loop 1 -t 5 -i 15323488345b55c9a2b2908.gif -i watermark.png -filter_complex "[0]scale=trunc(iw/2)*2:trunc(ih/2)*2[v];[v][1]overlay=x=(W-w-10):y=(H-h-10)" output.mp4
GIFs are handled by a seperate demuxer module, not the generic image sequence demuxer. The gif demuxer has a separate option. See command below.
ffmpeg -ignore_loop 0 -t 5 -i 15323488345b55c9a2b2908.gif ...
The python script for gif to video conversion using ffmpeg library
f"/opt/ffmpeglib/ffmpeg -ignore_loop 0 -i {lambda_file_path} -c:v libx264 -t 10 -pix_fmt yuv420p {lambda_output_file_path}

I can't overlay and center a video on top of an image with ffmpeg. The output is 0 seconds long

I have an mp4 that I want to overlay on top of a jpeg. The command I'm using is:
Ffmpeg -y -i background.jpg -i video.mp4 -filter_complex "overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2" -codec:a copy output.mp4
But for some reason, the output is 0 second long but the thumbnail does show the first frame of the video centred on the image properly.
I have tried using -t 4 to set the output's length to 4 seconds but that does not work.
I am doing this on windows.
You need to loop the image. Since it loops indefinitely you then must use the shortest option in overlay so it ends when video.mp4 ends.
ffmpeg -loop 1 -i background.jpg -i video.mp4 -filter_complex \
"overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2:shortest=1" \
-codec:a copy -movflags +faststart output.mp4
See overlay documentation for more info.
Well you should loop the image until the video duration. So to do the you need to add -loop 1 before the input image. Then the image will have a infinite duration. So to control it specify -shortest before the output file which will trim all the streams to the shortest duration among them. Else you can use -t to trim the image duration to the video length. This will do what you want.
Hope this helps!

Ffmpeg video overlay

I am trying to create a video output from multiple video cameras.
Following the example given here Presenting more than 2 videos using FFmpeg
and other similar examples.
but Im getting the error
Output pad "default" for the filter "src" of type "buffer" not connected to any destination
when i run
ffmpeg -i /dev/video1 -i /dev/video0 -filter_complex "[0:0]pad=iw*2:ih[a];[a][1:0]overlay=w[b];[b][2:0]overlay=w:h" -shortest output.mp4
Im not really sure what this means or how to fix it.
Any help would be greatly appreciated!
Thanks.
When using the "padding" option, you have to specify which is the size of the output image and where you want to put the input image
[0:0]pad=iw*2:ih:0:0
tested under windows 7 with file of same size
ffmpeg -i out.avi -i out.avi -filter_complex "[0:0]pad=iw*2:ih:0:0[a];[a][1:0]overlay=w" -shortest output.mp4
and with WebCam Cap (vfwcap) and a still picture (as i have only o=1 WebCam). BTW you can see how to scale one the source to fit in the target (just in case your source have different resolution)
ffmpeg -y -f vfwcap -r 10 -i 0 -loop 1 -i photo.jpg -filter_complex "[0:0]pad=iw*2:ih:0:0[a];[1:0]scale=640:480[b];[a][b]overlay=w" -shortest output.mp4
under Linux:
ffmpeg -i /dev/video1 -i /dev/video0 -filter_complex "[0:0]pad=iw*2:ih:0:0[[a];a][1:0]overlay=w" -shortest output.mp4
if it doesn't work test a simple record of video 1 and after of video 0 and check their properties (type, resolution, fps).
ffmpeg -i /dev/video1 -shortest output1.mp4
ffmpeg -I output1.mp4
If you still have issue, update your question with ffmpeg console output (as text) for video and video 0 capture and also of the call with the overlay

How to scale and position watermark to scale?

I'm scaling a video and applying a watermark like so:
ffmpeg -ss 0:0:0.000 -i video.mp4 -y -an -t 0:0:10.000
-vf \"[in]scale=400:316[middle]\" -b:v 2000k -r 20
-vf 'movie=watermark.png,pad=400:316:0:0:0x00000000 [watermark];[middle] [watermark]overlay=0:0[out]'
out.flv
However, the applied watermark seems to be scaled to the original video size rather than the smaller scaled video size.
This command line worked on ffmpeg version 0.8.6.git and now behaves differently after an upgrade to version N-52381-g2288c77.
How do I get it to work again?
Update 2013-04-26:
I now have tried to use the overlay filter's X and Y parameters instead of padding without success.
Answered by ubitux on the FFmpeg IRC:
Use scale and overlay in a single -filter_complex chain, like so:
ffmpeg -y -ss 0 -t 0:0:30.0 -i 'video.mp4' -i '/watermark.png'
-filter_complex "[0:0] scale=400:225 [wm]; [wm][1:0] overlay=305:0 [out]"
-map "[out]" -b:v 896k -r 20 -an
'out.flv'
Also load the watermark via -i rather than the movie filter.

Resources