Ffmpeg watermarking multiple images - ffmpeg

I'm a bit puzzled here and can't find an answer to the following question. Is it possible to have 2 .png files watermarked into a video in a single command line with Libavfilter?
I'm using this commandline, but everything I try to get the second PNG image in it fails.
ffmpeg –i inputvideo.avi -vf "movie=watermarklogo.png [watermark]; [in][watermark] overlay=main_w-overlay_w-10:10 [out]" outputvideo.flv

This is certainly possible, and should look something like:
ffmpeg –i in.avi -vf "movie=logo1.png [logo1]; movie=logo2.png [logo2]; \
[in][logo1] overlay [tmp]; [tmp][logo2] overlay=50:50" out.flv
Both logo files are read in. One's overlaid at 0,0. Then the next is overlaid at 50,50 on the output from the first overlay filter.
Using more recent versions of FFmpeg, this command could be done slightly less verbosely like so:
ffmpeg -i in.avi -i logo1.png -i logo2.png -filter_complex "overlay [tmp]; \
[tmp] overlay=50:50" out.flv
The first overlay command overlays the first two inputs (in.avi and logo1.png), and the second automatically uses the third input (logo2.png) as its second input.

Related

How can I resize an overlay image with ffmpeg?

I am trying to add an overlay to a video using the following command
ffmpeg -y -i "$videoPath" -i "$overlayPath" -filter_complex "[0:v] [1:v] overlay=$overlayPosition" -pix_fmt yuv420p -c:a copy "$outputPath"
However, I would like to be able to resize the overlay I am about to apply to some arbitrary resolution (no care for keeping proportions). However, although I followed a couple of similar solutions from SO (like FFMPEG - How to resize an image overlay?), I am not quite sute about the meaning of the parameters or what I need to add it in my case.
I would need to add something like (?)
[1:v]scale=360:360[z] [1:v]overlay=$overlayPosition[z]
This doesn't seem to work so I'm not sure what I should be aiming for.
I would appreciate any assistance, perhaps with some explanation.
Thanks!
You have found all parts. Let's bring them together:
ffmpeg -i "$videoPath" -i "$overlayPath" -filter_complex "[1:v]scale=360:360[z];[0:v][z]overlay[out]" -map "[out]" -map "0:a" "$outputPath"
For explanation:
We're executing here two filter within the "filter_complex" parameter separated by a semicolon ";".
First we scale the second video input ([1:v]) to a new resolution and store the output in variable "z" (you can put here any name).
Second we bring the first input video ([0:v]) and the overlay ([z]) together and store the output in variable "out".
Now it's time to tell ffmpeg what he should pack into our output file:
-map "[out]" (for the video)
-map "0:a" (for the audio of the first input file)

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.

FFMPEG multiple commands using filter-complex

I've pieced together 3 commands but my solution involves writing a number of tempory files. I would ultimately like to pipe the output of one command into the next command, without the temporary files.
Although many questions discuss filter-complex (which is how I believe results passing as inputs is accomplished), I can't seem to find an example of commands that use filter_complexs flowing into other filter_complex commands (nested filter-complex commands?). In my example, two distinct inputs are required, resulting in one output.
/*
Brighten & increase saturation of original image
Remove white shape from black background silhouette, leaving a transparent shape
Overlay black background silhouette over brightened image. Creating a focus point
*/
ffmpeg -i OrigionalImage.png -vf eq=brightness=0.06:saturation=2 -c:a copy BrightenedImage.png
ffmpeg -i WhiteSilhouette.png -filter_complex "[0]split[m][a]; [a]geq='if(lt(lum(X,Y),16),255,0)',hue=s=0[al]; [m][al]alphamerge" -c:a copy TransparentSilhouette.png
ffmpeg -i BrightenedImage.png -i TransparentSilhouette.png -filter_complex "[0:v][1:v] overlay=(W-w)/2:(H-h)/2" -c:a copy BrightnedSilhouette.png
Two original inputs and final output
Origional Image
White Silhouette
Brightned Silhouette
Use
ffmpeg -i OriginalImage.png -i WhiteSilhouette.png -filter_complex "[0]eq=brightness=0.06:saturation=2[img];[1]split[m][a];[a]geq='if(lt(lum(X,Y),16),255,0)',hue=s=0[al];[m][al]alphamerge[sil];[img][sil]overlay=(W-w)/2:(H-h)/2" BrightnedSilhouette.png
You can also just invert WhiteSilouhette to generate the alpha,
ffmpeg -i OriginalImage.png -i WhiteSilhouette.png -filter_complex "[0]eq=brightness=0.06:saturation=2[img];[1]split[m][a];[a]geq='255-lum(X,Y)',hue=s=0[al]; [m][al]alphamerge[sil];[img][sil]overlay=(W-w)/2:(H-h)/2" BrightnedSilhouette.png

add multiple overlays to a single image with ffmpeg

How am I supposed to add two transition animations to the same image in the video with ffmpeg command? I want the image to slide from left to right and after a while back from right to left... This command is for left to right
ffmpeg -i input.mp4 -i image.png -filter_complex "[0:v][1:v]overlay=x='min(-1.5*w+5*w*t,5)':y=H/2-h/2'" -y output.mp4
There are two methods to do this. One is to provide a clipped oscillating function, similar to the expression for x used in the drawtext filter here.
The other method is use a conditional expression, shown below.
ffmpeg -i input.mp4 -i image.png
-filter_complex
"[0:v][1:v]overlay=x='if(lt(t,8),min(-1.5*w+5*w*t,5),5-5*w*(t-8))':y=H/2-h/2'"
-y output.mp4
Here's the slide out starts at t=8s.

Create animated gif from a set of jpeg images

I need something that can be scripted on windows 7. This image will be used in banners.
Simon P Stevens' answer almost got me there:
ffmpeg -f image2 -i image%d.jpg video.avi
ffmpeg -i video.avi -pix_fmt rgb24 -loop_output 0 out.gif
Let's see if we can neaten this up.
Going via an avi is unnecessary. A -pix_fmt of rgb24 is invalid, and the -loop_output option prevents looping, which I don't want. We get:
ffmpeg -f image2 -i image%d.jpg out.gif
My input pictures are labeled with a zero-padded 3-digit number and I have 30 of them (image_001.jpg, image_002.jpg, ...), so I need to fix the format specifier
ffmpeg -f image2 -i image_%003d.jpg out.gif
My input pictures are from my phone camera, they are way too big! I need to scale them down.
ffmpeg -f image2 -i image_%003d.jpg -vf scale=531x299 out.gif
I also need to rotate them 90 degrees clockwise
ffmpeg -f image2 -i image_%003d.jpg -vf scale=531x299,transpose=1 out.gif
This gif will play with zero delay between frames, which is probably not what we want. Specify the framerate of the input images
ffmpeg -f image2 -framerate 9 -i image_%003d.jpg -vf scale=531x299,transpose=1 out.gif
The image is just a tad too big, so I'll crop out 100 pixels of sky. The transpose makes this tricky, I use the post-rotated x and y values:
ffmpeg -f image2 -framerate 9 -i image_%003d.jpg -vf scale=531x299,transpose=1,crop=299,431,0,100 out.gif
The final result - I get to share my mate's awesome facial expression with the world:
You can do this with ffmpeg
First convert the images to a video:
ffmpeg -f image2 -i image%d.jpg video.avi
(This will convert the images from the current directory (named image1.jpg, image2.jpg...) to a video file named video.avi.)
Then convert the avi to a gif:
ffmpeg -i video.avi -pix_fmt rgb24 -loop_output 0 out.gif
You can get windows binaries for ffmpeg here.
You can also do a similar thing with mplayer. See Encoding from multiple input image files.
I think the command line would be something like:
mplayer mf://*.jpg -mf w=800:h=600:type=jpg -vf scale=160:120 -vo gif89a:fps=3:output=out.gif
(Where 800 & 600 are your source width and height and 160 & 120 are the target width and height.out.gif is your target file name)
I've just tested both of these and they both work fine. However I got much better results from mplayer as I was able to specify the resolution and framerate. Your milage may vary and I'm sure you could find more options for ffmpeg if you looked.
With ImageMagick:
convert *.png a.gif
The ffmpeg to .avi and .avi to .gif worked, but the only thing to note is that your images must be named in perfect increasing numeric order to work, with no gaps. I cooked up a quick python script to rename all of my images accordingly so that this ffmpeg recipe would work:
import os
files = [ f for f in os.listdir('.') if os.path.isfile(os.path.join('.',f)) and f.endswith('.jpg') ]
for i, file in enumerate(sorted(files)):
os.rename(file, 'image%03d.jpg' % i)
And then I stumbled upon a much simpler approach than ffmpeg for doing the conversion, which is simply using ImageMagick's command line convert tool like this
convert image%03d.jpg[0-198] animated_gif.gif
Doesn't get much simpler than that folks.
Gist here: https://gist.github.com/3289840
Based on the answers of Simon P Stevens and dwurf I came up with this simplified solution:
ffmpeg -f image2 -framerate 1 -i image%d.jpg video.gif
This results in a rate of 1 second per image. Adjust the framerate value according to your needs.
I'd just like to add to dwurf's answer, that this will generate a gif with the standard 256-colors palette, which does not look very visually pleasing.
I've found two blog-posts and adapted them to my needs, in order to improve the visual quality by using a custom palette for your animation:
Generate the color palette:
ffmpeg -f image2 -i image%d.jpg -vf scale=900:-1:sws_dither=ed,palettegen palette.png
Convert images into a regular video with the desired framerate, because the third command only worked with a single input video and not a bunch of images
ffmpeg -f image2 -framerate 1.2 -i image%d.jpg video.flv
Now convert the generated video with the generated palette into a more beautiful gif:
ffmpeg -i video.flv -i palette.png -filter_complex "fps=1.2,scale=900:-1:flags=lanczos[x];[x][1:v]paletteuse" video.gif

Resources