Skip to content

Instantly share code, notes, and snippets.

@panzi
Created October 2, 2019 22:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save panzi/ebdfe0bb37ffc401c9f103edf12394b1 to your computer and use it in GitHub Desktop.
Save panzi/ebdfe0bb37ffc401c9f103edf12394b1 to your computer and use it in GitHub Desktop.
convert a video into a GIF with optimal palette
#!/usr/bin/bash
input=/dev/stdin
output=/dev/stdout
slice=
palette="/tmp/mkgif-$$-palette.png"
fps=15
width=
crop=
while getopts "s:d:t:w:f:c:h" opt; do
case $opt in
h)
echo "Usage: mkgif.sh [-s start_time] [-d duration] [-t tempfile] [-w width] [-f fps] [-c width:height:x:y] [input.mp4] [output.gif]"
exit
;;
s)
slice="$slice -ss $OPTARG"
;;
d)
slice="$slice -t $OPTARG"
;;
t)
palette=$OPTARG
;;
f)
fps=$OPTARG
;;
w)
width=$OPTARG
;;
c)
crop=$OPTARG
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
exit 1
;;
esac
done
if [[ $OPTIND -le $# ]]; then
input=${@:$OPTIND:1}
OPTIND=$((OPTIND+1))
fi
if [[ $OPTIND -le $# ]]; then
output=${@:$OPTIND:1}
fi
filters="fps=$fps"
if [[ ! -z $width ]]; then
filters="$filters,scale=${width}:-1:flags=lanczos"
fi
if [[ ! -z $crop ]]; then
filters="crop=$crop,$filters"
fi
set -xe
ffmpeg -v warning $slice -i "$input" -vf "$filters,palettegen" -y "$palette"
ffmpeg -v warning $slice -i "$input" -i "$palette" -lavfi "$filters [x]; [x][1:v] paletteuse" -f gif -y "$output"
rm "$palette"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment