Speed up poster image overlay - ffmpeg

Using FFMPG I'm creating a poster image from a video and adding an watermark/overlay to the poster. The following works great with small video files, but destroys my CPU with 1080p files.
ffmpeg -ss 15 -i preview.mp4 -i play-button.png \
-filter_complex overlay='(main_w-overlay_w)/2:(main_h-overlay_h)/2', \
scale='min(640\, iw):-1' -vframes 1 poster.jpg
Is there any way to speed this up? Or should I look to another solution for the overlay?

My solution is similar yours. But i use -s to set the output resolution for the image, and -f image2 for rendering. This commands works fine for me:
ffmpeg -ss 15 -i preview.mp4 -i play-button.png -filter_complex "overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2" -vframes 1 -s 640x360 -f image2 -y poster.jpg

Related

overlay multiple images on a video with specific time per image and repeat (loop) the process the images until video end

I am trying to making video with ffmpeg where I want to overlay images on a video.
I want to show the image for 5 secound each and want to the process to loop until the video end.
I am using following commend which working perfectly but want to modify to loop the images.
ffmpeg -y -i long_process/2-scrolling.mp4 \
-i upload-images/040820221255452.png \
-i upload-images/040820221255453.png \
-filter_complex "[0:v][1:v]overlay=75:(H-h)/2:enable='between(t, 1, 5)'[v0]; \
[v0][2:v]overlay=75:(H-h)/2:enable='between(t, 5, 10)'" \
-c:a copy long_process/output.mp4
I am very new to ffmpeg looking for help from you.
Thanks in advance
I got the answer
ffmpeg -y -i long_process/2-scrolling.mp4 -framerate 1/3 -pattern_type glob -loop 1 -i 'tools/*.png' \
-filter_complex "[0]overlay=75:(H-h)/2:shortest=1" \
-r 60 -c:a copy long_process/output.mp4

GIF overlays blink with ffmpeg

I've been playing around with ffmpeg over the past months and can't get rid of an issue I'm facing when adding a GIF file as an overlay.
Basically what I'm trying to achieve is to add a transparent GIF animation as an overlay on top of a MP4 video.
Please find below an example command that I'm using:
ffmpeg \
-i 0689a8a9-43b5-45d2-b0e8-acbea6905ce1.mp4 \
-ignore_loop 0 \
-i 02a6e696-969b-4a90-9444-e4b0b4d6f6da.gif \
-t 10.000000 \
-filter_complex "[0:v][1:v]overlay=enable='between(t, 1, 3)'[overlay]" \
-map '[overlay]' \
-pix_fmt yuv420p \
output.mp4
For a better understanding, please note that:
-ignore_loop 0 allows me to loop the animation as long as the overlay is enabled
-t makes my video last 10s
overlay=enable='between(t, 1.0, 3.0)' sets the interval during which it's visible
However, when I run this command, a very few milliseconds before the GIF disapears (at 3s), it starts blinking. If I run take a look at it frame by frame, it actually disappears from the video, then comes back, and eventually goes away as expected.
Please find an example with a black background and a random GIF from giphy at this link. The assets can be found here.
I'm probably missing something here. Do you have any hints ?
I'm running ffmpeg in 4.3.1.
Thank you in advance
I can replicate this with an arbitrary gif. I suspect a bug in the overlay filter. Feel free to present this to https://trac.ffmpeg.org.
This happens as soon as the temporal filtering is set (filter is listed as having timeline support) and furthermore changes depending on the time boundaries. The latter should never be the case.
MWE
ffmpeg \
-t 10 -s qcif -f rawvideo -pix_fmt rgb24 -r 25 -i /dev/zero \
-ignore_loop 0 -i 'https://media.tenor.com/images/c50ca435dffdb837914e7cb32c1e7edf/tenor.gif' \
-filter_complex "overlay=enable='between(t,3,7)'" \
-f flv - | ffplay -
You could try, as a workaround, converting the gif to an mp4 (ffmpeg -re -i <gif> [...]) and set the white areas to transparent.
In the official FFmpeg community there is a ticket for this, which hasn't been fixed though:
https://trac.ffmpeg.org/ticket/4803
The ticket mentions that a GIF is being shown before the specified enable time. On my tests, given a 60 fps video, a 10.42 fps GIF (that needs to be shown from 5 to 10 s) blinks once 5 frames before the desired time (at 4.933 s) and becomes visible again right at 5 s. Should be something connected to the GIF's fps which doesn't match the video's fps.
Anyways, I've found the most elegant workaround, which solves the problem in a single pass and doesn't require converting GIFs to temporary MP4s (because in some cases that could be undesired). So, given the video fps, to overlay a GIF at a certain position (x=10, y=20) from 5 to 10 s without blinking we should use the following:
ffmpeg -y -i "video.mp4" -ignore_loop 0 -i "giphy.gif" \
-filter_complex "[1:v]fps=60[gif];[0:v][gif]overlay=x=10:y=20:enable='between(t,5,10)'" \
-c:a copy -shortest "overlay.mp4"
We can go further and come up with a command line which doesn't require a prior knowledge of the video fps (but you should know the output video fps instead, which is 60 fps in this case):
ffmpeg -y -i "video.mp4" -ignore_loop 0 -i "giphy.gif" \
-filter_complex "[0:v]fps=60[video];[1:v]fps=60[gif];[video][gif]overlay=x=10:y=20:enable='between(t,5,10)'" \
-acodec copy -shortest "overlay.mp4"

FFMPEG: animation: Zoom In and zoom Out

How can I get the following effect with FFMPEG?
I know I have to do it with Zoompan, but the truth is, I've been trying for a while and I can not!
the following code works:
ffmpeg -loop 1 -i imagen.png -vf "scale=iw*4:ih*4,zoompan=z='if(lte(mod(on,60),30),zoom+0.002,zoom-0.002)':x='iw/2-(iw/zoom)/2':y='ih/2-(ih/zoom)/2':d=25*5" -c:v libx264 -t 5 -s "1280x720" out.mp4 -y
The code is based on the following (answered by Gyan):
FFMPEG How to zoom in and then zoom out in one command line.
Also, if there is a way to do it better, I invite you to participate.
Please try following command:
ffmpeg -y -i image.jpg \
-vf zoompan=d=300:z='if(gte(zoom,1.8)+eq(ld(1),1)*gt(zoom,1),zoom-0.03*st(1,1),zoom+0.03+0*st(1,0)):x=iw/2-(iw/zoom/2):y=ih/2-(ih/zoom/2)' \
-t 10 output.mp4
The code is based on the following:
https://video.stackexchange.com/questions/23651/ffmpeg-zoompan-in-and-out-alternately/23653#23653

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

Overlay animated images with transparency over a static background image using 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

Resources