Search code examples
imagevideoffmpeggifvideo-processing

Animated GIF overlay is not looping on Video built from Image FFmpeg


My goal is to transform an image .jpg into a .mp4 video and then add a .gif overlay on the video created. The problem is the GIF overlay on the video created is not playing/looping.

Here is the command for the image -> video :

"-framerate 1/10 -i image.jpg -vf scale=720:1280 -t 10 -pix_fmt yuv420p -c:v libx264 -movflags faststart output.mp4"

This create successfully a video of 10seconds from my image.

Here is the command for applying the gif as overlay :

-i video.mp4 -ignore_loop 0 -i animated.gif -filter_complex '[1:v]scale=321.0:-1[ovrl0];[0:v][ovrl0]overlay=160.5:487.28:shortest=1' -codec:a copy -codec:v libx264 -preset ultrafast output.mp4

The overlay is correctly applied but it's not playing or looping at all.

I don't know what I am doing wrong because the last command (overlay) is working perfectly when it's triggered from a classic video file (like from recorded camera or something) -> the gif is looping as expected.

So I'm assuming the real issue come from the video I created from my image but result I've got seems to be good so can't find what's wrong with the image or video created.

Can someone could help me please to fix it and understand this case ?


Solution

  • Your (image->video) has only one frame over 10 seconds. I believe by default the output stream configuration is drawn from the first input so its framerate is set to 0.1 fps. (not 100% certain of who actually sets what but this should be the expected behavior). So, the output video also has only one frame, and consequently, it won't show any of the gif animation. You need to use higher framerate.

    A simple solution with video.mp4 assuming the gif framerate is 25 fps:

    -i video.mp4 -ignore_loop 0 -i animated.gif \
    -filter_complex '[1:v]scale=321.0:-1[ovrl0];\
                     [0:v]fps=25[main0];\
                     [ovrl0]overlay=160.5:487.28:shortest=1' \
    -codec:a copy -codec:v libx264 -preset ultrafast output.mp4
    

    Change fps=25 to the actual gif framerate if you want the lowest framerate possible.

    Alternately, you can do the whole thing in one command:

    -ignore_loop 0 -i animated.gif \
    -loop 1 -i image.jpg \
    -filter_complex '[0:v]scale=321.0:-1[ovrl0];\
                     [1:v]scale=720:1280[main0];\
                     [main0][ovrl0]overlay=160.5:487.28' \
    -t 10 -pix_fmt yuv420p -c:v libx264 -movflags faststart output.mp4
    

    I think this should make the framerate of the output to match that of the gif. If not, insert -r xx output option like above.

    I see in your second command audio stream is set to copy. If you added audio between your 2 commands, you can add it to this unified command as well.