Skip to content

Instantly share code, notes, and snippets.

@arstropica
Created November 29, 2020 21:26
Show Gist options
  • Save arstropica/5da536087f88ea551dc5af557637b571 to your computer and use it in GitHub Desktop.
Save arstropica/5da536087f88ea551dc5af557637b571 to your computer and use it in GitHub Desktop.
Converts a video or image sequence to a animated gif with ffmpeg
#!/usr/bin/env bash
die () {
echo >&2 "$@"
exit 1
}
palette="./palette.png"
temp="./_temp.mp4"
path=false
file=false
ext=false
filename=false
width=-1
height=-1
dimensions=""
transpose=0
vf=""
fps=""
rate=0
orate=0
bg=""
bgopts=""
noop=0
declare -a args
declare -a vargs
while getopts ":hi:w:d:t:r:f:c:n" option; do
case $option in
h) echo "usage: $0 [-i] [-w] [-d] [-t] [-r] [-f] [-c] [-n] file ..."; exit ;;
i) path="$OPTARG" ;;
w) width=$OPTARG ;;
d) height=$OPTARG ;;
t) transpose="$OPTARG" ;;
r) rate=$OPTARG ;;
f) orate=$OPTARG;;
c) bg=$OPTARG;;
n) noop=1 ;;
?) echo "error: option -$OPTARG is not implemented"; exit ;;
esac
done
[ "$path" ] || die "-i argument required"
[[ ! -f "$path" && ! "$path" =~ png|jpg|tif$ ]] && die "File not found"
file=$(basename -- "$path")
ext="${file##*.}"
filename="${file%.*}"
args+=("y")
if [ $rate -gt 0 ]; then
args+=("r ${rate}")
fi
if [ ! -z "$bg" ]; then
args+=("f lavfi")
args+=("i color=${bg}")
bgopts="[0][1]scale2ref[bg][gif];[bg]setsar=1[bg]"
vargs+=("${bgopts};[bg][gif]overlay=shortest=1")
fi
args+=("i ${file}")
if [ $width -gt 0 ] || [ $height -gt 0 ]; then
vargs+=("scale=${width}:${height}")
dimensions=".${width}x${height}"
fi
if [ $transpose -ne 0 ]; then
vargs+=("transpose=${transpose}")
fi
if [ $rate -gt 0 ]; then
vargs+=("minterpolate='mi_mode=mci:mc_mode=aobmc:vsbmc=1:fps=30'")
elif [ $orate -gt 0 ]; then
args+=("r ${orate}")
fi
if [ ${#vargs[@]} -gt 0 ]; then
vf=$(IFS=, ; echo "${vargs[*]}")
if [ -z "$bgopts" ]; then
args+=("vf ${vf}")
else
vf+="[out]"
fi
fi
args+=("c:v libx264")
args+=("crf 18")
args+=("preset veryslow")
args+=("an")
[ -e $palette ] && rm -f $palette
[ -e $temp ] && rm -f $temp
#ffmpeg -i "$file" "$vf" "-c:v libx264 -crf 18 -preset veryslow -an" "${filename}.gif"
if [ $noop -ne 0 ]; then
if [ ! -z "$bgopts" ]; then
echo "ffmpeg ${args[@]/#/-} -filter_complex \"${vf}\" -map \"[out]\" ${temp}"
else
echo "ffmpeg ${args[@]/#/-} ${temp}"
fi
echo "ffmpeg -y -i $temp -filter_complex \"[0:v] palettegen\" $palette"
echo "ffmpeg -y -i $temp -i $palette -filter_complex \"[0:v][1:v] paletteuse\" ${filename}${dimensions}.gif"
else
if [ ! -z "$bgopts" ]; then
ffmpeg ${args[@]/#/-} -filter_complex "${vf}" -map "[out]" "${temp}"
else
ffmpeg ${args[@]/#/-} "${temp}"
fi
ffmpeg -y -i "$temp" -filter_complex "[0:v] palettegen" "$palette"
ffmpeg -y -i "$temp" -i "$palette" -filter_complex "[0:v][1:v] paletteuse" "${filename}${dimensions}.gif"
[ -e $palette ] && rm -f $palette
[ -e $temp ] && rm -f $temp
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment