Introduction#
Recently, I encountered a requirement at work that involved adding watermarks to a large number of videos in bulk. I tried various existing programs for adding watermarks that I found online, some of which required payment and others that didn't support scripting. In fact, as we all know, most commercial video processing programs make use of FFmpeg to some extent to help achieve their functionality. Therefore, I decided to use FFmpeg directly to add watermarks to videos, which would also allow me to easily write bash scripts for batch processing. By the way, some commercial programs that use FFmpeg do not comply with its open-source license, which is really annoying!
Download and Installation#
For macOS/Linux, you can simply use package management tools to install it. For Windows, you can download it from FFmpeg Download. I won't go into the specifics.
Usage#
FFmpeg is very easy to use.
Use -i
to specify the input file, and specify the output file at the end.
ffmpeg -i input.mp4 output.avi
This means converting a video in mp4 format to avi format.
You can also use the -c:v
parameter to specify the video codec format, which is h264 by default.
This is just the most common video format conversion, but what we need is to add watermarks.
FFmpeg provides a parameter option called -filter
.
It is called a filter, and it can be used to implement functions such as cropping, rotating, changing image resolution, and adding filters.
In FFmpeg, there are two types of filters: simple and complex. The simple type only supports single input and single output, while the complex type supports multiple inputs and outputs because it is not a simple linear process.
Generally speaking, the simple type is faster because it processes frames related to decoding, and then re-encodes them.
_________ ______________
| | | |
| decoded | | encoded data |
| frames |\ _ | packets |
|_________| \ /||______________|
\ __________ /
simple _\|| | / encoder
filtergraph | filtered |/
| frames |
|__________|
At the same time, filters can also be linearly stacked, and the output of one filter becomes the input of another filter, forming a filter chain.
-vf
and -af
represent the parameters for video and audio filters, respectively.
For example,
ffmpeg -i input.mp4 -c:v libx264 -vf "transpose=2" output.mp4
means rotating the main video track counterclockwise by 90 degrees.
You can form a filter chain by adding commas between the -vf
parameters.
There are many filters similar to transpose, and you can find nearly 300 video filters alone in the FFmpeg filters doc.
Adding Watermarks#
I roughly divide the types of watermarks into two categories:
- Text watermarks
- Image watermarks
When adding these two types of watermarks, we also need to consider the content, position, size, and transparency of the watermarks.
Let me explain them one by one.
Text Watermarks#
Text watermarks are implemented using the drawtext
filter.
Here are some useful parameters:
- fontsize (font size)
- fontfile (font)
- text (text)
- x (x coordinate)
- y (y coordinate)
- fontcolor (text color)
- alpha (transparency)
I'm going to test it with the following command:
ffmpeg -i input.mp4 -vf "drawtext=fontsize=100:fontfile=Arial.ttf:text='Watermark':x=20:y=20:fontcolor=red:alpha=0.5" output.mp4
Result:
You can see that the color, position, font, and transparency are all customizable.
Image Watermarks#
Image watermarks are implemented using the movie
and overlay
parameters.
Here's an example:
ffmpeg -i input.mp4 -vf "movie=watermark.jpg[wm];[in][wm]overlay=20:20[out]" output.mp4
Result:
The photo seems a bit large, how should we handle it?
This is where we can use the filter chain we mentioned earlier to process it.
We can use scale
to resize it.
ffmpeg -i input.mp4 -vf "movie=watermark.jpg,scale=50:50[wm];[in][wm]overlay=20:20[out]" output.mp4
It seems that the photo is blocking the view again. What should we do?
Let's make it transparent!
First, use format
to convert the image to a pixel format with an alpha channel, and then specify the blending to achieve it.
ffmpeg -i input.mp4 -vf "movie=watermark.jpg,scale=200:200,format=yuva444p,colorchannelmixer=aa=0.5[wm];[in][wm]overlay=20:20[out]" output.mp4
But why didn't we use a transparent png image from the beginning? Haha, that seems more convenient.