Skip to content

Instantly share code, notes, and snippets.

@anisse
Last active April 30, 2025 08:08
Show Gist options
  • Save anisse/ffc7dc7b3301ea11a0e5fc8155889b21 to your computer and use it in GitHub Desktop.
Save anisse/ffc7dc7b3301ea11a0e5fc8155889b21 to your computer and use it in GitHub Desktop.
Script to do the optimal compression of a gif or video into a slack emoji. Cropping or limiting the number of frames should be done separately.
#!/bin/bash
set -euo pipefail
INPUT="$1"
DIMENSION="${2:-128}"
QUALITY=100
TARGET_SIZE=130278 # Not the real value, but I'm too lazy to really test the slack limits
TMPOUT=$(mktemp gifski-slack.XXXXXXX)
TMPYUV=$(mktemp gifski-slack-yuv.XXXXXXX)
MIN=1
MAX=100
trap 'rm -f -- "$TMPOUT" "$TMPYUV"' EXIT
ffmpeg -loglevel warning -i "$INPUT" -vf "format=yuv420p" -f yuv4mpegpipe -y "$TMPYUV"
while true
do
echo "Trying quality = $QUALITY..."
gifski --quiet --width "$DIMENSION" --height "$DIMENSION" --quality "$QUALITY" --output "$TMPOUT" "$TMPYUV"
SIZE=$(stat -c %s "$TMPOUT")
if [ "$QUALITY" = 100 ]; then
if [ "$SIZE" -lt "$TARGET_SIZE" ]; then
echo "Target size reached with maximum quality. Nothing to do"
break
fi
QUALITY=1
continue
fi
if [ "$SIZE" -gt "$TARGET_SIZE" ]; then
if [ "$QUALITY" = 1 ]; then
echo "Target size cannot be reached even with minimum quality. Sorry"
break
fi
MAX="$QUALITY"
fi
if [ "$SIZE" -lt "$TARGET_SIZE" ]; then
MIN="$QUALITY"
fi
if [ "$SIZE" -eq "$TARGET_SIZE" ] || [ "$SIZE" -le "$TARGET_SIZE" ] && [ $((MAX-MIN)) = 1 ]; then
break
fi
QUALITY=$((MIN + (MAX-MIN) / 2 ))
done
INPUT_FILE="${INPUT##*/}"
mv "$TMPOUT" "${INPUT_FILE%.*}-gifslack.gif"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment