FFmpeg watermarking
Thursday, 16 June 2016, 10:47
FFmpeg and websites
The easiest way to implement movie-based serives on website running on Linux-based platform is FFmpeg with it's command-line interface. One of the most commonly demanded features for such services is movies watermarking with website's logo image. The problem is, that lastly FFmpeg introduced new filters mechanism and removed old APIs like vhook which was used for that purpose. So if you want to implement this feature using latest FFmpeg, you will have to mess a bit with it, since filters required for watermarking are currently available only in Summer of Code tree. So here is the solution.
Getting FFmpeg
First of all, you have to get the FFmpeg source. You will need FFmpeg itself, and few files from SoC tree. Download code from SVN repository:
svn co svn://svn.ffmpeg.org/ffmpeg/trunk /usr/local/src/ffmpeg
svn co svn://svn.ffmpeg.org/soc/libavfilter /usr/local/src/libavfilter
Installing filters
Now copy movie and overlay filters from Soc tree to trunk libavfilter tree:
cp /usr/local/src/libavfilter/{vf_overlay.c,vsrc_movie.c} /usr/local/src/ffmpeg/libavfilter/
Next step will require some code ingerention - we have to add both filters into source code, so FFmpeg would see them. Edit file /usr/local/src/ffmpeg/libavfilter/allfilters.c and in function avfilter_register_all add following lines:
REGISTER_FILTER (OVERLAY, overlay, vf);
REGISTER_FILTER (MOVIE, movie, vsrc);
We also need to edit Makefile as the build process have to include new filters - add following lines to /usr/local/src/ffmpeg/libavfilter/Makefile:
OBJS-$(CONFIG_OVERLAY_FILTER) += vf_overlay.o
OBJS-$(CONFIG_MOVIE_FILTER) += vsrc_movie.o
Building
Now simply build FFmpeg using standard commands:
./configure (--options-you-want)
# you should see movie ad overlay on filters list
make
make install
ldconfig
Watermarking
Now you should be able to use both movie video source and overlay filter. The syntax of -vf option (libavfilter) is described in it's documentation - in general here we use movie source to load image from file into stream named [watermark] (you can call it whatever you want) and next we pass both [in] (input file) and loaded streams into overlay filter which produces single [out] (output file) stream:
ffmpeg -i input.avi -vf 'movie=0:png:images/logo.png [watermark];[in] [watermark]overlay=0:0:1[out]' output.flv
Padding
The very last thing you might need is watermark padding. Fortunately padding filter exists even in FFmpeg trunk:
pad=width:height:x:y:color
It can be however a bit confusing about it's parameters relations. width and height parameters are dimensions of entire padding area and x/y are coordinates of top-left corner of overlayed clip (our watermark). So if you want to put watermark in point, for instance, 30x60, then you have to use 30+watermarkWidth/60+watermarkHeight as padding area dimensions and 30/60 as x/y. Color is the walue for background (I believe so) and it is in RGBA color, so you can use transparent color by passing color with 0 value of it's alpha part.
Putting it all together
Ok, but how to add padding filter into the filter queue, you ask? Use it only on your watermark stream, since you don't want to add padding to your oryginal movie stream:
ffmpeg -i input.avi -vf 'movie=0:png:images/logo.png,pad=640:480:560:400:0x00000000 [watermark];[in] [watermark]overlay=0:0:1[out]' output.flv
Any problems? Strange, worked fine for me .