Convert GIF to Video with FFmpeg

In video production and online sharing, you may sometimes need to convert GIF animations to standard video formats. Compared to GIF, video formats offer better compression efficiency, higher image quality, and broader compatibility. This article explains how to efficiently perform this conversion using FFmpeg.

Basic Conversion Command

Simple Conversion

The most basic GIF to video command:

ffmpeg -f gif -i animation.gif animation.mp4

An optimized conversion command suitable for web sharing:

ffmpeg -i animated.gif -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" video.mp4

Parameter Details

ParameterFunctionDescription
-movflags faststartOptimize MP4 structureMoves metadata to the beginning of the file for better streaming
-pix_fmt yuv420pPixel formatEnsures maximum compatibility with all players
-vf "scale=..."Size adjustmentEnsures width and height are even (required by H.264 encoding)

movflags Explained

The -movflags faststart parameter moves the MP4 file's metadata (moov atom) to the beginning, allowing browsers to start playing the video before the entire file is downloaded, greatly improving user experience.

Importance of Pixel Format

-pix_fmt yuv420p is key for compatibility:

Size Handling Tips

H.264 encoding requires even dimensions. The scale=trunc(iw/2)*2:trunc(ih/2)*2 filter ensures:

Advanced Usage Examples

Control Output Quality

# High quality output
ffmpeg -i input.gif -c:v libx264 -crf 18 -pix_fmt yuv420p output.mp4

# Compression priority (for web)
ffmpeg -i input.gif -c:v libx264 -crf 28 -preset fast -pix_fmt yuv420p output.mp4

CRF Value Explanation:

Specify Frame Rate

# Set output frame rate to 30fps
ffmpeg -i input.gif -r 30 -c:v libx264 -pix_fmt yuv420p output.mp4

# Keep original frame rate but limit maximum
ffmpeg -i input.gif -vf "fps=min(24\,source_fps)" -c:v libx264 -pix_fmt yuv420p output.mp4

Add Audio Track

# Add silent audio track (required by some platforms)
ffmpeg -i input.gif -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 \
    -c:v libx264 -c:a aac -shortest -pix_fmt yuv420p output.mp4

Different Output Formats

ffmpeg -i input.gif -c:v libx264 -movflags faststart -pix_fmt yuv420p output.mp4

MOV Format

ffmpeg -i input.gif -c:v libx264 -pix_fmt yuv420p output.mov

WebM Format

ffmpeg -i input.gif -c:v libvpx-vp9 -crf 30 output.webm

Batch Conversion Script

#!/bin/bash
# Batch convert all GIFs in the directory to MP4

for gif in *.gif; do
    if [ -f "$gif" ]; then
        output="${gif%.gif}.mp4"
        echo "Converting: $gif -> $output"
        ffmpeg -i "$gif" -movflags faststart -pix_fmt yuv420p \
            -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" \
            -y "$output"
    fi
done

echo "Batch conversion complete"

Troubleshooting

Q: The converted video cannot be played on some devices? A: Make sure to use the -pix_fmt yuv420p parameter, which is key for compatibility.

Q: The file size is too large? A: Adjust the CRF value (increase the number) or use the -preset parameter:

ffmpeg -i input.gif -crf 28 -preset medium -pix_fmt yuv420p output.mp4

Q: The quality drops significantly after conversion? A: Lower the CRF value or use a slower preset:

ffmpeg -i input.gif -crf 20 -preset slower -pix_fmt yuv420p output.mp4

Q: How to keep the GIF looping? A: Video formats do not contain loop information. You need to set the loop property in the player.

Performance Optimization Tips

  1. Use hardware acceleration (if supported):

    ffmpeg -hwaccel auto -i input.gif -c:v h264_videotoolbox -pix_fmt yuv420p output.mp4
    
  2. Process multiple files in parallel:

    find . -name "*.gif" | xargs -P 4 -I {} ffmpeg -i {} -c:v libx264 -pix_fmt yuv420p {}.mp4
    

References: