Adding two overlays in FFMPEG - ffmpeg

I am adding an animated PNG overlay to an existing video with some text written right below the gif in ffmpeg using the command:
.\ffmpeg.exe -i vid.mp4 -ignore_loop 0 -i elephant.png -filter_complex "overlay=x=(main_w-overlay_w-10):y=(main_h-overlay_h-30):shortest=1, drawtext=fontfile=seguiemj.ttf:text='This is a test': fontcolor=white: fontsize=48: x=(w-text_w-250): y=(h-text_h-10)" output.mp4
Now, instead of text, I want to add another png in the same position as the text and using the same relative equations but I'm not sure how to write the variables for the second overlay? Since I'm already using overlay_w and overlay_h for the first image overlay, how can I define other variables for other overlay images?

Related

FFMpeg add drop shadow to a video

I have this example video, recorded by Kazam:
https://user-images.githubusercontent.com/1997316/178513325-98513d4c-49d4-4a45-bcb2-196e8a76fa5f.mp4
It's a 1022x728 video.
I need to add a drop shadow identical to the one generated by the "Drop shadow (legacy)" filter of Gimp with the default settings. So, I generated with Gimp a PNG containing only the drop shadow. It's a 1052x758 image:
Now I want to put the video over the image to get a new video with the drop shadow. The wanted effect for the first frame is:
So, the video must be placed over the image. The top-left corner of the video must be in the position 11x11 of the background image.
How can I achieve this result?
I tried without success the following command. What's wrong?
ffmpeg -i shadow.png -i example.mp4 -filter_complex "[0:v][1:v] overlay=11:11'" -pix_fmt yuv420p output.mp4
About the transparency of the PNG background image, if it can't be maintained, then it's okay for the shadow to be on a white background. Otherwise, if it can be maintained by using an animated GIF as the output format, it is better.
The solution is to remove the transparency from shadow.png. Then:
ffmpeg -i example.mp4 -filter_complex "[0:v] palettegen" palette.png
ffmpeg -loop 1 -i shadow.png -i example.mp4 -i palette.png -filter_complex "[1:v] fps=1,scale=1022:-1[inner];[0:v][inner]overlay=11:11:shortest=1[new];[new][2:v] paletteuse[out]" -map '[out]' -y output.gif
The result is exactly what I wanted:
This solution is inspired by the answer https://stackoverflow.com/a/66318325 and by the article https://www.baeldung.com/linux/convert-videos-gifs-ffmpeg

Rotate text in ffmpeg [duplicate]

I am trying to overlay some text on video using ffmpeg. I am able to overlay text by the bellow command.
ffmpeg -i input1.mp4 -filter_complex "[0:v]transpose=2[anticlockwiserotated];[anticlockwiserotated]drawtext=fontfile=../../public/fonts/Roboto-Regular-webfont.ttf: text='Test Text':x=100: y=50: fontsize=36: fontcolor=white:[textapplied];[textapplied]transpose=1" output_video.mp4
It is allowing me to overlay horizontally or vertically only.
But I want to append it with some angle like 45 degrees.
For that if I modify the command as
ffmpeg -i input1.mp4 -filter_complex "[0:v]rotate=45*PI/180[anticlockwiserotated];[anticlockwiserotated]drawtext=fontfile=../../public/fonts/Roboto-Regular-webfont.ttf: text='Test Text':x=100: y=50: fontsize=36: fontcolor=white:[textapplied];[textapplied]rotate=315*PI/180" output_video.mp4
By this I am getting overlay video as:
Because in this first I am rotating video to 45 degrees, appending text and bringing it back to original position. So I am loosing borders.
Please suggest me the best way to overlay text with required angle on video.
Thanks in advance.
Basic method is to generate text on a blank canvas, then an alpha layer for the text, rotating the result and overlaying that on the main video.
In the command below, a should be replaced by the angle. The co-ordinates for the drawtext are used in the overlay instead. Depending on the length of your text, some of it may get clipped if you've rotated it anticlockwise. So check and adjust the Y offset accordingly.
ffmpeg -i input1.mp4 -filter_complex
"color=black:100x100[c];
[c][0]scale2ref[ct][mv];
[ct]setsar=1,drawtext=fontfile=../../public/fonts/Roboto-Regular-webfont.ttf:
text='Test Text':fontsize=36:fontcolor=white,split[text][alpha];
[text][alpha]alphamerge,rotate=a:ow=rotw(a):oh=roth(a):c=black#0[txta];
[mv][txta]overlay=x='min(0,-H*sin(a))+100':y='min(0,W*sin(a))+50':shortest=1"
output_video.mp4
One method is by using ASS or SRT subtitles with the FFmpeg subtitles or ass filters.
ffmpeg -i input -filter_complex "subtitles=diagonal.ass" output
SRT subtitles are much simpler than ASS and don't support rotation, but you can manually add it with the filter:
ffmpeg -i input -filter_complex "subtitles=diagonal.srt:force_style='Angle=45'" output
You can create and style the subtitles with Aegisub or manually.

FFMPEG - crop and pad a video (keep 3840x1920 but with black borders)

I am trying to crop a video so that I can remove a chunk of the content from the sides of a 360-degree video file using FFmpeg.
I used the following command and it does part of the job:
ffmpeg -i testVideo.mp4 -vf crop=3072:1920:384:0,pad=3840:1920:384:0 output.mp4
This will remove the sides of the video and that was initially exactly what I wanted (A). Now I'm wondering if it is possible to crop in the same way but to keep the top third of video. As such, A is what I have, B is what I want.:
I thought I could simply do this:
ffmpeg -i testVideo.mp4 -vf crop=3072:1920:384:640,pad=3840:1920:384:640 output.mp4
But that doesn't seem to work.
Any input would be very helpful.
Use the drawbox filter to fill cropped portion with default colour black.
ffmpeg -i testVideo.mp4 -vf drawbox=w=384:h=1280:x=0:y=640:t=fill,drawbox=w=384:h=1280:x=3840-384:y=640:t=fill -c:a copy output.mp4
The first filter acts on the left side, and the 2nd on the right.

Overlay circular video with transparency with maskedmerge

I have a square video from Snap Spectacles (1088x1088) that I want to overlay on itself zoomed in and blurred.
Example input frame:
Generated zoomed in and blurred background:
Desired output:
I think I can do this with ffmpeg's maskedmerge, but I'm having trouble finding examples.
There's an example of maskedmerge that merges two videos of the same size and dynamically removes a green screen, and another that merges videos with transparency.
Here's the closest I've been able to get:
ffmpeg -i background.jpg -vf "movie=input.jpg[inner];[in][inner] overlay=#{offset}:0 [out]" -c:a copy output.jpg
tl;dr: given the first two frames, how could I generate the third frame (as video)?
Got it!
Like #Mulvya recommended, I needed a circular mask:
Given that mask snapmask.png, a blurred square background video background.mov, and the original video 65B6354F61B4AF02_HD.MOV, they can be merged like this:
ffmpeg -i background.mov -loop 1 -i snapmask.png -filter_complex " \
[1:v]alphaextract, scale=1080:1080 [mask];\
movie=65B6354F61B4AF02_HD.MOV, scale=1080:1080 [original];\
[original][mask] alphamerge [masked];\
[0:v][masked] overlay=420:0;"\
-c:a copy output.mov
You can do one better, though, which is generating the blurred background video on the fly in the same command. Now the only inputs are the original spectacles round video and the circular mask:
ffmpeg -i 65B6354F61B4AF02_HD.MOV -loop 1 -i snapmask.png -filter_complex "\
[0:v]split[a][b];\
[1:v]alphaextract, scale=1080:1080[mask];\
[a]scale=1080:1080 [ascaled];\
[ascaled][mask]alphamerge[masked];\
[b]crop=946.56:532:70.72:278, boxblur=10:5,scale=1920:1080[background];\
[background][masked]overlay=420:0"\
-c:a copy 65B6354F61B4AF02_HD_sq.MOV
That crop=946.56:532:70.72:278 bit is what I found worked best to crop out a rectangular portion of the circular video to zoom into.
It took me a while to wrap my head around the ffmpeg filter system for how to do this, but it's not as scary as I'd initially thought. The basic syntax is [input]command args[output], and commands can be chained without explicitly naming their outputs (like in [1:v]alphaextract, scale=1080:1080[mask]).

Overlaying text on video with required angle using FFMPEG

I am trying to overlay some text on video using ffmpeg. I am able to overlay text by the bellow command.
ffmpeg -i input1.mp4 -filter_complex "[0:v]transpose=2[anticlockwiserotated];[anticlockwiserotated]drawtext=fontfile=../../public/fonts/Roboto-Regular-webfont.ttf: text='Test Text':x=100: y=50: fontsize=36: fontcolor=white:[textapplied];[textapplied]transpose=1" output_video.mp4
It is allowing me to overlay horizontally or vertically only.
But I want to append it with some angle like 45 degrees.
For that if I modify the command as
ffmpeg -i input1.mp4 -filter_complex "[0:v]rotate=45*PI/180[anticlockwiserotated];[anticlockwiserotated]drawtext=fontfile=../../public/fonts/Roboto-Regular-webfont.ttf: text='Test Text':x=100: y=50: fontsize=36: fontcolor=white:[textapplied];[textapplied]rotate=315*PI/180" output_video.mp4
By this I am getting overlay video as:
Because in this first I am rotating video to 45 degrees, appending text and bringing it back to original position. So I am loosing borders.
Please suggest me the best way to overlay text with required angle on video.
Thanks in advance.
Basic method is to generate text on a blank canvas, then an alpha layer for the text, rotating the result and overlaying that on the main video.
In the command below, a should be replaced by the angle. The co-ordinates for the drawtext are used in the overlay instead. Depending on the length of your text, some of it may get clipped if you've rotated it anticlockwise. So check and adjust the Y offset accordingly.
ffmpeg -i input1.mp4 -filter_complex
"color=black:100x100[c];
[c][0]scale2ref[ct][mv];
[ct]setsar=1,drawtext=fontfile=../../public/fonts/Roboto-Regular-webfont.ttf:
text='Test Text':fontsize=36:fontcolor=white,split[text][alpha];
[text][alpha]alphamerge,rotate=a:ow=rotw(a):oh=roth(a):c=black#0[txta];
[mv][txta]overlay=x='min(0,-H*sin(a))+100':y='min(0,W*sin(a))+50':shortest=1"
output_video.mp4
One method is by using ASS or SRT subtitles with the FFmpeg subtitles or ass filters.
ffmpeg -i input -filter_complex "subtitles=diagonal.ass" output
SRT subtitles are much simpler than ASS and don't support rotation, but you can manually add it with the filter:
ffmpeg -i input -filter_complex "subtitles=diagonal.srt:force_style='Angle=45'" output
You can create and style the subtitles with Aegisub or manually.

Resources