ffmpeg animated gif overlay, animation starts before specified 'between' - ffmpeg

I am adding an animated gif as an overlay to a video with a command like this:
ffmpeg -y -i video.mp4 -i overlay.gif -filter_complex "[0:v][1:v] overlay=38:11:enable='between(t,1.35,15.042000)'" -pix_fmt yuv420p -c:a copy -safe 0 output.mp4
In that command I'm asking it to show the gif from 1.35 to 15, and that works insofar as the overlay is only shown between those times, but it's as if the animation starts before it reaches 1.35, because the bit of the animation before that point doesn't ever appear on the screen. The start of the animation is missing from the final video.
Tried in ffmpeg-20180925-a7429d8 and ffmpeg-N-100581-ga454a0c14f

Typically, I find the answer after posting:
https://dev.to/oskarahl/ffmpeg-overlay-a-video-on-a-video-after-x-seconds-4fc9
Solution:
Use the setpts filter to delay the overlay video (gif.mp4) start with x seconds.
ffmpeg -i main_video.mp4 -i gif.mp4 -filter_complex
“[1:v]setpts=PTS-STARTPTS+1/TB[delayedGif];
[0:v][delayedGif]overlay=enable='between(t,1,3)'[out]”
-map [out] complete.mp4
The setpts filter evaluates its expression and assigns the value as the timestamp for the current frame it is processing.

Related

Ffmpeg/lavfi Is it possible to fade out an image overlay that was loaded with a movie= filter not a -i parameter

I've tried something like:
movie='overlaylogo.png',fade=out:st=5:d=1[logo],[in][logo]overlay='0:0'[out]
But it seems to stick on 100% opacity, adding in a loop=loop-1 and fps=24 filter after the movie= load seem to have little effect, is there some step required to convert an image into a video for fade to apply over?
The key is to keep your stream alive so the fade filter can do its job. An image input dies immediately after it sends out its frame.
With -i we'd do
ffmpeg -i input.mp4 -loop 1 -i logo.png \
-filter_complex [1:v]fade=out:st=5:d=1:alpha=1,[0:v]overlay=0:0:shortest=1[out] \
-map [out] -map 0:a output.mp4
The -loop image2 input option keeps the stream alive. The same thing must be done with movie source filter. It has loop option but with a caveat: "Note that when the movie is looped the source timestamps are not changed, so it will generate non monotonically increasing timestamps." So, you need to add setpts filter to establish monotonically increasing timestamps yourself:
ffmpeg -i input.mp4 \
-vf movie=logo.png:loop=0,setpts=N/FR/TB,fade=out:st=5:d=1,[in]overlay=0:0:shortest=1[out] \
output.mp4
P.S., loop=-1 (not 1) should also work (and it likely won't need the setpts filter to fix the timestamp).

ffmpeg: sliding overlay for filter comparison

I am trying to get the effect demonstrated in this video: https://www.youtube.com/watch?v=xrMZSLb_gPs
Most of the sliding overlay solutions I've seen are for a sliding fixed image, but not for a progressive crop of each part of the video.
I've tried doing:
ffmpeg -i video1.mp4 -i video2.mp4 \
-filter_complex "[0]crop='min(iw*(1+n)/100,iw)':ih:0:0[left];[1]crop='max((1-n/100)*iw,1)':ih:1-'max((1-n/100)*iw,1)':0[right];[left][right]hstack[out]" -map '[out]' -y out.mp4
But it still does not work. Is there a way?
Thank you!
Use the xfade filter:
ffmpeg -i video1.mp4 -i video2.mp4 -filter_complex "xfade=transition=wiperight:duration=5:offset=1" output.mp4
transition chooses the style/effect.
duration is how long the transition lasts.
offset is number of seconds before transition begins.

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!

gifs not loops in ffmpeg movie filter

I have a gif that loops infinite(loop.gif). I want to overlay this gif to top left corner of video.mpg. So I am using this code to make this:
ffmpeg -i video.mpg -vf "movie=loop.gif [logo]; [in][logo] overlay=10:10 [out]" -vcodec mpeg2video out.mpg
The problem is; gif loops only 1 time and last frame of the gif showing until end of video.mpg.
How can I loop this gif continuously?
Use the -ignore_loop option from the GIF demuxer:
ffmpeg -i video.mp4 -ignore_loop 0 -i loop.gif -filter_complex "[0:v][1:v]overlay=10:10:shortest=1" output.mp4
See the GIF demuxer documentation or run ffmpeg -h demuxer=gif for more options.
No need to use the movie source filter.
This example uses the shortest option in the overlay filter. Otherwise the encoding will run indefinitely due to the looping GIF.

Show watermark at the beginning of the video

Need to add watermark for first 3 seconds the video using ffmpeg. Here's what I got right now:
ffmpeg -y -i '255871.mov' -qscale:v 0 -qscale:a 0 -vf '[in] transpose=1 [out];movie=watermark.png , select=lte(t\,3) [bg]; [out][bg] overlay=x=20:y=main_h-60 [out]' output.mp4
It rotates video to the right and adds watermark at the bottom of the video for first 3 seconds. The problem is watermark is visible during the whole video.
Thought that select doesn't work at all. Tried following command
ffmpeg -y -i '255871.mov' -qscale:v 0 -qscale:a 0 -vf '[in] transpose=1 [out];movie=watermark.png , select=0 [bg]; [out][bg] overlay=x=20:y=main_h-60 [out]' output.mp4
Watermark is not visible. This is correct and proves that select filter works as expected. As I understand this is how ffmpeg works: it leaves last frame of the shortest video visible.
How can I force ffmpeg to discard show watermark after N seconds?
Have to answer it myself. ffmpeg mailing list helped me to solve the issue.
The main idea is to convert existing watermark into video using Apple Animation codec (it supports transparency) and fade out last frame of created video using fade filter.
Example:
ffmpeg -loop 1 -i watermark.png -t 3 -c qtrle -vf 'fade=out:73:1:alpha=1' watermark.mov
ffmpeg -y -i '255871.mov' -qscale:v 0 -qscale:a 0 -vf '[in] transpose=1 [out];movie=watermark.mov [bg]; [out][bg] overlay=x=20:y=main_h-60 [out]' output.mp4
Fade out is required because ffmpeg uses last frame of overlaid video for the rest of the video. This filter makes last frame fully transparent via alpha=1 parameter. In fact it should be fade=out:74:1:alpha=1, but it didn't work for me, don't know why

Resources