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
Related
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.
I'm trying to overlap an animated gif over a video with no success.
My goals are the next:
gif animation have to loop until video ends.
gif is scaled so it covers the whole video.
gif preserves transparency.
The most I have achieved regarding this is that the gif covers the whole video with the scale filter and that it loops until video ends (but this not in the best way, I guess).
Regarding loop I know I can use -ignore_loop 0 gif filter parameter with shortest=1 in overlay but this way it is not working so I ended up with -frames:v 900 (my video is 30fps and 30sec long so 900 is the number of frames).
My most important issue is I'm not able to keep gif transparency and everything I've tried resulted in no success.
This is my ffmpeg command with arguments, so I hope anybody can help (I'm using ffmpeg 4.1).
ffmpeg -y
-i videoin.mp4
-i anim01.gif
-filter_complex [1:v]scale=1080:1920[ovrl] [0:v][ovrl]overlay=main_w-overlay_w:main_h-overlay_h
-frames:v 900
-codec:a copy
-codec:v libx264
-preset ultrafast
video.mp4
Ok, I'll answer my own question. The first part, not being able to achieve gif transparency, such a silly issue!! The gif I was using was not transparent and I didn't realized!! OMG, I thought, so this is the first thing to check whenever you have a transparency issue.
The second, looping the gif until the video ends, I wasn't able to do it with -ignore_loop 0 along with shortest=1 but what I did is -ignore_loop 0 and -frames:v 900 and that worked like a charm.
What was not working was not the -ignore_loop 0 but the shortest=1 and so ffmpeg was never ending encoding but if you set it to finish at a certain number of frames that resolves the problem.
900 comes from 30fps x 30 sec video.
In the end, my complete ffmpeg command line parameters ended up as follows:
ffmpeg -y -i xxx.mp4 -ignore_loop 0 -i xxx.gif -filter_complex "[1:v]scale=1080:1920[ovrl];[0:v][ovrl]overlay=0:0" -frames:v 900 -codec:a copy -codec:v libx264 -max_muxing_queue_size 2048 video.mp4
Hello Guys if anyone want to add gif to video use this command. Deffienetly you will get the right answer
String strFilter = "[1:v]scale=h=-1:w=100[overlay_scaled],"
+ "[0:v][overlay_scaled]overlay=shortest=1:x=W*0:y=H*0";
String[] complexCommand = new String[] {
"-i",
yourRealPath,
"-itsoffset",
String.valueOf(0),
"-ignore_loop", "0", "-i",
fullPath,
"-filter_complex",
strFilter,
"-frames:v", "900", "-preset",
"ultrafast",
"-g",
"120",
dest.getAbsolutePath()
};
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!
trying to get my head around ffmpeg to create a slideshow where each image is displayed for ~5 seconds with some audio. created a bat file to run the following so far:
ffmpeg -f image2 -i image-%%03d.jpg -i music.mp3 output.mpg
It gets the images and displayes them all very fast in the first second of the video, it then plays out the rest of the audio while showing the last image.
I want to make the images stay up longer (about 5 seconds), and stop the video after the last frame (not playing the rest of the song), are either of these things possible? i could hack the frame rate thing i guess by having hundreds of the same image in order to keep it up longer, but this is far from ideal!
Thanks
The default encoder for mpg output, mpeg1video, is strict about the allowed frame rates, so an input and an output -r are required:
ffmpeg -r 1/5 -i image-%03d.jpg -i music.mp3 -r 25 -qscale:v 2 -shortest -codec:a copy output.mpg
The input images will have a frame rate of 1 frame every 5 seconds and the output will duplicate frames to reach 25 frames per second.
-f image2 is generally not required.
-qscale:v can control output quality. A sane range is 2-5.
-shortest will make the output duration the same as the shortest input duration.
-codec:a copy copy your MP3 audio instead of re-encoding.
MPEG-1 video has more modern alternatives. See the FFmpeg and x264 Encoding Guide for more info.
Also see:
* FFmpeg FAQ: How do I encode single pictures into movies?
* FFmpeg Wiki: Create a video slideshow from images
You could use the filter fps instead of output framerate
ffmpeg -r 1/5 -i img%03d.png -i musicfile -c:v libx264 -vf fps=25 -pix_fmt yuv420p out.mp4
This however skips the last image for me strangely.
ffmpeg -i v.3gp -acodec copy -vf "movie=w.png [logo]; [in][logo] overlay=10:main_h-overlay_h-10 [out]" nv.3gp
It work's fine, but i want watermark only first 30 seconds.
Any ideas?
You can convert the logo into a 30 second video with png codec and alpha channel, and apply the video as overlay.
The duration of the logo video should be specified through the number of frames at the frame rate of the main video (in your case, v.3pg). For example, for 30 fps main video run:
ffmpeg.exe -loop 1 -i w.png -vframes 901 -vf "fade=out:899:1:alpha=1"
-vcodec png -pix_fmt rgba w.mov
The logo needs to be faded out; otherwise it will not disappear. Then use the logo video as overlay on another video:
ffmpeg -i v.3gp -acodec copy -vf "movie=w.mov [logo]; [in][logo]
overlay=10:main_h-overlay_h-10 [out]" nv.3gp
Alternatively, rather then ending abruptly, the logo can be faded out gradually, e.g. within 30 frames using -vf "fade=out:870:30:alpha=1".
overlay filter supports timeline editing; you can simply read from a png file and then overlay=enable='lte(t,30)':...
Realize it's late, but as I was looking at a similar problem I managed to solve this one.
It fades in with 0.5 sec from start, then fades out at 30 sec
ffmpeg \
-i v.3gp \
-loop 1 -i w.png \
-acodec copy \
-filter_complex \
"[1:v] fade=in:st=0:d=0.5,fade=out:st=30:d=0.5 [logo]; [0:v][logo] overlay=10:main_h-overlay_h-10" \
nv.3gp
You may cut the first 30 seconds, apply watermark to it, then join it with the remaining part.