Search code examples
ffmpegsnapchat

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:

original snap spectacles video frame

Generated zoomed in and blurred background:

generated zoomed in and blurred background

Desired output:

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

enter image description here

tl;dr: given the first two frames, how could I generate the third frame (as video)?


Solution

  • Got it!

    Like @Mulvya recommended, I needed a circular mask:

    ffmpeg 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]).