Search code examples
ffmpegcommandimagemagickwebm

How to convert two png to transparent webm video with FFMPEG and Xfade


I have two transparent pictures, one is in completely transparent png format, its name is C0.png, the other is the main picture, and its name is C1.png. I want to superimpose two pictures with xfade and transparency effects.

I used the command below:

ffmpeg -loop 1 -t 12 -i c0.png -t 12 -loop 1 -i c1.png -filter_complex "[0]format=rgb24,drawbox=thickness=fill,split[black][black2];[black2]negate[white];[black][white]xfade=transition=wipedown:duration=1:offset=0[alf];[0][1]overlay=format=auto[ovr];[ovr][alf]alphamerge[fg];[0][fg]overlay=format=auto:alpha=1,format=yuv420p" -t 12 -pix_fmt yuv420p 1p.webm

But after executing this way, the final webm video will have a black background, and what I want is a video with a transparent background。

How to optimize it, look forward to your help, thank you

C0.png https://i.sstatic.net/fPuQH.png

C1.png https://i.sstatic.net/W9RA6.png


Solution

  • Try this:

    ffmpeg -loop 1 -i c1.png -filter_complex "nullsrc=size=800x800[bg]; \
    [bg][0]xfade=transition=wipedown:duration=1:offset=1,format=yuva420p" \
    -c:v libvpx-vp9 -pix_fmt yuva420p -metadata:s:v:0 alpha_mode="1" -t 12 1p.webm
    

    You do not need the drawbox filter at all because xfade itself can do the transition.

    Also, you do not need a blank image. Instead, use a null source for the other image, here achieved by the nullsrc filter. Note that the size of the nullsrc has to adjusted by you so that it matches your image c1.png. In my sample I have used a sample/arbitrary size of 800x800 pixels. I have used an offset of 1 second. So the wipedown starts 1 second after the video starts.

    You can choose anything you prefer.

    You do need the format to be yuva420p because the a represents the alpha channel. Also for webm it seems you need to state -metadata:s:v:0 alpha_mode="1" for the result to have alpha.

    Note that in Chrome as soon as I drag a video, the entire canvas turns black, so even a transparent background will show as black. If you query through ffprobe or ffmpeg your video will report "Alphamode : 1".

    The drawbox filter, which draws a solid black color with fill will certainly make it non-transparent because it will cover the alpha channel. Anyway it is not required at all for what you want to do.

    The above code is tested on bash 4.4 and ffmpeg version 4.4, and works perfectly.